戦略バックテストにおける過剰最適化の回避

優れたバックテストが何の意味も持たないことがある理由——そして、本物のエッジとカーブフィッティングによる幻想を見分ける方法。

最終更新 2026-09
要点まとめ
  • 過剰最適化とは、戦略がルールを学ぶのではなく過去のノイズを暗記している状態です。バックテストでは優秀に見えるのに、本番運用ではランダムと変わりません。
  • 100 通りのパラメータをスキャンすれば、戦略にエッジがまったくなくても、有意水準 5% のもとで偶然だけでおよそ 5 通りがプラスの Sharpe を出します。
  • ピークではなくプラトーを選びます。Blave Agent の find_plateau は、単一の最大値ではなく 3×3 の近傍で平均 Sharpe が最も高いセルを取ります。
  • スキャン範囲は指標自身の分布から育ちます。過去分布の p5 と p95 を両端、その算術中点を境目とし、エントリー閾値は上半分、エグジット閾値は下半分をスキャンします。
  • 過剰最適化の五つのサイン——孤立したピーク、アウトオブサンプルでの大幅な低下、取引回数が 30–50 回に届かない、成績が単一の市場レジームだけから出ている、損失期間を「消す」ためにパラメータを足している。

スキャンを終えて Sharpe が最も高い組み合わせを選ぶと、バックテストの曲線は出来すぎなほど美しい。ところが実際に走らせてみると、その成績はランダムと見分けがつきません。その間に起きたことには名前があります。

過剰最適化とは

戦略の過剰最適化とは、パラメータが過去データに合わせて精密に調整されすぎた結果、汎化できるルールを学ぶのではなく、実質的に過去を暗記している状態を指します。バックテストでは非常に優秀に見えますが、本番運用では成績が振るわない——あるいはランダムと変わらない結果になります。

過剰最適化は、必ずしも意図的に起こるものではありません。次のようなことをすると、自然に発生します。

  • 多数のパラメータ組み合わせをスキャンし、Sharpe が最も高いものを選ぶ
  • バックテスト結果を見てから戦略を修正し、同じデータで再テストする
  • チャート上で見えている損失期間を避けるためだけに条件を追加する
  • バックテスト期間が短く、運の良いパラメータ組み合わせが偶然だけで好成績を出してしまう
核心的な問題: どのバックテストデータにも、本物のパターンとノイズの両方が含まれています。十分に複雑な戦略は、必ずノイズにも当てはめられます。そしてノイズは将来繰り返されません。

パラメータスキャンの罠

100 通りのパラメータ組み合わせをスキャンしたとします。戦略にエッジがまったくなくても、偶然だけでプラスの Sharpe を出す組み合わせがいくつか現れます——有意水準 5% なら、100 個中およそ 5 個です。その中から最も良いものを選び、戦略の成績として報告すれば、それはノイズをシグナルとして報告していることになります。

この問題は、スキャンするパラメータが増えるほど深刻になります。独立したパラメータが 2 個で 20×20 のグリッドなら 400 通り、パラメータが 4 個で 10×10×10×10 のグリッドなら 10,000 通りです。次元が増えるたびに、運の良いピークに行き当たる確率は倍増します。

経験則: 戦略に自由パラメータが一つ加わるごとに、結果が統計的に意味を持つには、バックテストの取引回数がおよそ 10 倍必要になります。パラメータ二つでも、かなりの取引回数が要ります。パラメータ四つとなると、必要なバックテスト期間は通常、現実的ではありません。

ピークとプラトー

過剰最適化を避けるうえで最も重要な実務的テクニックは、ピークを選ばないことです。

パラメータスキャンの 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 から中点)に置かれます。これにより、どちらの閾値も実際に観測されたデータ範囲に根ざしたものとなり、明らかに非現実的な極端値を避けられます。

戦略が過剰最適化されているサイン

1

Sharpe ヒートマップ上の鋭いピーク。 最良のパラメータ組み合わせが、はるかに低い値に囲まれています。どの方向にパラメータを一段動かしても Sharpe が 0.5 以上下がります。エッジは頑健ではなく、局所的なものです。

2

バックテストの Sharpe がアウトオブサンプルで維持されない。 訓練期間では Sharpe 2.0、取り置いたテスト期間では 0.2。この差が大きいほど、戦略は過剰最適化されています。

3

取引回数が極端に少ない。 3 年のバックテストで取引が 12 回しかない戦略には、統計的検出力がほとんどありません。運の良い数回の取引だけで、偶然に 2.0 以上の Sharpe が出てしまいます。バックテストの指標を意味のあるものとして扱う前に、最低でも 30–50 回の完結した取引を求めてください。

4

不自然にきりの良いパラメータ。 最良パラメータが SMA(50) / SMA(200)、RSI(14)、あるいはちょうど 1.0 / −1.0 になっている場合、それはスキャンの結果、よく知られた「デフォルト」値でたまたま当たりを引いただけであることが少なくありません。正しくない理由で機能している可能性があります。

5

特定の市場レジームでしか機能しない。 バックテストの成績が一度の強気相場または弱気相場だけによって生み出され、それ以外の期間はすべて横ばいかマイナスであるなら、その戦略は一般的なルールではなく、その特定のレジームを学習しただけかもしれません。

パラメータは何個までか

普遍的な上限はありませんが、役に立つ原則があります。追加する自由パラメータには一つひとつ、戦略ロジックの中に存在すべき事前の理由がなければならない、というものです。データによく当てはまるからという理由でパラメータを追加してはいけません——あなたが利用しようとしている市場メカニズムの、本物の次元を表しているからこそ追加するのです。

意味のある概念を表す二つのパラメータを持つ戦略(たとえば速いシグナル窓と遅い確認窓)は、チャート上で見える特定の損失期間を「消す」ためにいくつものパラメータが追加された、六つのパラメータを持つ戦略よりも、はるかに正当化しやすいものです。

これらの手法でも救えないもの

  • プラトー選択が扱うのは「選んだそのセルが運かどうか」であって、「この戦略にそもそもエッジがあるのか」は扱いません。分布からスキャン範囲を導くのも同じです——過去にほとんど起きなかった極端値をテストさせないだけで、エッジのないルールをエッジのあるルールに変えてくれるわけではありません。
  • 上のインサンプル/アウトオブサンプルの表は概念レベルの判断です。製品レベルでは一文を足す必要があります。Blave に「30% をテストセットに取り置く」という設定はなく、唯一のアウトオブサンプルの道具は、ワークスペースの 5 番目のタブの rolling walk-forward で、2 つの入力欄に入れるのは日数です。検証する対象は単純な分割とは違います——〈アウトオブサンプル検証のやり方:ここに「30% をテストセットに」がない理由〉をご覧ください。
  • この記事が答えていない問いがもう一つあります。アウトオブサンプルを通ったとしても、その成績は運なのか? それは有意性検定の仕事で、〈バックテストの利益は実力か運か:MCPT の p 値の読み方〉をご覧ください。アウトオブサンプルと有意性は同じことを問うているのではなく、2 つのツールが同じ答えをくれる保証もありません。