FreqAI(freqtradeのML拡張)で暗号資産のペーパートレードボットを運用しています。数値予測はLightGBMに任せるとして、「LLMの能力を予測以外のどこで活かすか」を考えた結果、ボット自身のトレードをLLMが研究して改良案を出し続ける3層構造を1日で実装したので、設計を解説します。ローカルLLM(gemma系12B)とClaude CLIの併用構成です。
前提: LLMは数値時系列の予測が苦手
最初に設計判断として明確にしたのは、「LLMにローソク足から上昇パターンを直接予測させない」ことです。数値時系列のパターン認識は勾配ブースティング(LightGBM等)の領分で、LLMを予測器にするのは適材適所に反します。LLMにしかできないのは、(1)数値の羅列から意味のある仮説を言語化すること、(2)テキスト情報(ニュース)を読むこと。この2つに役割を絞りました。
層1: トレード反省会ループ(毎時・ローカルLLM)
クローズした全トレードについて、コード側で事実を計算してからLLMに解釈だけをさせます。
- コード側で計算: エントリー直前4時間の騰落率、保有中の最大逆行(MAE)/最大順行(MFE)、決済理由、保有時間
- LLM側で出力: カテゴリ分類(pump_chase / flash_crash / early_exit など7種)+40文字の教訓、をJSONで
数値の計算をLLMにさせないのが要点です。LLMに渡るのは検証済みの実測値だけなので、教訓が事実から乖離しません。蓄積された教訓はJSONLの台帳(トレードジャーナル)になり、層2の材料になります。初回実行で19トレードを検死し、「急騰銘柄への飛び乗りが損失の主因」を人間の事前分析と独立に言い当てました。
ローカルLLM運用の細かい罠として、思考型モデル(gemma系)はOllama APIで think を明示的に無効化しないと、隠れ推論トークンが出力予算を食い潰して空応答になります。これはデーモン故障と誤診しやすい挙動なので注意が必要です。
層2: LLM研究員ループ(毎晩・Claude CLI)
本命の層です。毎晩、次のサイクルが自動で回ります。
- ドシエ生成: 直近7日の決済理由別・時間帯別集計、層1の教訓、過去に検証済みの仮説一覧をJSONに
- 仮説提案: Claude CLIがドシエを読み、検証可能な仮説を最大2個提案
- variant自動生成: 仮説から戦略クラスのソースを自動生成
- 自動バックテスト: 160銘柄×30日でベースラインと同一条件比較
- 台帳記録: 勝敗にかかわらず結果を記録。改善した仮説だけメールで人間に上申
安全設計: 仮説は制約付きDSLでしか書けない
LLMに任意のコードを書かせると、生成コードの検証が地獄になります。そこで仮説はホワイトリスト化した素性6種(4時間騰落率、RSI、時間帯、出来高比など)と比較演算子だけのJSON DSLで表現させ、コード生成はテンプレートへの埋め込みのみにしました。素性名・演算子・数値範囲を全て検証してから、既知のプリミティブを合成する形でvariantを生成します。任意コード実行の余地はありません。
実運用で踏んだLLMの罠: 単位の取り違え
初日にさっそく面白いバグを踏みました。プロンプトで「小数表記(0.05=5%)」と指定しても、Claudeは「1時間で+5%」のつもりで value: 5 (=+500%)を書いてきます。絶対に成立しない条件なので、バックテスト結果がベースラインと完全一致になり発覚しました。対策として、割合系の素性で絶対値が1を超える値は%とみなして自動で1/100に補正する正規化層を入れています。LLMとの構造化データ連携では、この手の「指示しても混ざる単位系」への防御をコード側に置くのが実務的です。
検証の規律が初日から仕事をした
研究員が初日に提案した2仮説のうち1つ(エントリー閾値の変更)は、もっともらしい根拠付きでしたが、バックテストの結果7,000 USDT超(仮想)の損失になると判明し自動却下されました。負けた仮説も台帳に残り、翌日以降のプロンプトに「検証済み」として渡されるため、同じ提案は二度と出ません。「LLMの創造性」と「機械的な検証」の分業がこのループの核です。
層3: セマンティック・ニュース隔離(毎時・ローカルLLM)
数値モデルには原理的に読めない情報として、暗号資産ニュースのRSSをローカルLLMが銘柄別に分類します(センチメント・イベント種別・確度)。運用は安全側からで、
- ハッキング/上場廃止級のネガティブ高確度 → その銘柄を24時間エントリー禁止(戦略側はファイル欠損時フェイルオープン)
- ポジティブシグナル → 当面はシャドー記録のみ。実際に効くかを検証してから昇格
「ニュースで買う」を検証なしにライブへ直結させない、が方針です。ちなみに銘柄シンボルのニュース照合では、THE・US・INのような英語一般語と衝突するシンボルの除外リストが実用上必須でした。
常駐化と運用
3層はsystemdユーザータイマー(毎時×2、日次×1)で常駐化しています。バックテストの検証窓は週単位でスナップさせ、FreqAIの予測キャッシュを週内で使い回すことで、日次の仮説検証を現実的な実行時間(数十分)に収めています。
まとめ
- LLMを「予測器」ではなく「研究員・検死官・ニュース番」として使うと、MLトレーディングボットに自己改良ループを付けられる
- 数値計算はコード、解釈はLLM、裁定はバックテスト、採否は人間——の4分業が規律の要
- 制約付きDSL+テンプレート生成で、LLM由来コードの安全性問題を回避できる
- 単位取り違えのような「LLMの癖」はプロンプトでなくコード側の正規化で防ぐ
運用の様子はKurage AI自動取引ブログで毎日公開しています(dry-run運用・実資金は動いていません)。