← 記事一覧に戻る
March 20, 2026
読了時間: 5分

LLMアルファマイニング:決算説明会と金融文書からトレーディングシグナルを抽出する方法

LLMアルファマイニング:決算説明会と金融文書からトレーディングシグナルを抽出する方法
#llm
#alpha
#earnings
#nlp
#gpt
#金融分析
#アルゴトレーディング

ウォール街にはこんなジョークがある。「決算説明会で最も価値のある情報は、CEOが何を言ったかではなく、どう言ったかだ。」ティム・クックが昨年の「非常に満足している」ではなく「慎重ながらも楽観的だ」と言ったとき——それは言葉遊びではなく、数億ドル規模のシグナルだ。

数十年にわたり、クオンツファンドはこれらのシグナルの体系的な抽出を試みてきた。最初は辞書を使って「ポジティブ」「ネガティブ」な単語の出現頻度を数えた。次にBERTを投入した。そして今、GPT-4o、Claude、オープンソースのLLMが登場し、研究者自身をも驚かせるほどの精度で企業の二枚舌を解析できるようになった。

決算説明会からトレーディングシグナルを抽出する本格的なパイプラインの構築方法を見ていこう——トランスクリプトの取得から累積異常リターンのバックテストまで。

なぜ決算説明会はアルファの宝庫なのか

決算発表後ドリフト:消えない市場アノマリー

1968年、ボールとブラウンは奇妙な現象を発見した。四半期決算の発表後、株価は「サプライズ」の方向にさらに60~90日間ドリフトし続けるのだ。これはPost-Earnings Announcement Drift(PEAD)と名付けられた。以来半世紀以上が経過し、数百の論文が書かれ、十数の角度からこのアノマリーが説明されてきた——しかし、いまだに機能している。

PEADは金融史上最も持続的な市場アノマリーの一つだ。「ポジティブサプライズを買い、ネガティブサプライズを売る」というポートフォリオ戦略は、歴史的に年間10~25%の超過リターンをもたらしてきた。なぜ市場はこれを裁定で消し去っていないのか?理由はいくつかある:

  • 投資家の注意力の限界——1週間に200社が決算を発表するとき、すべてのトランスクリプトを読むのは物理的に不可能
  • 認知的複雑さ——決算説明会は45~60分続き、キーシグナルはQ&Aセッション38分目の一文に隠されていることもある
  • 言語の曖昧さ——CFOが「we are navigating headwinds」と言っても、文脈なしでは穏やかな警告なのか標準的なヘッジなのか不明

ここでLLMが登場する。500件のトランスクリプトを一晩で処理し、かつ経験豊富なアナリストでさえ見逃すようなニュアンスを捉えられるツールを、我々は初めて手にした。

PEAD.txt:テキストは数字より重要

フィラデルフィア連銀の研究者(Meursault、Liang、Routledge、Scanlon)はPEAD.txtという論文を発表し、テキスト情報の価値に関する常識を覆した。彼らは標準的なearnings surpriseのテキスト版——SUE.txt——を構築したが、これは利益の数値を一切使用しない

結果は?SUE.txtは古典的PEADの2倍のドリフトを生成する。さらに、近年では数値サプライズに基づく古典的PEADがほぼ消滅した(市場が学習した)一方で、テキストドリフトは依然として有意である。市場は数字の処理を素早く学んだが、テキストの解釈にはまだ苦戦している。

これが決算説明会へのNLPアプローチを支持する根本的な論拠だ。

センチメントからセマンティクスへ:アプローチの進化

センチメントからセマンティクスへ

第一世代:Bag-of-Wordsと辞書(2000-2015)

すべてはLoughran-McDonald辞書(2011)から始まった——「ポジティブ」「ネガティブ」「不確実」「訴訟関連」とラベル付けされた単語リストだ。アイデアはシンプルで洗練されていた:10-K報告書のネガティブ単語の割合を数えて取引する。

問題は?金融文脈では「outstanding」は「優れた業績」よりも「未払い債務」を意味することが多い。Risk Managementの「risk」はネガティブシグナルではなく、プロセスの説明だ。標準的なNLPセンチメント辞書は金融テキストに対して恥ずかしいほど機能しなかった。

LoughranとMcDonaldは専門辞書を作成し、状況は改善したが、根本的な問題は残った:bag-of-wordsは文脈を理解しない。「We did not fail to meet expectations」——ここには2つの「ネガティブ」な単語があるが、意味はポジティブだ。

第二世代:FinBERTとTransformer(2019-2023)

2019年、Dogu AraciはFinBERTを発表した——Reuters TRC2の金融テキストでファインチューニングしたBERTだ。結果は印象的で、Financial PhraseBank データセットで最先端を14パーセントポイント上回った。FinBERTは文脈を理解した:「outstanding」が「debt」の隣なら——ネガティブ、「performance」の隣なら——ポジティブ。

しかしFinBERTには制限があった:512トークンのコンテキストウィンドウだ。決算説明会は8,000~12,000語になる。チャンクに分割してセンチメントを平均化すると、段落間のセマンティクスが失われる。CEOが楽観的に始めて、Q&Aでさりげなくサプライチェーンの問題に触れるかもしれない。FinBERTは各チャンクを独立に分析し、このコントラストを見逃す。

第三世代:ロングコンテキストLLM(2023-現在)

GPT-4、Claude、Geminiは128K~1Mトークンのコンテキストウィンドウを持ち、ゲームのルールを変えた。今やトランスクリプト全体を一度に読み込み、文書全体の理解を必要とする質問を投げかけることができる。

重要な研究——Lopez-Lira & Tang(2023)「Can ChatGPT Forecast Stock Price Movements?」。50,000件以上のヘッドラインに対し、GPT-4は市場の初期反応の方向予測で~90%のヒット率を示し、特に小型株とネガティブニュースにおいて後続ドリフトを有意に予測した。初期モデル(GPT-1、GPT-2、BERT)にはこの能力がなかった——予測力は大規模モデルの創発的特性として出現する。

BloombergGPT(2023)——Bloombergの金融コーパスで訓練された500億パラメータモデル——は金融NER、ニュース分類、センチメント分析で改善を示した。FinGPT——そのオープンソース代替——はデータ中心アプローチとRAGにより金融センチメントタスクで89%の精度を達成した。

GPT-4とChain-of-Thought、In-Context LearningをS&P 100分析に使用したMarketSenseAIは、15ヶ月のテスト期間で10~30%の超過アルファと最大72%の累積リターンを示した。確かに、これらの数字は慎重に受け止める必要がある(バックテスト≠ライブトレーディング)が、トレンドは明確だ。

データパイプライン:データの取得先

SEC EDGAR:公式ソース

米国株式の場合、主要なソースはSEC EDGAR。決算説明会は通常直接提出されないが、関連文書は利用可能:

  • 8-K filing(Item 2.02——業績報告)——決算のプレスリリースで、トランスクリプト付きのexhibit 99を含むことが多い
  • 10-Q / 10-K——四半期・年次報告書、Management Discussion & Analysis(MD&A)を含む——これも価値あるテキストソース
  • DEF 14A——経営陣報酬情報を含む委任状
from edgar import Company

company = Company("AAPL")
filings = company.get_filings(form="8-K")

for filing in filings.latest(10):
    if "2.02" in str(filing.items):
        doc = filing.document()
        text = doc.text()  # 添付資料を含む全文
        print(f"{filing.filing_date}: {len(text)} chars")

Seeking Alphaと商用API

決算説明会のトランスクリプトは別製品だ。Seeking Alphaは歴史的に主要な無料ソースだったが、現在はアクセスを制限している。商用オプション:

  • Seeking Alpha Premium API——スピーカーラベル付きの完全なトランスクリプト
  • AlphaVantage Earnings API——制限付きの無料枠
  • Financial Modeling Prep——トランスクリプト+ファンダメンタルデータ
  • Earnings Call Edge / Motley Fool Transcripts——代替ソース

暗号資産:ガバナンスコールとDAO提案

ここが面白い。大手DeFiプロトコルは決算説明会に相当するイベントを開催している:

  • Uniswap——ガバナンスコール、コミュニティコール、YouTubeでの録画
  • Aave——月次コミュニティコール+ガバナンスフォーラム提案
  • MakerDAO——ガバナンスコール+広範なフォーラムディスカッション
  • Compound——詳細な議論付きのガバナンス提案

暗号資産のコールトランスクリプトは通常構造化されていない。解決策——OpenAIのWhisperによるYouTube録画の文字起こし:

import openai
from yt_dlp import YoutubeDL

def transcribe_governance_call(youtube_url: str) -> str:
    """YouTubeから音声をダウンロードしWhisperで文字起こし。"""
    ydl_opts = {
        'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': '64',  # 音声には低ビットレートで十分
        }],
        'outtmpl': '/tmp/governance_call.%(ext)s',
    }

    with YoutubeDL(ydl_opts) as ydl:
        ydl.download([youtube_url])

    client = openai.OpenAI()

    with open("/tmp/governance_call.mp3", "rb") as audio_file:
        transcript = client.audio.transcriptions.create(
            model="whisper-1",
            file=audio_file,
            response_format="verbose_json",
            timestamp_granularities=["segment"]
        )

    return transcript.text

Whisper APIによる文字起こしコスト:0.006/分。1時間のガバナンスコールで約0.006/分。1時間のガバナンスコールで約0.36。セルフホスト版の場合——Whisper Large-v3 Turboは最新のGPUで60分のファイルを約17秒で文字起こし(リアルタイムの216倍)。

LLMプロンプティング戦略:ナイーブから本番品質まで

シグナル抽出パイプライン

戦略1:直接センチメント(弱い)

最もナイーブなアプローチ——モデルに直接質問する:

"Is this earnings call positive or negative for the stock price?"

これは機能するか?驚くべきことに、する。Lopez-Lira & Tangは、このような原始的なプロンプトでも統計的に有意な予測が得られることを示した。しかし問題がある:

  • バイナリ出力——グラデーションが失われる。「大惨事」と「軽い失望」が同じラベルを受ける
  • 説明がない——モデルが何に基づいて判断したか不明
  • 不安定性——再実行で異なる回答が出る可能性がある

戦略2:Chain-of-Thoughtを用いた構造化抽出(強い)

アイデア:単一の数値ではなく、モデルに各ステップの説明を強制しながら、構造化されたシグナルセットを抽出する。

from pydantic import BaseModel, Field
from openai import OpenAI
from enum import Enum
from typing import Optional


class SentimentLevel(str, Enum):
    VERY_BEARISH = "very_bearish"
    BEARISH = "bearish"
    NEUTRAL = "neutral"
    BULLISH = "bullish"
    VERY_BULLISH = "very_bullish"


class GuidanceSurprise(BaseModel):
    """フォワードガイダンスのコンセンサス予想からの乖離。"""
    revenue_guidance_vs_consensus: Optional[float] = Field(
        None, description="売上ガイダンスのコンセンサスからの乖離率%"
    )
    margin_guidance_direction: Optional[str] = Field(
        None, description="expanding / stable / contracting"
    )
    key_quote: str = Field(
        description="ガイダンスを含む原文引用"
    )
    reasoning: str = Field(
        description="CoT:なぜこのガイダンスが重要か"
    )


class ConfidenceMetrics(BaseModel):
    """経営陣の自信度指標。"""
    hedge_word_count: int = Field(
        description="ヘッジワード数:'approximately'、'potentially'、'subject to'"
    )
    forward_looking_ratio: float = Field(
        description="前向き声明の総声明に対する割合"
    )
    q_and_a_evasion_count: int = Field(
        description="CEO/CFOが曖昧な回答をした質問数"
    )
    ceo_vs_cfo_sentiment_delta: float = Field(
        description="CEOとCFOのセンチメント差(-1〜1)。乖離はレッドフラグ"
    )


class CompetitiveIntelligence(BaseModel):
    """競合他社の言及と市場ポジション。"""
    competitors_mentioned: list[str] = Field(
        description="言及された競合他社のリスト"
    )
    market_share_claims: list[str] = Field(
        description="市場シェアに関する主張"
    )
    new_product_signals: list[str] = Field(
        description="新製品・サービスに関するシグナル"
    )


class ManagementSignals(BaseModel):
    """経営陣シグナル。"""
    turnover_risk: SentimentLevel = Field(
        description="主要経営陣の交代リスク"
    )
    tone_shift_from_previous: Optional[str] = Field(
        None, description="前四半期からのトーンの変化"
    )
    insider_language_flags: list[str] = Field(
        description="マーカーフレーズ:'exploring strategic alternatives'、'right-sizing'など"
    )


class EarningsCallAnalysis(BaseModel):
    """決算説明会の完全分析。"""
    ticker: str
    quarter: str
    overall_sentiment: SentimentLevel
    sentiment_score: float = Field(description="-1.0から1.0")
    guidance_surprise: GuidanceSurprise
    confidence_metrics: ConfidenceMetrics
    competitive_intel: CompetitiveIntelligence
    management_signals: ManagementSignals
    key_risks: list[str]
    key_catalysts: list[str]
    one_line_summary: str


def analyze_earnings_call(transcript: str, ticker: str, quarter: str) -> EarningsCallAnalysis:
    """
    決算説明会から構造化シグナルを抽出。
    コスト:1回あたり約$0.15-0.30(GPT-4o、入力約10Kトークン)。
    """
    client = OpenAI()

    system_prompt = """You are a senior equity research analyst with 20 years of experience.
Analyze the following earnings call transcript and extract structured trading signals.

IMPORTANT INSTRUCTIONS:
1. Use Chain-of-Thought reasoning for each field — explain WHY before giving the value
2. Focus on DEVIATIONS from expectations, not absolute statements
3. Pay special attention to Q&A section — management is less scripted there
4. Compare management's language to typical corporate hedging baseline
5. Flag any "strategic alternatives", "right-sizing", or other euphemisms
6. Score sentiment relative to market expectations, not in absolute terms

HEDGE WORDS TO COUNT: approximately, potentially, subject to, may, might,
could, uncertain, challenging, headwinds, navigate, prudent, cautious,
evolving, dynamic, unprecedented, transitional"""

    completion = client.beta.chat.completions.parse(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": f"Ticker: {ticker}\nQuarter: {quarter}\n\n{transcript}"}
        ],
        response_format=EarningsCallAnalysis,
        temperature=0.1,  # 再現性のため低いtemperature
    )

    return completion.choices[0].message.parsed

いくつかの重要なポイントに注目してほしい:

Pydanticスキーマ——OpenAI Structured Outputsは100%のスキーマ準拠を保証する。「sorry, I cannot parse the JSON」は起きない。各フィールドにはdescriptionがあり、分析の特定側面に対するミニプロンプトとして機能する。

スキーマ内のChain-of-Thought——reasoningkey_quoteフィールドはモデルに「作業過程を示す」ことを強制する。これは品質を向上させるだけでなく(モデルは判断を下す前に具体的な引用を見つけなければならない)、規制当局への監査証跡も作成する。

Temperature 0.1——創造性は不要だ。再現性が必要だ。Temperature 0ではモデルが時々パターンに「はまる」ことがある。0.1が最適な妥協点だ。

戦略3:過去の実例を用いたFew-Shot

さらに強力な手法——過去の決算説明会の例と実際の市場反応をモデルに与える:

few_shot_examples = """
EXAMPLE 1:
Transcript excerpt: "We are cautiously optimistic about the second half...
While we continue to navigate macro headwinds, our pipeline remains robust."
Actual market reaction: -3.2% (next day)
Analysis: Despite surface-level positivity, "cautiously optimistic" is a
DOWNGRADE from previous quarter's "very confident". Five hedge words in
two sentences. Market read through the hedging.

EXAMPLE 2:
Transcript excerpt: "Frankly, demand has exceeded our ability to supply.
We're expediting CapEx to address this."
Actual market reaction: +7.8% (next day)
Analysis: "Frankly" signals genuine surprise even from management.
Accelerated CapEx on demand = strong confidence. No hedging language.
"""

Few-shot例はモデルのキャリブレーションに役立つ:ウォール街の言語では「cautiously optimistic」はポジティブではなく、ソフトなネガティブだと学ぶ。例なしでは、LLMは言葉を文字通りに解釈する可能性がある。

4種類のシグナル

1. ガイダンスサプライズ

最も直接的なシグナル。企業が次の四半期/年のフォーキャスト(ガイダンス)を提供し、市場はコンセンサスからの乖離に反応する。経営陣が曖昧に伝えた場合でも、LLMはガイダンスを抽出できる:

  • "We expect revenues in the range of..."——直接的なガイダンス、パースしやすい
  • "We feel comfortable with current Street estimates"——暗黙的なコンセンサス確認
  • "There are puts and takes relative to consensus"——暗黙的なリスクシグナル

LLMは3つすべてを理解する。正規表現は最初のものだけ。

2. 自信度指標:ヘッジワード密度

これは私のお気に入りのシグナルだ。反直感的だから。本質はこうだ:経営者は法律教育を受け、偏執的な法務部門を持つ人々だ。うまくいっているとき、具体的に話すことを許される。問題が醸成されているとき——ヘッジを始める。

追跡すべき指標:

指標 説明 弱気シグナル
ヘッジワード密度 1,000語あたりのヘッジワード比率 1,000語あたり15超
確実性比率 "will/expect"対"may/could"の比率 < 1.5
Q&A回避率 直接回答のない質問の割合 > 30%
CEO/CFO差異 CEOとCFOのトーンの乖離 [-1, 1]スケールで0.3超

最後のポイントが特に興味深い。CEOはストーリーテラー——美しい絵を描くのが仕事だ。CFOは監査法人に対して責任を負う人物だ。CEOが「transformative growth ahead」と言い、CFOがすぐに「while maintaining disciplined cost management」と差し込むとき——この乖離は社内の緊張を示すシグナルだ。

3. 競合インテリジェンス

経営陣が直接名前を避けていても、LLMはトランスクリプトから競合他社の言及を抽出できる。「The largest player in the market」——業界を知っていればGPT-4にとっては謎ではない。

トレーディングシグナル:A社が決算説明会で競合他社Bをネガティブな文脈で言及した場合(「we're taking share from...」)、これはA(ロング)だけでなくB(ショート)のシグナルでもある。ペアトレードだ。

4. 経営陣交代シグナル

経営陣の変更や戦略的転換を示すマーカーフレーズ:

  • 「Exploring strategic alternatives」——会社売却の可能性
  • 「Right-sizing our operations」——大規模リストラ
  • 「The board has initiated a comprehensive review」——CEOの近い退任
  • 「We're bringing in fresh perspectives」——現チームの失敗

これらのフレーズのそれぞれが、その後の価格動向と統計的に有意な相関を持つ。LLMはゼロの偽陽性でこれらを検出できる——文脈を理解するからだ。正規表現は製品ラインの説明中の「strategic alternatives」を誤検出する可能性がある。

バックテスト:イベントスタディ手法

イベントスタディ結果

シグナルを生成した——素晴らしい。しかし機能するのか?標準的な検証方法は、累積異常リターン(CAR)を計算するイベントスタディだ。

手法

  1. イベントの定義——決算説明会の日付
  2. 推定ウィンドウ——イベント前[-250, -30]営業日で「通常の」リターンを推定
  3. イベントウィンドウ——イベント前後[-1, +60]日
  4. 通常リターンの計算——マーケットモデルによる:Rit=αi+βiRmt+ϵitR_{it} = \alpha_i + \beta_i R_{mt} + \epsilon_{it}
  5. 異常リターン——実際のリターンと「通常の」リターンの差
  6. CAR——イベントウィンドウにわたる異常リターンの累積和
import numpy as np
import pandas as pd
from scipy import stats
from dataclasses import dataclass


@dataclass
class EventStudyResult:
    car: np.ndarray          # 日次累積異常リターン
    t_stats: np.ndarray      # 各日のt統計量
    avg_car_3d: float        # CAR[-1, +1]
    avg_car_30d: float       # CAR[-1, +30]
    avg_car_60d: float       # CAR[-1, +60]
    p_value_3d: float
    p_value_30d: float
    n_events: int


def run_event_study(
    returns: pd.DataFrame,       # 株式日次リターン(columns = ティッカー)
    market_returns: pd.Series,   # 市場指数日次リターン
    events: pd.DataFrame,        # DataFrame、columns: [ticker, date, signal_score]
    estimation_window: int = 220,
    gap: int = 30,
    event_window: tuple = (-1, 60),
) -> EventStudyResult:
    """
    LLMシグナルの予測力を評価するイベントスタディ。

    signal_scoreでイベントをソートし、ロング/ショートポートフォリオを構築、
    CARを計算し統計的有意性をテスト。
    """
    all_cars = []

    for _, event in events.iterrows():
        ticker = event['ticker']
        event_date = event['date']

        if ticker not in returns.columns:
            continue

        try:
            event_idx = returns.index.get_loc(event_date, method='ffill')
        except KeyError:
            continue

        est_start = event_idx - estimation_window - gap
        est_end = event_idx - gap

        if est_start < 0:
            continue

        y = returns.iloc[est_start:est_end][ticker].values
        x = market_returns.iloc[est_start:est_end].values

        mask = ~(np.isnan(y) | np.isnan(x))
        if mask.sum() < 60:  # 最低60観測
            continue

        y_clean, x_clean = y[mask], x[mask]

        slope, intercept, _, _, _ = stats.linregress(x_clean, y_clean)
        residual_std = np.std(y_clean - (intercept + slope * x_clean))

        ev_start = event_idx + event_window[0]
        ev_end = event_idx + event_window[1] + 1

        if ev_end > len(returns):
            continue

        actual = returns.iloc[ev_start:ev_end][ticker].values
        market = market_returns.iloc[ev_start:ev_end].values

        expected = intercept + slope * market
        ar = actual - expected
        car = np.cumsum(ar)

        all_cars.append(car)

    if not all_cars:
        raise ValueError("No valid events found")

    min_len = min(len(c) for c in all_cars)
    all_cars = np.array([c[:min_len] for c in all_cars])

    mean_car = np.mean(all_cars, axis=0)
    std_car = np.std(all_cars, axis=0) / np.sqrt(len(all_cars))
    t_stats = mean_car / (std_car + 1e-10)

    offset = -event_window[0]  # イベント日までのオフセット

    car_3d = mean_car[min(offset + 1, min_len - 1)] if min_len > offset + 1 else mean_car[-1]
    car_30d = mean_car[min(offset + 30, min_len - 1)] if min_len > offset + 30 else mean_car[-1]
    car_60d = mean_car[min(offset + 60, min_len - 1)] if min_len > offset + 60 else mean_car[-1]

    n = len(all_cars)
    p_3d = 2 * (1 - stats.t.cdf(abs(car_3d / (np.std([c[min(offset+1, min_len-1)] for c in all_cars]) / np.sqrt(n) + 1e-10)), df=n-1))
    p_30d = 2 * (1 - stats.t.cdf(abs(car_30d / (np.std([c[min(offset+30, min_len-1)] for c in all_cars]) / np.sqrt(n) + 1e-10)), df=n-1))

    return EventStudyResult(
        car=mean_car,
        t_stats=t_stats,
        avg_car_3d=car_3d,
        avg_car_30d=car_30d,
        avg_car_60d=car_60d,
        p_value_3d=p_3d,
        p_value_30d=p_30d,
        n_events=n,
    )


def backtest_llm_signals(
    llm_signals: pd.DataFrame,  # [ticker, date, sentiment_score]
    returns: pd.DataFrame,
    market_returns: pd.Series,
):
    """バックテスト:トップ五分位をロング、ボトム五分位をショート。"""

    llm_signals['quintile'] = pd.qcut(
        llm_signals['sentiment_score'], 5, labels=[1, 2, 3, 4, 5]
    )

    long_events = llm_signals[llm_signals['quintile'] == 5].copy()
    short_events = llm_signals[llm_signals['quintile'] == 1].copy()

    long_result = run_event_study(returns, market_returns, long_events)
    short_result = run_event_study(returns, market_returns, short_events)

    print(f"LONG portfolio (top quintile LLM sentiment):")
    print(f"  CAR[0,+3]:  {long_result.avg_car_3d:+.2%} (p={long_result.p_value_3d:.4f})")
    print(f"  CAR[0,+30]: {long_result.avg_car_30d:+.2%} (p={long_result.p_value_30d:.4f})")
    print(f"  N events:   {long_result.n_events}")

    print(f"\nSHORT portfolio (bottom quintile LLM sentiment):")
    print(f"  CAR[0,+3]:  {short_result.avg_car_3d:+.2%} (p={short_result.p_value_3d:.4f})")
    print(f"  CAR[0,+30]: {short_result.avg_car_30d:+.2%} (p={short_result.p_value_30d:.4f})")
    print(f"  N events:   {short_result.n_events}")

    ls_3d = long_result.avg_car_3d - short_result.avg_car_3d
    ls_30d = long_result.avg_car_30d - short_result.avg_car_30d
    print(f"\nLONG-SHORT spread:")
    print(f"  CAR[0,+3]:  {ls_3d:+.2%}")
    print(f"  CAR[0,+30]: {ls_30d:+.2%}")

予想される結果

既存の研究に基づく、LLMシグナルの現実的なCAR:

ウィンドウ ロングポートフォリオ ショートポートフォリオ LS スプレッド
[0, +1] +0.8% — +1.5% -0.5% — -1.2% 1.3% — 2.7%
[0, +30] +1.5% — +3.0% -1.0% — -2.5% 2.5% — 5.5%
[0, +60] +2.0% — +4.0% -1.5% — -3.5% 3.5% — 7.5%

重要な指標は統計的有意性だ。p < 0.01かつN > 200イベントであれば、ロバストなシグナルと言える。p > 0.05の場合——ノイズの可能性がある。

本番実装:Jupyterからプロダクションへ

リアルタイムパイプラインアーキテクチャ

YouTube/Audio Stream
       │
       ▼
┌─────────────────┐    ┌──────────────────┐
│  Whisper         │───▶│  Transcript       │
│  Transcription   │    │  Buffer           │
│  (streaming)     │    │  (Redis Stream)   │
└─────────────────┘    └──────────────────┘
                              │
                    ┌─────────┴─────────┐
                    ▼                   ▼
            ┌──────────────┐   ┌──────────────┐
            │ Real-time    │   │ Full-call    │
            │ Chunk Anal.  │   │ Analysis     │
            │ (every 5min) │   │ (after call  │
            │              │   │  ends)       │
            └──────────────┘   └──────────────┘
                    │                   │
                    ▼                   ▼
            ┌──────────────────────────────┐
            │     Signal Aggregator        │
            │  (confidence-weighted merge) │
            └──────────────────────────────┘
                         │
                         ▼
            ┌──────────────────────────────┐
            │     Trading Engine           │
            │  (position sizing, risk mgmt)│
            └──────────────────────────────┘

コスト分析:1回の決算説明会にいくらかかるか

本番環境で1回の決算説明会を処理する経済性を分析しよう:

コンポーネント コスト レイテンシ
Whisper API文字起こし(60分) $0.36 ~17秒(Turbo)
GPT-4o構造化抽出 $0.15-0.30 ~8-15秒
GPT-4oリアルタイムチャンク分析(x12) $1.80-3.60 各~5秒
RAG保存用Embedding $0.01 <1秒
合計(フルパイプライン) $2.30-4.30 ~30秒

ちょっと待てよ、$30-50/コールという見積もりはどこから?モデルとアプローチ次第だ:

  • エコノミーオプション(GPT-4o-mini、シングルパス):$0.50-1.00
  • スタンダードオプション(GPT-4o、構造化抽出+チャンク分析):$2-5
  • プレミアムオプション(GPT-4o、複数パス、クロスバリデーション、過去比較):$15-30
  • ヘッジファンドグレード(複数モデル+人間レビュー+リアルタイムストリーミング):$30-50+

500銘柄を取引するクオンツファンドにとって、決算シーズン(6週間で約2,000コール)の処理コストはスタンダードオプションで4,0004,000~10,000。ポジションあたりの平均アルファが1~3%であることを考えると——ROIは天文学的だ。

レイテンシ:ミリ秒の競争

HFTの世界ではレイテンシがすべてだ。しかし決算ベースの戦略では状況が異なる:

  1. 決算説明会は45~60分続く——時間はある
  2. PEADは60日間にわたる——最初の1秒でエントリーする必要はない
  3. 主要なディスロケーションはコール終了後の最初の30分で起こる

最適な戦略は二段階だ:

  • フェーズ1(リアルタイム):コール中に5分チャンクを分析し、予備シグナルを形成
  • フェーズ2(コール後):終了後2~5分以内にトランスクリプト全体の完全分析

フェーズ1は、コール終了を待つ市場参加者に対して5~10分のエッジを提供する。中型株にはこれで十分だ。

暗号資産への拡張:DeFiガバナンスとDAO提案

暗号市場はLLMアルファマイニングの理想的な実験場だ。その理由:

  1. 機関投資家が少ない——つまり、利用できる非効率性が多い
  2. ガバナンス=決算説明会——DAOの決定はトークノミクスに直接影響する
  3. 24時間365日市場——反応を即座に取引できる
  4. 公開データ——すべての提案と投票がオンチェーン

分析対象の暗号イベントタイプ

ガバナンス提案(Aave、Compound、Uniswap)

提案はプロトコルのパラメータを変更する——金利、担保係数、手数料スイッチ。LLMは経済的影響を評価できる:

crypto_analysis_prompt = """Analyze this DeFi governance proposal.
Extract:
1. Economic impact on token holders (positive/negative/neutral)
2. TVL impact estimate (increase/decrease/stable + magnitude)
3. Competitive positioning vs other protocols
4. Risk factors introduced by the proposal
5. Historical precedent (similar proposals in other protocols)
6. Likely voting outcome based on forum discussion sentiment

Proposal: {proposal_text}
Forum discussion: {discussion_text}
"""

プロトコルアップデートの発表

Uniswapがhooks付きのv4を発表したり、AaveがGHOをローンチしたりするとき——それはTradFiにおける製品ローンチに相当する。LLMはナラティブのモメンタムと技術的重要性を評価できる。

トレジャリーレポート

大規模DAOは数億ドル規模のトレジャリーを持つ。四半期トレジャリーレポートは決算の直接的な類似物だ。ランウェイ、バーンレート、分散投資——すべてLLM分析に適している。

暗号シグナルの特殊性

TradFiと異なり、暗号資産では:

  • オンチェーンデータがナラティブを確認または反証する——ガバナンスコールで言われたことをプロトコルの実際のメトリクス(TVL、取引量、アクティブユーザー)と照合できる
  • クジラウォレットはインサイダー取引に相当——ガバナンス議論後の大口ウォレットの動きはしばしば投票に先行する
  • CT(Crypto Twitter)によるセンチメント増幅——ガバナンスコールからのシグナルはTwitterナラティブによって増幅または抑制される可能性がある

落とし穴と限界

ハルシネーション:モデルが数字を捏造するとき

LLMはトランスクリプトに存在しないガイダンスを「抽出」することがある。ヘッジワード密度の分析時に特に危険:モデルは実際より多くまたは少なく単語を数える可能性がある。

解決策:二段階検証。LLMが抽出し、決定論的コードが検証する。ヘッジワードには——LLM評価と並行して正規表現でカウント。乖離 > 20%——手動レビューのフラグ。

import re

HEDGE_WORDS = [
    r'\bapproximately\b', r'\bpotentially\b', r'\bsubject to\b',
    r'\bmay\b', r'\bmight\b', r'\bcould\b', r'\buncertain\b',
    r'\bchallenging\b', r'\bheadwinds\b', r'\bnavigate\b',
    r'\bprudent\b', r'\bcautious\b', r'\bevolving\b',
    r'\bdynamic\b', r'\bunprecedented\b', r'\btransitional\b',
]

def verify_hedge_count(text: str, llm_count: int) -> dict:
    """LLMのヘッジワードカウントの決定論的検証。"""
    regex_count = sum(
        len(re.findall(pattern, text, re.IGNORECASE))
        for pattern in HEDGE_WORDS
    )

    deviation = abs(llm_count - regex_count) / (regex_count + 1)

    return {
        "llm_count": llm_count,
        "regex_count": regex_count,
        "deviation": deviation,
        "needs_review": deviation > 0.2,
    }

コンテキストウィンドウの制限

以下を入力したい場合、128Kトークンでも足りないことがある:

  • 現在のトランスクリプト(~10Kトークン)
  • 比較用の前回トランスクリプト(~10K)
  • アナリストのコンセンサス予想(~2K)
  • Few-shot例(~3K)
  • システムプロンプト(~1K)

合計~26K——収まる。しかし文脈として10-K filing(~80-120Kトークン)を追加すると——限界ギリギリだ。解決策:長い文書から関連チャンクを取得するRAG。

バイアスと系統的誤差

LLMは特定のフレーズが特定の結果に関連付けられた歴史的データで訓練されている。しかし市場は適応する:

  • 全員がGPT-4でヘッジワードを数え始めれば、経営者は言葉遣いを変える
  • モデルは訓練データのパターンの重要性を過大評価する可能性がある(生存者バイアス)
  • 企業言語は進化する:2010年の「synergies」と2026年の「synergies」は意味が異なる

混雑した取引のリスク

50のクオンツファンドが同じGPT-4で同じトランスクリプトを分析すれば——シグナルは劣化する。類推:全員が数値サプライズでPEADを取引し始めたとき、アノマリーは縮小した。テキストシグナルでも同じことが起こるが、タイムラグがある:

  1. 現在(2026)——決算説明会にLLMを体系的に使用している人は少ない。アルファは大きい
  2. 2~3年後——広範な普及、アルファは減少
  3. 5年後——基本的なLLMシグナルはコモディティ化、エッジはカスタムモデルとユニークなデータにのみ残る

これはアルファシグナルの標準的なライフサイクルだ。Enjoy it while it lasts。

結論に代えて:アクションプラン

決算説明会分析にLLMを使い始めたいなら、以下が最小限の実行可能プランだ:

  1. 無料データから始める——SEC EDGAR + EdgarToolsで8-K/10-Qファイリング
  2. 構造化抽出を使う——OpenAI Structured OutputsによるPydanticスキーマ
  3. イベントスタディでバックテスト——歴史的データでのCAR、最低200イベント
  4. Few-shot例を追加する——5-10のラベル付き例が品質を劇的に改善
  5. 決定論的に検証する——LLMが抽出し、正規表現が検証し、人間が監査
  6. 中型株から始める——より多くのアルファ、大手ファンドとの競争が少ない
  7. 暗号資産に拡張する——ガバナンスコールとDAO提案は未開拓の領域

クオンツ分析の最も重要な法則を忘れないでほしい:シグナルが良すぎるように聞こえるなら——もう一度確認せよ。LLMは理解の幻想を作り出すが、その背後にあるのは統計的パターンマッチングだ。強力なツール——だがあくまでツールであり、オラクルではない。


参考文献

  1. Ball, R., Brown, P. (1968). An Empirical Evaluation of Accounting Income Numbers. Journal of Accounting Research, 6(2), 159-178. — PEADの初発見。

  2. Bernard, V.L., Thomas, J.K. (1989). Post-Earnings-Announcement Drift: Delayed Price Response or Risk Premium? Journal of Accounting Research, 27, 1-36. — PEADの正典的論文。

  3. Loughran, T., McDonald, B. (2011). When Is a Liability Not a Liability? Textual Analysis, Dictionaries, and 10-Ks. Journal of Finance, 66(1), 35-65. — 金融センチメント辞書。

  4. Araci, D. (2019). FinBERT: Financial Sentiment Analysis with Pre-trained Language Models. arXiv:1908.10063. — 金融NLP向けBERT、SOTAを+14pp超越。

  5. Wu, S. et al. (2023). BloombergGPT: A Large Language Model for Finance. arXiv:2303.17564. — Bloombergの500億パラメータモデル。

  6. Yang, H. et al. (2023). FinGPT: Open-Source Financial Large Language Models. arXiv:2306.06031. — BloombergGPTのオープンソース代替、89%精度。

  7. Lopez-Lira, A., Tang, Y. (2023). Can ChatGPT Forecast Stock Price Movements? Return Predictability and Large Language Models. arXiv:2304.07619. — GPT-4が~90%ヒット率でリターンを予測。

  8. Meursault, V., Liang, P.J., Routledge, B., Scanlon, M.M. (2023). PEAD.txt: Post-Earnings-Announcement Drift Using Text. Journal of Financial and Quantitative Analysis. — テキストPEADは数値PEADの2倍。

  9. Fatouros, G. et al. (2024). Can Large Language Models Beat Wall Street? Evaluating GPT-4's Impact on Financial Decision-Making with MarketSenseAI. Neural Computing and Applications. — S&P 100で10-30%超過アルファのGPT-4フレームワーク。

  10. Chen, Y. et al. (2025). GPT-Signal: Generative AI for Semi-automated Feature Engineering in the Alpha Research Process. arXiv:2410.18448. — LLMによるトレーディングシグナルの自動生成。

  11. Zhang, X. et al. (2025). Can LLMs Hit Moving Targets? Tracking Evolving Signals in Corporate Disclosures. arXiv:2510.03195. — 企業開示における「移動標的」の検出。

  12. Chen, Z. et al. (2025). Large Language Models in Equity Markets: Applications, Techniques, and Insights. Frontiers in Artificial Intelligence. — 金融における84のLLM研究のサーベイ。


本記事は教育目的であり、投資助言を構成するものではありません。ここで説明するトレーディング戦略は、実資本での運用前に、十分なバックテストとリスク管理が必要です。

blog.disclaimer

MarketMaker.cc Team

クオンツ・リサーチ&戦略

Telegramで議論する
Newsletter

市場の先を行く

ニュースレターを購読して、独占的なAI取引の洞察、市場分析、プラットフォームの更新情報を受け取りましょう。

プライバシーを尊重します。いつでも配信停止可能です。