← 記事一覧に戻る
July 5, 2026
読了時間: 5分

フィデリティゲート: 安価なプロキシが高価な評価と同じ順位付けをしない限り、粗密探索バックテストはより速くあなたを欺く

フィデリティゲート: 安価なプロキシが高価な評価と同じ順位付けをしない限り、粗密探索バックテストはより速くあなたを欺く
#アルゴトレード
#バックテスト
#マルチフィデリティ
#Hyperband
#ASHA
#successive halving
#過学習
#検証
Part 6 of 10 · Collection
High-Performance Backtest Engines

「幻想なきバックテスト」シリーズの一部。

本気で取り組むパラメータ探索は、どれも同じ壁にぶつかる。探索空間は膨大で、まともな評価はどれも高くつく。十数個の閾値と3つのインジケーター期間を持つマルチタイムフレーム戦略を、複数フォールドのウォークフォワード分割で評価すると、1設定あたり数秒かかることもある。1万設定ともなれば数時間だ。そこで人は近道を探し、その近道はいつも同じ発想に行き着く。安価に評価し、生き残ったものだけを高価なテストに昇格させるというものだ。1万設定を1フォールドでスクリーニングし、上位数百件だけを残し、それらを全フォールドで実行する。1時間足でスクリーニングし、ファイナリストだけを1秒足まで掘り下げる。

これが粗密探索——ドリルダウン、マルチフィデリティ、successive halving、Hyperband、ASHA——であり、最適化における正真正銘の名案の一つだ。1日分の計算を1時間に圧縮できる。我々もこれを使っている。しかしこの手法は、導入したほとんどの人が確認すらしないほど静かな罠を隠し持っている。その罠とは、手法全体が、安価なプロキシが高価な評価と同じ順位で設定をランク付けするという前提の上に成り立っているということだ。もしそうでなければ、あなたは速く探索しているのではない。最初のゲートで将来の勝者を捨て去り、ノイズを昇格させているだけであり——ただ自分をより速く欺いているにすぎない。

本稿が扱うのは、あなたのドリルダウンが本物か幻想かを教えてくれるたった一つの測定についてだ。我々はこれを自分たちのマルチタイムフレーム探索で実行し、その答えは居心地の悪いものだった。最も安価なフィデリティでは、我々のプロキシは設定をほぼランダムにランク付けしていた(Spearman ρ ≈ 0.03)。もしそのフィデリティで積極的に枝刈りをしていたら——市販のASHAのデフォルト設定はまさにそれを促すのだが——最終的な勝者を最初のラウンドで捨てていたことになる。解決策は、探索の前に実行する必須のゲートだ。順位相関を測定し、それが信頼できるフィデリティを下回っては枝刈りを行わないようにする。

マルチフィデリティ探索とは実際には何か

粗から密への探索カスケード: 左側で数千の安価な低フィデリティ設定が幅広くスクリーニングされ、生き残った上位のみが右方向へ、段階的により高価なフル評価へと昇格していく — successive halvingが広大なエメラルド色の候補群を絞り込み、少数の明るいファイナリストへと収束させる

この一群の手法はすべて同じ形をしている。まずフィデリティリソース予算とも呼ばれる)を定義する。これは安価から高価へと動かせるダイヤルで、最大値にすると真の目的関数の値が得られる。次に低フィデリティで設定を実行し、順位付けし、上位の一部だけを残し、生き残ったものだけをより高いフィデリティで再実行する——これを、少数のファイナリストがフルフィデリティで評価されるまで繰り返す。

successive halvingJamieson & Talwalkar, 2016)が核となる考え方だ。N個の設定を最小リソースで開始し、上位1/ηだけを残し、リソースをη倍にして繰り返す。HyperbandLi et al., 2018)はsuccessive halvingを外側のループで包み込み、開始リソースの取り方をヘッジすることで、どれだけ積極的に枝刈りすべきかを推測しなくて済むようにする。ASHALi et al., 2020)は非同期・並列実行向けのバージョンだ。淘汰率ηはこれらすべてに共通する唯一のつまみであり、標準的なデフォルトはη = 3——各ラングで上位3分の1を残し、予算を3倍にする——である。

フィデリティそのものは、安価から高価へと動かせて真の値に収束するものであれば、ほぼ何でもよい。

  • ウォークフォワードのフォールド数。 1フォールド、次に2フォールド、3フォールドと、Kまで評価していく。これが以下で扱うフィデリティだ。ローリング方式のアウトオブサンプル分割を持つバックテストにとって、これが最も自然なフィデリティだからだ。
  • ローソク足の解像度。 1時間足でスクリーニングし、1分足へ昇格させ、ファイナリストに限って1秒足または生の約定データまで掘り下げる。これは適応的ドリルダウンの発想を、約定シミュレーションではなく探索に適用したものだ。
  • 履歴の長さ、エポック数、データセットのサブサンプル——古典的な機械学習のフィデリティだ。

バックテストにおいて重要なのはフォールドと解像度の2つであり——これが本稿全体の要点なのだが——両者は同じように安全というわけではない。 一方には、どれだけ注意深くゲートを設けても静かに誤ったパラメータを選んでしまうバイアスが潜んでいる。

すべてが依拠するたった一つの前提

ドリルダウンの静かな崩壊: 安価な低フィデリティの順位付けが高価なフル評価の順位付けと食い違い、真のエメラルド色の勝者が最初のゲートで刈り取られる一方、赤橙色のノイズが上へと昇格していく——それでもエラーは一切発生しない

successive halvingが正しく機能するために実際に何が必要かを書き出してみよう。安価なフィデリティが正しい目的関数のを返す必要はない——1フォールドが6フォールドと異なるSharpeを報告したところで誰も気にしない。必要なのはもっと弱いが、はるかに具体的な条件だ。安価なフィデリティは、高価なフィデリティと同じ順位で設定をランク付けしなければならない。設定Aがフルフィデリティで設定Bに勝るなら、Aは低フィデリティでもBに勝る傾向があるべきだ。それだけだ。そしてそれがすべてでもある。

形式的に言えば、ドリルダウンが機能するかどうかを支配する量は、設定空間全体にわたる低フィデリティと高フィデリティの目的関数の間の順位相関である。この相関が高ければ、安価なラウンドの生存者は高価なラウンドでも勝っていたはずの設定と同じであり、計算コストをただで節約できたことになる。低ければ、安価なラウンドはランダムなフィルターにすぎない。良い設定を捨て、悪い設定を昇格させ、予算を使ってより悪い答えへと加速していることになる。あなたを救ってくれるηの中間設定は存在しない——悪いプロキシは、穏やかに枝刈りしても勝者を漏らし続け、積極的に枝刈りすればそれを大量に失うことになる。

この失敗は、いつもと同じやり方で目に見えなくなる。探索は完了し、チャンピオンを報告し、そのチャンピオンはインサンプルでは問題なく見える。エラーは何も発生しない。プロキシが嘘をついていたと発覚するのは、チャンピオンがアウトオブサンプルで崩壊したときだけであり——その頃にはもう、失敗の原因を戦略のせいにしてしまっていて、それを選んだ探索のせいだとは考えない。だからこそ、このシリーズが繰り返し行き着く規律は同じものだ。手法を信頼する前に、その手法が前提としているものを測定せよ。 ドリルダウンにとって測定すべきものは順位相関であり、その測定自体は安価である。

測定する: フィデリティゲート

チェックポイントとしてのフィデリティゲート: どのラングも信頼される前に、およそ200個のランダムな設定があらゆるフィデリティレベルでスコア付けされ、安価なプロキシとフル評価の間の順位相関が、光を放つゲートで測定される——このゲートは2つの順位付けが一致したときにだけ開く

このゲートは、本番の探索の前に一度だけ、これから探索しようとしているのと同じ空間に対して行う小さな実験だ。手順は以下の通り。

  1. パラメータ空間から数百個の設定をランダムに抽出する(我々は約200個を使う——安定したSpearman推定には十分で、コスト的にも十分安い)。
  2. それぞれをすべてのフィデリティラングで評価する。1フォールド、2フォールド、……フルのKフォールドまで。フォールド数によるフィデリティの場合、これはほぼ無料でできる。安価なラングのために計算したフォールドが、高価なラングでも累積平均として再利用されるからだ。
  3. 各ラング r について、その約200個の設定にわたる、rフォールドの順位付けとフルKフォールドの順位付けの間のSpearman順位相関を計算する。
  4. ρが閾値(我々はρ ≥ 0.5を使う)を超える最初のラングが、枝刈りを許される最も浅いフィデリティとなる。それより下では、順位付けはノイズが多すぎて信頼できず、そこで設定を排除してはならない。

全体でもコード数十行に過ぎない。その核心部分は以下の通り。

def fidelity_check(cache, n_probe, seed=7):
    """Spearman ρ: cumulative mean over the first r folds (in FOLD_ORDER)
    vs the full K-fold objective, on n_probe random configs."""
    rng = np.random.default_rng(seed)
    k = len(FOLDS)
    per_fold = np.empty((k, n_probe))
    order_win = np.array([list(FOLDS[fi]) for fi in FOLD_ORDER], np.int64)
    for j in range(n_probe):
        p = _unit_to_params(rng.random(len(PNAMES)))       # random config
        scores, *_ = eval_group(cache, p, _sp_of(p)[None, :], order_win, False)
        per_fold[:, j] = scores[0]                          # score on each fold
    cums = np.cumsum(per_fold, axis=0) / np.arange(1, k + 1)[:, None]  # r-fold mean
    rhos = []
    for r in range(1, k):
        rho = spearmanr(cums[r - 1], cums[-1]).statistic    # r folds vs all K
        rhos.append(0.0 if math.isnan(rho) else rho)
    return rhos

一つ意図的な細部に注目してほしい。フォールドは FOLD_ORDER の順序で取られており、これはカレンダー上の初期と後期のスライスを交互に取るインターリーブ順序だ(フォールド0、次に中間のフォールド、次にフォールド1、次に後の方のフォールド、……)。これは非常に重要で、後の節で扱うテーマでもある。つまり「1フォールド」とは履歴の中間にまたがる1つのスライスであり、「2フォールド」とは初期と後期のスライスを1つずつ合わせたものであって——連続した直近のウィンドウでは決してない。安価なフィデリティは、より最近のフォールドを使うのではなく、より少ないフォールドを使うことで安くなっているのだ。

結果: 1フォールドではほぼランダムな順位付けになる

フォールド数とともに上昇する順位相関: 1フォールドではコイントス同然の散らばりから始まり、5フォールドまでにほぼ完全な一致へと急上昇していくSpearman rhoの曲線。中間には水平なゲート線が引かれており、それより下では枝刈りが禁止され、上では許可される

以下が、我々の2つのマルチタイムフレーム設定でこのゲートを実行した結果だ。この数値は、約200個のランダムな設定にわたる、rフォールドの順位付けとフルKフォールドの順位付けの間のSpearman ρである——安価なフィデリティの順位付けが、フルフィデリティの順位付けをどれだけ忠実に予測しているかを示す。

フォールド数 r マルチTF実行 より難しいレジーム
1 +0.43 +0.03
2 +0.67 +0.43
3 +0.78 +0.78
4 +0.82
5 +0.91 +0.91

まず「より難しいレジーム」の列を見てほしい。こちらの方が衝撃的だからだ。1フォールドでρ = 0.03。 これは弱い相関ではなく、相関がないということだ——200個の設定を1フォールドでランク付けした結果は、統計的にシャッフルしたものと見分けがつかない。(大半がそうであるように)デフォルトで min_resource = 1 から枝刈りを開始するように設定されたsuccessive halvingの実行は、このレジームでは、最初の、そして最も積極的な選別をコイントスで行うことになる。フルフィデリティで最終的に勝つはずの設定が、まさに最初のラウンドを生き残れるかどうかは五分五分だ。順位付けが何らかの意味を持つフィデリティ(3フォールドでρ = 0.78)にたどり着く頃には、その大半はすでに消えている。

マルチTFの列はより穏やかだが、同じ論点を別の形で示している。そこでも1フォールドではρ = 0.43——我々の0.5というゲートを下回る。まともな相関に見えるが、それこそが危険なのだ。0.43は油断させるには十分高く、最良の設定を漏らすには十分低い。順位付けが信頼できるようになるのは、2フォールド(ρ = 0.67)に達してからだ。

ここから一般化できることが2つある。第一に、1フォールドでのρはレジーム依存で信頼できない——我々は設定ごとに0.03から0.43まで様々な値を測定し、どちらの場合も1フォールドだけでは基準をクリアしなかった。第二に、ρは単調かつ急速に上昇する。3フォールドの時点で両設定とも0.78に達し、5フォールドでは0.91に収束する。シグナルは確かに存在する。それを見るために十分なフィデリティを費やしさえすればよい。ゲートの役目は、「十分」が始まる正確なラングを見つけ出し、それより下での枝刈りを禁じることだ。

なぜ1フォールドはこれほどノイズが多いのか

このノイズは我々のフォールド構成のバグではなく、本質的なものであり、その理由を理解しておけば間違った方向で「修正」してしまうことを防げる。1つのウォークフォワードフォールドは短いウィンドウ——1つの市場レジームの数週間分にすぎない。そのウィンドウでの戦略のスコアは、そのパラメータがたまたまそのレジームにどれだけうまく適合したかによって支配されており、それは戦略がどれだけ汎化するかとは緩くしか関係しない。本質的に品質が異なる2つの設定が、1フォールドだけでは順位が入れ替わることがある。単に一方がそのフォールドがたまたま含んでいたトレンドを捉えただけで。1フォールドでの目的関数値は、本当に気にしている目的関数の高分散な推定量であり、順位相関こそが高分散によって真っ先に破壊されるものだ——推定量の平均値は保たれていても、その順位付けは純粋なノイズになり得る。

フォールドを追加することで、この分散は平均化されて下がっていく。各フォールドは市場状況の部分的に独立した抽出であり、rフォールド平均はより低分散な推定量であって、その順位付けはフルフィデリティの順位付けへと収束していく。それがまさにρ = 0.03 → 0.43 → 0.78 → 0.91という上昇の正体だ。目的関数自体が変化しているのではなく、レジーム固有の運が平均化されて消えていくにつれて、その順位推定が安定化していくのだ。教訓は、バックテストにおけるフィデリティとは、根本的には独立したレジームをいくつサンプリングしたかという問題であるということであり——1つでは順位付けの根拠としてほぼ常に不十分だということだ。

これはまた、なぜ「より難しいレジーム」では0.03から始まり、マルチTF実行では0.43から始まるのかも説明する。より難しいレジームでは、単一フォールドがよりレジーム固有的だ——設定の1フォールドスコアは、持続的なエッジよりも運によって左右される度合いが大きく、そのためランダムに近い順位付けになる。ゲートはその違いを自動的に読み取り、枝刈りを行う前により多くのフォールドを要求することで応答する。自分がどのレジームにいるかを事前に知る必要はない。測定すればよいのだ。

コードで見るゲート: 最小フィデリティの自動引き上げ

ゲートの出力は1つの整数、すなわちASHAが枝刈りを許される最も浅いフィデリティである min_resource である。ルールは機械的だ——ラングを順に見ていき、ρが閾値をクリアする最初のラングを採用する。

RHO_GATE = 0.5
min_res = len(FOLDS)                      # default: pruning OFF (full fidelity)
rhos = fidelity_check(cache, n_probe=200) # [ρ@1, ρ@2, …, ρ@(K-1)]
passing = [r for r, rho in enumerate(rhos, 1) if rho >= RHO_GATE]
if passing:
    min_res = passing[0]                  # first rung that clears the gate

pruner = SuccessiveHalvingPruner(min_resource=min_res, reduction_factor=3)

これを2つの実行例でたどってみよう。マルチTFの設定では、ρ@1 = 0.43はゲートを通過できないが、ρ@2 = 0.67は通過するので、min_resource は自動的に2に引き上げられる。ASHAは何かを排除する前に、すべての設定を少なくとも2フォールドで実行し、それ以降は通常通り枝刈りを行う。より難しいレジームでは、ρ@1 = 0.03とρ@2 = 0.43がともに失敗し、ρ@3 = 0.78が最初にクリアするので、min_resource3になる。そして重要なフォールバック処理がある。どのラングも0.5に達しない場合、passing は空になり、min_resource はKのままとなる——枝刈りは完全にオフになり、探索は速いが誤った探索ではなく、素直なフルフィデリティ探索へと優雅に劣化する。自分のプロキシを証明できないドリルダウンは、単に枝刈りを拒否するのだ。

これは制御フローのたった1行に凝縮された哲学全体だ。あらゆるsuccessive halvingライブラリのデフォルトは「min_resource = 1 から枝刈りし、安価なラングを信頼せよ」というものだ。ゲートはそれを「データが信頼できると告げる最初のラングから枝刈りし、どこも信頼できなければ枝刈りするな」に置き換える。事前に約200設定分のプローブを1回実行するコストがかかるだけで、ドリルダウンを信仰の行為から測定に基づく決定へと変える。淘汰率η = 3はそのままだ。ゲートはどれだけ強く枝刈りするかには手を触れず、どれだけ早く始めることを許すかにだけ関わる。

上のコードから見て取れる、正直に述べておくべき点が1つある。min_resource を引き上げると高速化の恩恵は目減りする。1フォールドではなく3フォールドで枝刈りするということは、捨てることになる設定も含め、すべての設定が3フォールド分のコストを払うということだ。それが正しさの代償であり、それは正しいトレードオフだ。本物の勝者を見つける探索での2倍小さい高速化は、勝者を捨ててしまう探索での6倍の高速化に勝る。ゲートはそのトレードオフを隠すのではなく、明示的に行う。

誤った安価軸: より短い履歴は罠である

誘惑的で、わかりやすく、しかもバイアスがかかっている安価なフィデリティが存在する。誰もが真っ先に手を伸ばすものなので、名指しで取り上げる価値がある。それはより短い履歴だ。直近1ヶ月で設定をスクリーニングし、生き残ったものを丸2年分のデータへ昇格させる。これは自明なほど安価で、フォールド数を減らすのと同じ発想のように感じられる。しかし、そうではない。

フォールド数を減らすことと履歴を短くすることは、決定的な一点で異なる。フォールド数によるフィデリティは、正しく行えばカレンダー全体にまたがったままであり、単により粗くサンプリングするだけだ。履歴を短くするフィデリティは、カレンダーの一部の区間を密にサンプリングする。そして市場履歴の一部区間とは、特定のレジームのことだ。直近1ヶ月で設定をランク付けするとき、あなたは全期間の順位に対するノイズはあるが不偏な推定値を得ているのではない。直近1ヶ月のレジームに合わせて調整された設定を体系的に優遇する偏った推定値を得ているのだ。サンプルサイズをいくら増やしても——より多くの設定、より多くの試行で平均を取っても——バイアスは縮小しない。なぜならそれは分散ではないからだ。あなたはスクリーニングウィンドウに最もよく適合する設定を昇格させることになり、それはまさに一時的なレジームに過学習している可能性が最も高い設定なのだ。

だからこそ我々のフィデリティは、時系列順ではなくインターリーブ順でフォールドを進む。K個のフォールドが履歴全体に散らばっていれば、「1フォールド」は中間付近の1つのスライスであり、「2フォールド」は初期と後期のスライスを1つずつ、「3フォールド」は初期/中間/後期に広がる——最も安価なものも含め、あらゆるフィデリティレベルがカレンダー全体をサンプリングする。安価なプロキシは期間の粗い眺めであって、その一部のスライスの鮮明な眺めでは決してない。このインターリーブこそが、フォールド数によるフィデリティを、バイアスがかかったもの(どんなゲートでも直せない——バイアスのかかったターゲットに対する高いρは、レジームに適合した設定を安定して選んでしまうことを保証するだけだ)ではなく、単にノイズが多い(ゲートで治せる)ものにしているのだ。フィデリティを安くする唯一の方法がより最近のものにすることであるなら、それは有効なフィデリティではない。 代わりに、より粗くせよ。

誠実な安価軸としての解像度

もう1つの安価軸は、バイアスを完全に回避するもので、約定シミュレーションについて説明した適応的ドリルダウンの自然な相棒である。ローソク足の解像度だ。空間全体を1時間足でスクリーニングし、生存者を1分足へ昇格させ、ほんの一握りのファイナリストに限って1秒足または生の約定データまで掘り下げる。同じ全履歴に対してより粗いローソク足を使えば、評価はより安くなる——バーの数が減り、インジケーターの計算が速くなり、シミュレーションも速くなる——そして、より短いウィンドウとは異なり、カレンダーの粗い眺めは不偏である。すべてのレジームを見ているのであり、ただバー内部の詳細が少ないだけだ。

解像度とフォールドは互いに補完し合うフィデリティ軸であり、フィデリティゲートは両方に適用される。1時間足のスクリーニングを信頼する前に、同じプローブを実行しよう。約200個の設定を取り、1時間足と1分足でスコア付けし、順位相関を測定する。ρ(1時間足, 1分足) が高ければ、時間足でのスクリーニングは安全であり、誠実な形で大きな高速化を手に入れたことになる。低ければ——これは戦略のエッジが1時間足では均されてしまうバー内部の構造に宿っている場合に起こる——1時間足でのスクリーニングはその戦略にとってランダムなフィルターであり、ゲートはより細かいところから始めるよう告げてくる。ルールは決して変わらない。あるフィデリティで枝刈りが許されるのは、その順位付けが真実と一致することを測定した後に限られる。

この2つの軸は失敗の仕方も正反対であり、それが役に立つ。粗い解像度はバー内部の情報を失い、フォールド数が少ないとレジーム横断の情報を失う。日足の時間軸で動くモメンタム戦略は、1時間足で完璧に順位付けされるかもしれないが、レジームの運を平均化するには多くのフォールドが必要かもしれない。スキャルピング戦略は少ないフォールドでも問題なく順位付けされるかもしれないが、1秒足を超える解像度では崩壊するかもしれない。軸ごとに実行するゲートは、たまたま都合の良い答えを仮定するのではなく、この戦略についてどのフィデリティなら安く済ませて構わないのかを教えてくれる。

節約は実際どこから生まれるのか

ドリルダウンを誠実に保つための注意点が1つある。**フィデリティは、コストが実際に存在している場所でしか計算を節約できない。**我々のマルチタイムフレームエンジンでは、高価な部分はインジケーターの事前計算——マルチタイムフレームHMAと分離シグナル——であり、これはどのフォールドが実行される前にも、設定ごとに1回だけ支払われる。キャッシュされたシグナルに対するフォールドごとのシミュレーションは、比較的安価だ。したがって、フォールド数による枝刈りはシミュレーションコストしか節約できず、支配的なインジケーターコストは節約できない。フォールド数によるフィデリティは本物ではあるが、その上限は単純なフォールド比率が示唆するよりも低い。

対照的に、解像度軸は支配的なコストを直接攻撃する。より粗いローソク足は、インジケーターを計算する対象となるバーが少なくなることを意味し、高価な事前計算と安価なシミュレーションの両方がともに縮小する。これは些細な話ではない——どちらのドリルダウンを構築する価値があるかを決めるものだ。マルチフィデリティ探索に投資する前に、自分の秒数がどこに使われているかを問おう。90%がフォールド間で共有されるインジケーターの事前計算であれば、フォールド数によるフィデリティはほとんど得るものがなく、解像度によるフィデリティは大きな利益をもたらす。まずプロファイルを取ること。正しい安価軸とは、実際に存在するコストを取り除くものであり、それでもなおゲートをクリアしなければならない。

つながる先

フィデリティゲートは、このシリーズが積み上げてきたバックテスト衛生の連鎖の中で、特定の位置を占めている。

  • これは**過学習の制御よりも上流にある。**悪いプロキシで枝刈りするドリルダウンは、新手の過学習の仕方だ——ノイズの多い早期のラングにファイナリストを選ばせてしまっているのだから。チャンピオンはそれでもなおDeflated SharpeとPBOを生き延びなければならず、これらのゲートに投入される試行数には、生存者だけでなく枝刈りされたすべての試行を含めなければならない。枝刈りをしたからといって、その試行が多重検定の帳簿から免除されるわけではない。
  • これはプラトー分析と敵を共有している。1つのフォールドや1つのスクリーニングウィンドウだけで勝ち、他ではまったく勝てない設定は、両方のツールが排除するために存在する同じレジーム適合の産物だ。ゲートはそのようなフォールドで選ぶことを拒み、プラトー分析はそのようなフォールド1つの上に立つチャンピオンを信頼することを拒む。
  • その根底には、誠実なウォークフォワード分割——カレンダー全体にまたがるフォールドと、取り分けられたアウトオブサンプル——があることを前提としており、これは約定シミュレーションのために構築したドリルダウンの、探索時における対応物である。同じ粗密の原則を、どれだけ精密に約定させるかではなくどの設定を評価するかに適用したものだ。
  • そしてこれは、フィデリティがどのラングにおいてもリークがないことに絶対的に依存している。もし安価なラングに、高価なラングにはない先読みバイアスがあれば、ρは汚染されたターゲットとの一致度を測っているにすぎず、ゲートはリークにお墨付きを与えてしまうことになる。順位相関を測定するのはよいが——それは誠実な目的関数の上でなければならない。

統一的な考え方は、このシリーズが繰り返し訴え続けているものと同じだ。バックテストとは統計的な実験であり、その中のあらゆる近道は、検証する義務のある仮説である。ドリルダウンの仮説は「安価な順位 ≈ 高価な順位」というものだ。これは約200個の設定で検証可能だ。検証せよ。

まとめ

  1. 粗密探索はたった一つの前提の上に成り立っている。安価なプロキシが高価な評価と同じように設定をランク付けするという前提だ。 同じ値ではなく、同じ順位である。順位相関が低ければ、積極的な枝刈りは将来の勝者を捨て、ノイズを昇格させる。あなたはより悪い答えに向かって、より速く探索していることになる。
  2. 信頼する前に測定せよ。 約200個のランダムな設定を抽出し、あらゆるフィデリティラングでスコア付けし、各安価なラングとフルフィデリティの順位付けの間のSpearman ρを計算する。コード数十行と、1回の安価なプローブでできる。
  3. 1フォールドではほぼランダムな順位付けになる。 我々はρ@1が、レジームによって0.03(コイントス)から0.43(それでも信頼水準以下)までの範囲になることを測定した。フォールドが増えるにつれて0.67、0.78、0.82、0.91へと上昇していく。市販のあらゆるASHAのデフォルトである min_resource = 1 は、バックテストにおいては大抵の場合誤っている。
  4. ρ ≥ 0.5となる最初のラングまで最小フィデリティを自動的に引き上げ、どこもクリアしなければまったく枝刈りしない。 ゲートはある設定では min_resource = 2 に、より難しい設定では 3 になった。フォールバックはフルフィデリティ探索へと優雅に劣化する。正しさにはいくらかの高速化のコストがかかる——それを支払え。
  5. 安価軸は、安いかどうかではなく、バイアスがかかっているかどうかで選べ。 より短い履歴はバイアスがかかっている——レジームに適合したパラメータを選んでしまい、どんなサンプルサイズもそれを直せない。カレンダー全体にまたがる(連続ではなくインターリーブされた)より少ないフォールドを使うか、全期間にわたるより粗い解像度を使え。そして安価軸は、実際にコストが存在する場所に費やせ。

ドリルダウンはバックテストにおける最高の高速化手法の一つであり、同時に、自分をより速く欺く方法へと最も容易に転じてしまうものの一つでもある。その両者を分けるのは、探索が始まる前に測定できるたった一つの数値だ。もしあなたのプロキシが真実と同じように順位付けすることを証明できないなら、それはプロキシではない——もっともらしいコストプロファイルを持つ乱数生成器にすぎない。

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

市場の先を行く

ニュースレターを購読して、独占的なAI取引の洞察、市場分析、プラットフォームの更新情報を受け取りましょう。

プライバシーを尊重します。いつでも配信停止可能です。