Claude に 2 万円の実口座を渡して 3 ヶ月自動売買させたら、6 つの戦略すべてが検証で死んだ — それでも回収できたもの


自動売買のシミュレーションが 87.7% と見込んだ利確は、実弾では 24.1% しか起きなかった。walk-forward の out-of-sample 検証を通過した、3 ヶ月でいちばん有望だったはずの戦略が、実口座に乗せて 6.3 日で期待値ごと裏返った。約 2 万円の実口座と Python の bot と、その開発・検証・運用監視を回す Claude の無人基盤。この組み合わせで 6 月から 8 月まで、自動売買の戦略を 6 カテゴリ順に検証して、全部死んだ。ただし死に方はそれぞれ違っていて、この記事は 6 通りの死に方の記録だ。最後のひとつの授業料は、6.3 日で -45.4 円だった。

ルールを先に固定する — 事前登録という縛り

検証の型は最初に決めた。合格基準は戦略を動かす前に固定する。学習データ (in-sample) で最良だったパラメタを、未来のデータ (out-of-sample) にそのまま適用する。OOS の成績を見てから都合のいいセルを選び直すことはしない。基準を後から動かせば、どんな戦略でも合格に見せられるからだ。臨床試験の事前登録 (preregistration) の借り物だが、これをやらないバックテストは「勝てるまで探した記録」にしかならない。

もうひとつ先に決めたのは、負けたときの値段だ。実弾に進む場合はロットを 1 単位に固定し、日次損失に上限を置く。戦略が思想ごと間違っていても、失うのは日に数百円まで。「安く学ぶ」を、検証の中身より先に設計へ入れた。

bot 本体は Python だが、実装もテストも検証スクリプトも判定文書も週次レポートも、Claude Code が書いて回した。自分がやったのは方針の決定と、実弾に進む・止めるの承認だけだ。

第一波: テクニカル 4 種、walk-forward で全滅

6 月。最初はオーソドックスな 4 カテゴリを検証した。トレンド追従、クロスセクショナル・モメンタム、リバーサル、そしてリベート狙いのマーケットメイク。データは日足 11 ペア × 5.4 年 (2021-01〜2026-06)。

結果は一様で、in-sample で光る戦略ほど out-of-sample で崩れた。象徴はリバーサルだ。IS の最良パラメタは +498% を叩き出したのに、OOS では -73.6%。モメンタムは 45 パラメタ組のうち buy&hold の BTC を超えたものが、時間窓によって 0〜9 個。過去に効いたパラメタは、未来ではほぼ再現しなかった。リベート MM だけは小さく実弾まで進めたが、3 日で -266 円。板に指値を置いて手数料リベートを拾うだけの設計は、逆選択 (adverse selection) に食われた。

この時点の暫定結論はこうだ。価格を当てにいく戦略は、この市場・この資本規模では buy&hold に勝てない。

第二波: 日中の平均回帰は、学習データ内ですら負けた

7 月。時間軸を日中に下げた。10 秒間隔の ticker を 1 分足に集約し、z-score の行き過ぎを買う平均回帰 (mean reversion)。5 カテゴリ目になる。合格基準は動かす前に明文化した。年率 Sharpe 0.5 超、手数料込みの 1 トレード期待値プラス、OOS トレード数 30 以上。

結果は 5 ペア全滅。しかも予想と違う形の全滅だった。過学習して OOS で崩れたのではない。in-sample の全 45 セル (5 ペア × 9 パラメタ) が、最初からマイナスだった。理由は計算すると単純で、1 往復の取引コスト床 (スプレッド全幅 + taker 手数料) が、平均回帰で取れる値幅を上回っている。たとえば oas_jpy はコスト床 1.467% に対して、シミュレーション上の 1 トレード期待値は in-sample の最良セルでも -1.1% 以下、OOS では -1.776%。損失の大きさがコスト床とほぼ一致する。シグナルの良し悪し以前に、入って出るだけで負けが確定する構造だった。

最終章: OOS を PASS した 6 つ目が、実弾 6.3 日で覆る

残ったのが受動指値、いわゆるヒゲ取りだ。mid 価格より d% 下に post_only の買い指値を置き、約定したら建値の +e% に売り指値を置き、T 分で決まらなければ成行で手仕舞う。価格を予測しない。急落のヒゲを受け止めて、反発を 1 tick 拾うだけの戦略で、これが 6 カテゴリ目になる。

検証では優等生だった。in-sample では oas_jpy に頑健な正 EV のセルが 23 個並び、最良セルは日次 EV 145.1 円。そして事前登録どおり IS 最良セルを OOS 16.6 日分にそのまま適用した結果、主判定セルは日次 71.2 円の正 EV を維持し、決済は 399 件、23 セルすべてが正 EV のまま生き残った。判定は PASS。数値の転記は独立のエージェントに全数突合させ、別実装での再計算まで一致を確認した。ここまで、完璧に見えた。いま振り返れば、この時点で 6 月の死因を思い出すべきだった。

だから 8/5、実弾に進めた。ロット 400 円、日次損失上限 -500 円。判定の仕組みも動かす前に決めてあった。無人の週次レポートが毎週、シミュレーションの期待値と実弾のフィル (約定率・実現損益) を突き合わせ、乖離が大きければ停止を提案する。ただし白状すると、事前に固定したと言い切れるのはこの仕組みまでだ。「実現が期待の半分未満なら停止を提案する」という数値基準は週次レポート側の skill に書かれており、8/9 のレポートは実際にそれを引いて停止を提案してきた。だがその基準をパイロット開始前に文書化した記録は残っていないし、評価ウィンドウも最低サンプル数も決めていなかった。事前登録としては不完全だ。実際の停止も、8/9 の週次レポートが乖離を検出し、8/11 に自分が承認して決めた。基準の後出しを封じたはずの検証の最終段が、判定だけは人間の裁量に開いていた。

6.3 日と 57 トレードの実測結果が、実現損益 -45.4 円。シミュレーションの期待は同じ期間で +448 円だから、符号ごと裏返った。分解すると、シミュが 87.7% と見込んだ「指値での利確」が実弾では 24.1%。決済 29 件のうち利確が 7 件、タイムアウト損切りが 22 件。利確と損切りの比が、そっくり逆転していた。6.3 日は短い。それでも運では説明しがたい。利確率 87.7% が真なら、29 決済のうち利確が 7 件以下に留まる確率は、決済間の独立を仮定した見積もりで 10 のマイナス 15 乗のオーダーしかない。実際にはタイムアウト損切りは下落局面に固まり、決済は独立ではないから、この見積もりは楽観側に膨らんでいる。だが仮に有効サンプルを 1/3 の 10 決済相当まで割り引いても、確率は 10 のマイナス 6 乗のオーダーに留まる。偶然で引ける数字ではない。

根本原因: 防げた誤り、縮む乖離、知り得ない適応

乖離の機序は 3 つまで特定できた。

  • 自分の買い指値が約定する瞬間は、売り圧が強い局面に偏る (adverse selection)。そこから 1 tick 戻る確率は、シミュレーションが仮定した確率よりずっと低い
  • oas は価格 0.055 円に対して tick が 0.001 円。値段の刻みが 1.8% もあり、+1.0% の利確目標は切り上げで実効 +1.8% に広がって、届く前にタイムアウトする
  • 自分の指値が板に居ること自体が、他の参加者の行動を変える (undercut 競争)

当初は 3 つとも「シミュレーションの世界には自分がいない」というひとつの根で括ろうとした。だが腑分けすると、性質は 3 段階に分かれる。まず tick の切り上げ。これは無インパクト仮定とは関係のない、決定論的な仕様の見落としだ。取引所の tick 表と oas の価格を見比べれば、実弾に出る前に机上で検出できた。事前登録は基準の後出しを防いでくれるが、仕様の読み落としまでは防いでくれない。次に adverse selection。自分の指値が約定した瞬間は「相手がその値段で売りたかった」瞬間でもある、という情報を fill モデルが無視していた。これは fill モデルの忠実度の問題で、板の再生を精緻化すれば過去データの範囲でもある程度は縮められる。過去データから原理的に知り得ないのは undercut だけだ。シミュレーションは過去の板を再生して「ここに指値を置いていたら」を計算するが、その過去には自分の注文が存在せず、板に居る自分へ他の参加者がどう適応するかは、再生をどれだけ精緻化しても出てこない。後から置いた注文は誰の行動も変えない、という無インパクト仮定が本当に壊れるのは、この一点だった。

ここで 6 月に戻る必要がある。リベート MM は、まさに adverse selection に食われて死んだ。同じ maker 型で、死因の筆頭も同じだ。自分の一次データが 2 ヶ月前に「この市場では maker の fill はシミュレーションより不利に偏る」と警告していたのに、なぜ 8 月の fill モデルにその知見が入っていなかったのか。思い当たる答えはひとつで、OOS の PASS と独立検証の通過が「検証済み」という安心感を作っていた。検証の厳密さは、検証したカテゴリの中に閉じていた。リベート MM の死因はリベート MM の判定文書に記録され、受動指値の検証は受動指値の数字だけを見ていた。カテゴリ内の検証がどれだけ厳密でも、カテゴリをまたぐ盲点は自動では運ばれない。この 3 ヶ月でいちばん高くついたのは、たぶんこの教訓だ。

つまり 3 つのうち 2 つは、本来もっと事前に潰せたし、縮められた。それでも最後のひとつは残る。確かめられたのは自分の口座の中だけだ。事前登録して、OOS を通して、それでも実弾で覆った。

「安く学ぶ」設計は機能した

3 ヶ月の授業料を並べる。6 月のリベート MM が -266 円、8 月のパイロットが -45.4 円。パイロット期間の最悪日は -22.8 円で、日次上限 -500 円の 4.6%。上限に触れた日はゼロ。単一ロットと日次 cap を先に固定していたから、「戦略の思想が根本から間違っている」という最大級の発見を、合わせて缶コーヒー数本分で確定できた。

もうひとつ機能したのが無人の監視だ。収集と監視の基盤は 7/19 から 24 日間、人手を入れずに回した。無停止ではない — 7/19〜8/4 の OOS 16.6 日間だけでも 60 秒超のデータ欠損が 135 回・計 46.9 時間あり、最大は 7/20-7/21 の PC 停止による 25 時間だった。シミュレーション側はギャップ区間を fill させない設計でこれを吸収している。パイロット期間の daemon 稼働率は 98.8%。そして無人で 4 回走っていた週次レポートが、8/9 にシミュと実弾の乖離を人手ゼロで検出して報告してきた。自分はその報告を読んで、初めて乖離を知った。

残った操作

6 カテゴリすべてをクローズした後に残ったものを書いておく。正確を期すと、この 3 ヶ月で確定したのは「検証した 6 戦略のどれも、buy&hold を上回る根拠を示せなかった」こと、つまりアクティブ運用の付加価値を確認できなかったことであって、BTC 保有そのものの期待値は本記事の事前登録では一度も検証していない。不明のままだ。その前提で口座に残した操作は 3 つ。(1) BTC の保有 — これを上回れる操作が見つからなかったという消去法で残した。(2) 入金 — 唯一確実に資産を増やす操作だから。(3) 手数料まわりの構造的な特典 — これだけは市場観に依存しない構造的事実で、使っている取引所の bitbank では post_only の指値なら BTC の売買手数料が 0 になる。積立はすべてこの経路に寄せ、18 回・19,722 円の買付は全約定 maker で手数料 0 円、積立コアの形成は 8/7 に完了している。

「bot が寝ている間に増やしてくれる」という幻想は、3 ヶ月と数百円の実測で潰れた。代わりに残ったのは、事前登録つきの検証 6 本と、OOS 合格すら実弾で覆るという一次データと、負けを無人で検出する仕組みだ。増えたのは資産ではなく、何が増えないかについての確度だった。それで十分に元が取れたと思っている。

本記事は個人の実験記録であり、投資助言ではない。数字はすべて自分の口座の実測値で、他の誰かの環境での再現性を保証しない。

時間を、ゆっくりに。 — longdrift