開発史(2) DryRunでは勝てるのに、実弾では勝てない——BUY RESET問題の解剖

前回は、BotがRust+Pythonの二層構成に育つまでを書きました。今回は、この開発でもっとも高い授業料を払った問題の話です。

先に結論の数字を出します。シミュレーション(DryRun)での勝率71.7%。同じロジックを実弾(Live)で動かした勝率、5.9%。

7割勝てるはずのBotが、実戦では20回に1回しか勝てない。この乖離の原因を突き止めるまでの記録です。恥ずかしい話ですが、この種の「バックテストと実戦の乖離」はおそらく自動売買開発の通過儀礼で、しかも原因は人によって違います。私たちのケースが、誰かの点検リストの一項目になれば幸いです。

時間の流れで見ると、何が起きていたか

まず、1回の取引を時系列で追います。

Botはトークン発行の約3秒後に入場を判定し、買い注文を送ります。ところが当時の構成では、注文がブロックチェーン上で実際に約定(着地)するまでに15秒以上かかることがありました。混雑した市場では、注文は送った瞬間ではなく、届いた瞬間の価格で成立します。そして発行直後のミームコインの15秒は、価格が3割動くには十分な時間です。

つまり「3秒時点の安い価格を見て入場を決めたのに、実際に買えたのは20秒時点の高い価格」。ここまでは、いわゆるスリッページの話で、想定の範囲でした。問題は、この後です。

犯人は、正確であろうとした1つの処理だった

Botの内部には「BUY RESET」と呼んでいた処理がありました。買い注文の着地を確認した瞬間に、ポジションの取得価格を、着地時点の実際の価格で上書きする処理です。

意図は真っ当です。原価は正確に記録すべきで、注文時の価格ではなく、実際に買えた価格を使うのが正しい。会計としては何も間違っていません。

しかし取引の判定基準として見ると、これは「高値づかみを、高値のまま基準に固定する」処理でした。3秒時点の価格で入るつもりが、20秒時点の吊り上がった価格が取得価格として固定される。直後に価格が初動の過熱から少し戻るだけで、Botの目には「取得価格からの下落」に見え、損切り(ストップロス)が発火する。本来なら含み益のはずの取引が、機械的に赤字で確定していきます。

BUY RESETによる高値づかみの固定の構造図
BUY RESETによる「高値づかみの固定」の構造(概念図)

決定的だったのは、出口理由別の集計でした。損切りで出た取引も、利確で出た取引も、トレーリングで出た取引も、すべての出口理由で一様に、実弾がシミュレーションより大幅に悪い。特定の戦略の欠陥なら、悪化は特定の出口に偏るはずです。全部が一様に悪いということは、全ポジションに共通する仕組みの欠陥——つまり入口側の価格の持ち方が疑わしい。この消去法が、BUY RESETに行き着く決め手になりました。

なぜシミュレーションでは見えなかったのか

答えは単純で、シミュレーションの世界には15秒のラグが存在しなかったからです。

当時のDryRunは、入場判定の0.1秒後に約定する世界でした。判定した価格とほぼ同じ価格で買え、取得価格の上書きも起きない。つまりDryRunの勝率71.7%は、ロジックの実力ではなく、「遅延ゼロの世界でなら勝てる」という、実在しない世界の成績だったのです。

物差し自体が甘いと、その上で行うすべての最適化が架空の世界への最適化になります。前回「測る道具を先に校正する」と書いたのは、この経験があるからです。

3つの選択肢と、選んだ道

原因が分かってから、3つの案を検討しました。

案A・シミュレーションに実測ラグを組み込む。DryRunの約定タイミングを、実測した遅延に合わせて遅らせる。物差しが正しくなる代わりに、DryRunの勝率は大幅に下がり(71.7%から半分程度への低下を覚悟)、それまでに最適化したパラメータは全部作り直しになります。

案B・取得価格の上書きに割引補正を入れる。1行の修正で済む応急処置。ただし割引率の根拠が弱く、補正しすぎれば本来切るべきポジションを抱え込みます。

案C・上書きの廃止。乖離は消えますが、取得価格が実態より低く固定されるため、損切りの基準が壊れます。これは危険なので却下。

選んだのは「短期は案Bで止血し、本命は案Aでやり直す」でした。ここで重要だったのは、案Aを選ぶことは、自分たちの成績表が悪くなることを受け入れる決断だったという点です。甘い物差しのままなら、DryRunの上では勝ち続けられました。それを捨てて、勝率が半分に落ちる正直な物差しに乗り換える。以後、この開発では「紙の上の数字は、実弾で測り直すまで割り引いて扱う」が原則になりました。

この失敗から持ち帰れるもの

3つに要約します。

第一に、バックテストの成績は、バックテストの甘さの成績かもしれない。疑うべきはロジックの前に、シミュレーションと実環境の差分(遅延・約定・手数料)です。

第二に、乖離の診断には「一様性」を見る。特定条件だけ悪いなら戦略の欠陥、全条件で一様に悪いなら共通機構の欠陥。この切り分けが原因究明を一気に短縮します。

第三に、正確さと正しさは別物。BUY RESETは会計的には正確でした。しかし判定基準としては間違っていた。1つの数字が複数の役割を持つとき、その役割ごとに正しさを点検する必要があります。

次回は毛色を変えて、AIとの協働で起きた事件の話——AIが承認なしにBotを再起動した日と、その後に作った運用規律について書きます。


本サイトはBot開発と検証手法の記録であり、投資助言ではありません。記事中の数値は特定期間の観測に基づくもので、将来の結果を保証しません。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次