はじめに
ローカルLLMを使って、日本株・米国株の日足データを分析する仕組みを作っています。プロジェクト名は orchestration_tech_analyzer です。
目指しているのは、分析の計画、戦略コードの実装、バックテスト、検証、結果の整理をつなぎ、夜間に処理して朝にローカルのレポートを確認できる構成です。途中で失敗しても、決めた回数と時間の範囲で修正し、難しければ理由を残して保留にします。売買注文の発注は対象に含めません。
この連載では、開発計画だけでなく、実装した内容、試して分かった制約、設計を変えた理由も記録していきます。第1回は全体像と、最初に作ったRustコントローラの話です。
2026年10月4日時点で実装できているのは、タスクの制御コアとCLIです。 PythonやLLMを接続した分析、無人の夜間運転はこれからです。以下では、その現在地と今後の計画を分けて説明します。
何を自動化したいのか
研究用の処理では、次の流れを考えています。
- 分析の目的、使えるデータ、実行予算を決める
- 計画LLMがタスク、依存関係、合格条件を提案する
- コントローラが計画を検証する
- 実装LLMがコードを生成し、Pythonで計算・バックテストする
- 機械検証を行い、必要な箇所をLLMがレビューする
- 合格した成果物の版と検証結果を保存する
ここで気を付けたいのは、「コードが動いた」「説明がもっともらしい」だけでは分析を合格にできないことです。入力データ、計算方法、評価条件を追跡できなければ、翌日に同じ処理を再現するのも難しくなります。
そのため、優先順位は分析・検証の正しさ、再現性、夜間の完了可能性、処理速度の順にしています。LLMの一般的なベンチマークと、株式分析の妥当性や運用成績も分けて考えます。現時点で価格予測性能や収益性を実証したものではありません。
全体を動かす責任はRustに集める
計画している構成は次のとおりです。これは完成済みの構成図ではなく、接続先を含めた設計上の全体像です。
Rustコントローラ ── SQLite:タスクと試行の状態
│
├─ Pythonワーカー:計算、バックテスト、機械検証
├─ 推論アダプタ ── llama-server:計画、実装、レビュー
│ └─ 後続段階ではDifyの固定フローを介して接続
└─ 成果物とローカルレポート
Rustは依存関係、実行順、期限、試行回数、復旧を管理します。SQLiteを状態の正本とし、タスクが完了したか、何回試したかを一か所で判断できるようにします。
Pythonはジョブごとの別プロセスで動かす予定です。必要なデータを読み込み、成果物を保存したら終了する構成にします。起動の粒度やメモリ上限は実測して決め、子プロセスの終了確認もRust側の責任に含めます。
Difyには、固定したフロー、プロンプト、ノードのログを担ってもらう計画です。修正や再計画の回数はRust側で管理し、両方で再試行が走る状態を避けます。最小構成ではRustからllama-serverを直接呼び、後から同じタスク契約を保ったアダプタで接続先を切り替えます。
大きな日足データや計算結果は、会話履歴やDBの行に詰め込まず、ファイルとして保存します。基本形式は、表形式のデータがParquet、制御用の情報がJSON、レポートがMarkdownです。DBには成果物の参照や版を記録していく方針です。
研究用の実行と日次処理を分ける
毎日の処理で、毎回ゼロから計画や戦略コードを作り直す構成にはしません。
研究用の実行では、コードを生成し、検証し、採用候補となるデータ・コード・設定の組を保存します。日次処理では、その検証済みの版に新しい日足データを渡します。通常は計画LLMを起動せず、解釈やレビューが必要な部分だけLLMを使う予定です。
銘柄ごとに独立した長い会話を作るのではなく、共通の指標計算や戦略を銘柄群に適用します。仕様変更や異常があれば研究側に戻し、研究で失敗しても既存の合格済み版は保持します。
これによって、日次の入力更新による違いと、コードや設定の変更による違いを切り分けやすくしたいと考えています。
現在地は制御コアとCLI
最初の実装では、外部LLMやPythonを使わずに確認できる制御部分を作りました。
- JSON計画の検証。存在しない依存先、循環依存、重複ID、未知のフィールドなどを拒否
- SQLiteへのタスク、試行、結果、消費済み予算の保存
- 依存タスクが成功したものから次の試行を予約
- 結果受付と合格条件の照合、修正、再計画、保留
- 外部実行器の停止確認を前提にした、中断試行の復旧
初期上限は、タスクごとに初回と追加2回、再計画は実行全体で1回です。総試行数は既定100回で、実行開始時に絶対期限も設定します。同じDBを使う実行全体を通じ、同時に予約できる試行は1件です。
再起動や再計画で、使い切った予算が復活しないことを重視しています。また、同じ結果の再送は重複として扱い、異なる結果による上書きや、復旧前の古い試行から届く結果は拒否します。再計画では変更したタスクとその依存範囲を再計算し、無関係な成功結果を残します。
なお、現在の再計画には制約があります。タスクIDの集合と合格条件は維持し、タスクの追加・削除・改名はできません。まずは変更の影響と予算を追跡できる範囲に絞っています。
mainのCIでは、CLIと制御コアを合わせた27件のテスト、フォーマット確認、Clippyが通っています。ここで確認しているのは制御の動作です。分析精度や推論性能、夜間運転の完了を確認した結果ではありません。
CLIができることの境界
ここは誤解が起きやすいので、明確にしておきます。
next は次の実行要求を予約して返すだけで、PythonやLLMを起動しません。recover もプロセスを止める機能ではなく、呼び出し元が外部実行器の停止を確認したことを伝える操作です。期限もコマンド実行時などに判定しており、常駐タイマーによる強制終了は未実装です。
report は渡されたチェック結果を合格条件と照合しますが、成果物ファイルの存在やハッシュ、チェック内容の正しさを独立に検証する機能はまだありません。信頼できる実行器・検証器から結果を渡す前提で、LLMの自己申告をそのまま合格にする設計ではありません。
サンプルJSONの成果物参照や結果も、CLIの動作確認用です。実データのバックテスト結果ではありません。
モデルと実行環境は実測して決める
計画上の評価環境はUbuntu、Xeon E5-2650 v3を2基、ECCメモリ256GB、RX570 8GBという構成を想定しています。CPU中心の動作を基準にし、GPUの対応可否や効果は別途確認する方針です。
モデルは計画・実装・レビューの役割ごとに候補を置いていますが、採用は未確定です。大きなモデルを選ぶだけでなく、次のような共通課題で比較します。
- 実行可能な依存関係と、明確な合格条件を作れるか
- 決めたJSON形式に従えるか
- 固定データと既知の期待値に対して正しく実装できるか
- 意図的に埋めた欠陥をレビューで見つけられるか
- 修正を含めて、どれだけの時間とメモリが必要か
MoEについても、活性パラメータ数をそのまま必要メモリと見なさないようにします。モデル本体、推論キャッシュ、読み込み時のピーク、モデル切り替え、OSやDifyの余裕まで含めて測ります。生成速度だけでなく、修正・レビューを含めた全体の所要時間を比較する予定です。
次に実装するもの
直近は、制御コアの外側を次の順でつなぎます。
1 Python実行器
プロセスの起動と終了確認、タイムアウト、cgroupによる資源制限、成果物の検証・確定を実装します。まずは固定の小規模データで、実行要求から結果保存までを通すことが目標です。
生成コードを動かすため、資源上限とアクセス制御も分けて扱います。cgroupだけでコードのアクセスを制限できるとは考えず、コントローラやDifyの認証情報をワーカーに渡さない構成にします。
2 常駐スケジューラ
期限タイマー、実行器との状態照合、無人の復旧、結果レポートを追加します。正常に完走するケースに加えて、途中停止、遅延した結果、期限切れでも、終了または保留に落ち着けるかを確認します。
3 推論アダプタ
llama-serverとの接続、ロールとモデル設定、LLM呼び出し数・トークン数の予算を実装します。今あるタスク試行数の上限だけでは、1試行の内部で行われるLLM呼び出しは制限できないため、別の管理が必要です。
4 Difyアダプタ
固定フローを呼び出し、Rustの試行IDとDify側の実行IDを対応させます。内部の自動再試行を抑え、二重実行・二重再試行を避ける設計を試験で確認します。
これらと並行して推論を実測し、最小実行経路、無人運転、日米の分析検証へと進める計画です。データ提供元、モデルと量子化、夜間の開始・終了時刻、保存期間などはまだ確定していません。
分析の合格条件も育てていく
分析側では、少なくとも次の点を検証対象にします。
- シグナルを作る時点で、未来の情報が混ざっていないか
- 終値で作ったシグナルと、約定時刻・価格の前提が整合しているか
- 株価調整、手数料、スリッページを明示しているか
- 日米の取引日、タイムゾーン、データ確定時刻を扱えているか
- 欠損、銘柄選択の偏り、過学習を確認できるか
- 同じ入力・コード・設定で再計算できるか
収益率や勝率の良さだけを、実装の合格条件にはしません。固定データと既知の期待値による計算の確認を先に行い、開発期間と評価期間も分けます。
将来的にはDifyのDSL自動生成も検討しています。ただし、最初は固定フローで動作を確認します。生成した定義は別の下書きで検証し、失敗したときに直前の合格済み版を残せるようにする計画です。実行中のグラフを自由に書き換えながら動かすことは前提にしていません。
この連載で残していくこと
次の記事の題材としては、Rustコントローラの状態遷移とテスト、Python実行器との接続、モデルの実測結果を考えています。
各回で「何を実装したか」「何を確認できたか」「まだ確認できていないこと」を残し、実測や障害試験の結果に合わせて計画を更新していきます。夜間枠に収まらなければ、対象数や探索量、モデル構成を見直す方針です。検証条件を下げて完了扱いにすることは避けます。
まずは、小さなデータで実行から検証・保存までをつなぐこと。そのうえで、失敗や中断にも対応できる範囲を一つずつ広げていきます。