優れたバックテストが何の意味も持たないことがある理由——そして、本物のエッジとカーブフィッティングによる幻想を見分ける方法。
スキャンを終えて Sharpe が最も高い組み合わせを選ぶと、バックテストの曲線は出来すぎなほど美しい。ところが実際に走らせてみると、その成績はランダムと見分けがつきません。その間に起きたことには名前があります。
戦略の過剰最適化とは、パラメータが過去データに合わせて精密に調整されすぎた結果、汎化できるルールを学ぶのではなく、実質的に過去を暗記している状態を指します。バックテストでは非常に優秀に見えますが、本番運用では成績が振るわない——あるいはランダムと変わらない結果になります。
過剰最適化は、必ずしも意図的に起こるものではありません。次のようなことをすると、自然に発生します。
100 通りのパラメータ組み合わせをスキャンしたとします。戦略にエッジがまったくなくても、偶然だけでプラスの Sharpe を出す組み合わせがいくつか現れます——有意水準 5% なら、100 個中およそ 5 個です。その中から最も良いものを選び、戦略の成績として報告すれば、それはノイズをシグナルとして報告していることになります。
この問題は、スキャンするパラメータが増えるほど深刻になります。独立したパラメータが 2 個で 20×20 のグリッドなら 400 通り、パラメータが 4 個で 10×10×10×10 のグリッドなら 10,000 通りです。次元が増えるたびに、運の良いピークに行き当たる確率は倍増します。
過剰最適化を避けるうえで最も重要な実務的テクニックは、ピークを選ばないことです。
パラメータスキャンの Sharpe ヒートマップを見てください。絶対的な最良セルは Sharpe 1.8 を示しているかもしれません。一つ左に動かすと 0.4、一つ上に動かすと 0.3。このピークは脆弱です——それが存在するのは、その特定のパラメータ組み合わせが、訓練データ内のいくつかの個別の市場イベントにたまたま適合したからにすぎません。
代わりに探すべきはプラトー(高原)です。多くの近傍パラメータ組み合わせにわたって Sharpe が一貫して高い領域のことです。パラメータ値の 3×3 の近傍全体で Sharpe が 1.2 なら、それは頑健なシグナルです——エッジは特定の一点だけでなく、ある程度の幅を持つパラメータ範囲に存在しています。
# Blave Agent の find_plateau:各セルの周囲 3×3 ウィンドウで # 平均 Sharpe が最も高い近傍を選ぶ—— # 単一の最大セルではない。 best_idx = argmax(neighborhood_average_sharpe)
これが、パラメータスキャンのスクリプト——各戦略のフォルダに置かれた scan.py——が単純に最良の Sharpe を取るのではなく find_plateau を使う理由です。なめらかなプラトーの上に位置するパラメータセットは、成績の悪い領域に囲まれた鋭いピークに位置するものよりも、はるかに汎化しやすくなります。
戦略の本当の成績を測る唯一の有効な方法は、その戦略が一度も見たことのないデータでテストすることです。2020–2023 のデータでパラメータを最適化し、2024 で評価するなら、2024 の成績は本物のアウトオブサンプル推定です。
2020–2024 で最適化して 2020–2024 の成績を報告するなら、それはインサンプルです。過剰最適化するつもりがなかったとしても、最適化の過程は 2020–2024 の結果を暗黙のうちに使ってパラメータを選んでいます。報告された Sharpe には、後知恵の恩恵が含まれています。
| 方法 | 有効? | 補足 |
|---|---|---|
| 全期間で最適化し、全期間の成績を報告 | ✗ | インサンプル——過剰最適化は確実 |
| 最初の 70% で最適化し、最後の 30% の成績を報告 | ✓ | 単純な訓練/テスト分割——有効だが限定的 |
| ウォークフォワード:ローリングウィンドウで最適化し、次の期間を報告 | ✓✓ | 最も現実的——本番運用と同じ方法 |
もう一つよくある過剰最適化の罠は、取り得るパラメータ値の全範囲をスキャンしてしまうことです。その中には、過去のある異常な期間でたまたま高い Sharpe を出しただけの極端な値も含まれます。
Blave Agent は閾値ベースの戦略には別のアプローチを取ります。スキャン範囲を指標自身の分布から導くのです。まず指標の過去分布の p5 と p95 を両端とし、その算術中点(中央値ではありません)を境目にします。エントリーの候補値は上半分(中点から p95)に、エグジットの候補値は下半分(p5 から中点)に置かれます。これにより、どちらの閾値も実際に観測されたデータ範囲に根ざしたものとなり、明らかに非現実的な極端値を避けられます。
Sharpe ヒートマップ上の鋭いピーク。 最良のパラメータ組み合わせが、はるかに低い値に囲まれています。どの方向にパラメータを一段動かしても Sharpe が 0.5 以上下がります。エッジは頑健ではなく、局所的なものです。
バックテストの Sharpe がアウトオブサンプルで維持されない。 訓練期間では Sharpe 2.0、取り置いたテスト期間では 0.2。この差が大きいほど、戦略は過剰最適化されています。
取引回数が極端に少ない。 3 年のバックテストで取引が 12 回しかない戦略には、統計的検出力がほとんどありません。運の良い数回の取引だけで、偶然に 2.0 以上の Sharpe が出てしまいます。バックテストの指標を意味のあるものとして扱う前に、最低でも 30–50 回の完結した取引を求めてください。
不自然にきりの良いパラメータ。 最良パラメータが SMA(50) / SMA(200)、RSI(14)、あるいはちょうど 1.0 / −1.0 になっている場合、それはスキャンの結果、よく知られた「デフォルト」値でたまたま当たりを引いただけであることが少なくありません。正しくない理由で機能している可能性があります。
特定の市場レジームでしか機能しない。 バックテストの成績が一度の強気相場または弱気相場だけによって生み出され、それ以外の期間はすべて横ばいかマイナスであるなら、その戦略は一般的なルールではなく、その特定のレジームを学習しただけかもしれません。
普遍的な上限はありませんが、役に立つ原則があります。追加する自由パラメータには一つひとつ、戦略ロジックの中に存在すべき事前の理由がなければならない、というものです。データによく当てはまるからという理由でパラメータを追加してはいけません——あなたが利用しようとしている市場メカニズムの、本物の次元を表しているからこそ追加するのです。
意味のある概念を表す二つのパラメータを持つ戦略(たとえば速いシグナル窓と遅い確認窓)は、チャート上で見える特定の損失期間を「消す」ためにいくつものパラメータが追加された、六つのパラメータを持つ戦略よりも、はるかに正当化しやすいものです。