Yyatmita

もう一つの数字——DSR を入れたら『総当たりすればいい』が否定された話

PBO の翌日に Deflated Sharpe Ratio を実装した。割引後のエッジを測ったら最良戦略は運の天井に届いておらず、しかも『PBO と一致した』は偶然だった。そして総当たりは自分でハードルを上げる行為だと分かった

自分のエージェント基盤を組む#claude-code#autoresearch#backtest#interview

前回、autoresearch に PBO を入れて GBPJPY で 0.59 (STRONG WARN) が出た話を書いた。記事の最後で開発者は「次は別の軸で PBO を測り直す」と言っていた。

その日のうちに、話はもう一歩進んだ。PBO の隣に DSR (Deflated Sharpe Ratio) を置いてみたら、前回の結論そのものに疑問符が付いたのだ。しかも「PBO と DSR が綺麗に一致した」という最初の興奮は、よく見ると偶然だった。

引き続き、開発担当の Claude Code に yatmita 記者が聞いた。


1. PBO の隣に、なぜもう一つ指標を置くのか

記者: PBO を入れたばかりですよね。なぜ別の指標を?

開発者: PBO と DSR は、似ているようで測っているものが違うんです。PBO は「この探索プロセスは過学習しているか?」を Yes/No 寄りに言う。DSR は「何回試したかを割り引いた後、まだエッジが残っているか?」を 1 戦略について言う。

記者: 割り引く?

開発者: ここが今日の肝です。エッジがゼロの戦略でも、ランダムなデータに何個も当てれば、その中の「一番良かったやつ」の Sharpe は必ずプラスに出る。しかも試す数が多いほど、まぐれの最高記録は高くなる

記者: 1 個試して Sharpe 1.5 と、1000 個試して一番良いのが 1.5 は、価値が違う。

開発者: その通りです。なのに普通のバックテストは両方「1.5」と表示してしまう。DSR は「運だけで届く Sharpe の天井」を計算して、観測値からそれを差し引く。論文は Bailey & López de Prado (2014) "The Deflated Sharpe Ratio"。PBO と同じ著者です。

2. 「運の天井」はどう決まるか

記者: 運の天井——SR0 と呼ぶことにします——は何で決まるんですか?

開発者: 2 つです。試行回数 N と、試した戦略間の Sharpe のばらつき σ。式はこう:

SR0 = σ · [ (1-γ)·Φ⁻¹(1 - 1/N) + γ·Φ⁻¹(1 - 1/(N·e)) ]

γ はオイラー・マスケローニ定数、Φ⁻¹ は標準正規の逆 CDF。ざっくり言うと、N が増えると √(2 ln N) くらいで天井が上がっていく。

記者: で、DSR は?

開発者: その天井をベンチマークにした確率です。DSR = PSR(sr_star = SR0)。「真の Sharpe が運の天井を超えている確率」を、リターンの歪度・尖度・期間長まで込みで出す。0.5 を割ったら、運の期待値より下ということ。

3. 実装の検証——テストは人間が握る

記者: 実装は?

開発者: ralph-loop に任せました。ただし PBO の時に学んだ教訓を 1 つ守った。完成基準のテストは人間(私側)が先に書いて、ループには触らせない

記者: なぜ?

開発者: ループに実装とテストの両方を書かせると、自分で甘いテストを書いて 1 イテで「合格」して終わる。だから DSR の数式を独立に計算したリファレンス値で固定したゴールデンテストを先に置いて、ループには dsr_analysis.py だけを書かせた。

記者: 検算できる値というのは?

開発者: 例えば「観測 Sharpe = 運の天井のとき DSR は厳密に 0.5」「ガウス収益で sr=0.1, T=101 のとき PSR は 0.8407…」といった、紙で確かめられる値です。ループはそれを 12 個全部通した。テストファイルは untracked のまま——つまりループは一度も触れなかった。誤魔化す経路が物理的に無い状態で通したので、数式は信用できる。

4. GBPJPY に当てた——最良戦略は天井に届いていない

記者: で、自分のデータに当てた結果は?

開発者: これです。

DSR  = 0.4215
SR_hat (最良戦略)  = 0.0020   per-bar
SR0   (運の天井)   = 0.0027   per-bar
σ_SR = 0.0011 / N = 74 / T = 68,626

記者: SR_hat が SR0 より小さい。

開発者: そこが全てです。グリッドから選んだ最良戦略の Sharpe が、74 回試せば運だけで届く天井すら超えていない。DSR=0.42 は「割引後に真のエッジが残っている確率は 42%」、つまり break-even を割っている。

記者: 前回の PBO=0.59 と符合しますね。1 - 0.59 = 0.41、ほぼ DSR と同じ。

開発者: ……そう、最初はそこで興奮したんです。「独立な 2 つの指標が一致した、裏が取れた」と。

記者: 違ったんですか?

5. 「一致した」は嘘だった——出来過ぎを疑う

開発者: 出来過ぎでした。0.587 + 0.421 = 1.008。桁まで揃った相補性です。でも PBO + DSR = 1 という定理は存在しない。両者は別物を測っている。揃ったのは偶然と疑うべきだった。

記者: どう確かめたんですか?

開発者: DSR の N だけを振ってみた。もし 0.42 が本質的な値なら N を変えても動かないはず。

     N        SR0        DSR
     2     0.00057     0.6458
    16     0.00198     0.5020   ← グリッド16戦略だけを試行とみなすと break-even
    74     0.00267     0.4309   ← 今回の値(1−PBO とたまたま近い)
   500     0.00336     0.3611
  2000     0.00379     0.3194

記者: 0.65 から 0.32 まで動く。

開発者: DSR は定数じゃなくノブだった。0.42 が 1 - PBO に近かったのは、N=74 を選んだから偶然そこに刺さっただけ。N=16 を選んでいたら 0.50 で、PBO とは何も一致しない。だから「2 つの針が一致」は撤回しました。

記者: では信用できる結論は?

開発者: 表を縦に見ると、N≥16 のどこを取っても DSR≤0.5。これは N の選び方に依存しない。「過学習率 58%」みたいな精密な数字じゃなく、「最良戦略はせいぜい break-even で、正直に試行を数えるほど確実に沈む」という符号だけが頑健な事実です。

6. 「PBO が速いなら総当たりすればいい」——最大の落とし穴

記者: 素朴な疑問なんですが。PBO も DSR もこんなに速く出るなら、戦略を総当たりで大量に試して、良いやつを拾えばいいのでは?

開発者: それが今日一番大事なところで——逆です。総当たりはハードルを自分で上げる行為なんです。

記者: ハードル?

開発者: さっきの表をもう一度見てください。N が増えるほど SR0(運の天井)が上がる。総当たりで 10 万個試すというのは N を 10 万にすること。すると天井は √(2 ln N) で際限なく上がる。総当たりで勝てる戦略が見つかった気がするのは、天井が上がったことに気づいていないだけ

記者: 探索を増やしても、本物のエッジは増えない。

開発者: エッジは市場の構造にあるかないかで、探索では創れない。総当たりで増えるのは「運の最大値」だけで、その期待値こそ SR0。だから探索を増やすほど DSR は下がる。

記者: PBO の低いやつを拾えばいいのでは?

開発者: それをやると過学習が一段深くなる。PBO/DSR は「たくさん試して best を選ぶと運が混入する」を検出する道具です。それを使って best を選んだら、今度は PBO/DSR という指標の上で選択バイアスが発生する。診断器をセレクタに転用した瞬間、診断器が測っていたバイアスがメタレベルで復活する。煙感知器を「火を多く焚いていい合図」に使うようなものです。

記者: 速さも関係ない?

開発者: 関係ない。速く出るのは「あなたの探索は過学習」という判定であって、勝てる戦略じゃない。それに 16 戦略のバックテスト構築でも数分かかる。総当たり 1 万戦略なら全然速くない。

7. 前回の結論を、少し訂正する

記者: 前回の記事、最後はこう締めていました。「次は tp_atr_mult を弄るのをやめて、エントリートリガーのロジック自体を変えた集合で測り直す」と。

開発者: そこを今日、訂正したいんです。軸を変える・増やすことは、N を増やすことでもある。仮説を足すほど SR0 が上がってハードルが高くなる。「別の軸を探せば勝てる戦略が見つかる」は、加速して崖に向かう方向だった。

記者: では何が正しい?

開発者: 効くのは逆で、試行数を減らすこと。それが SR0 を下げる唯一の手です。具体的には 3 つ:

  1. 経済的根拠のある少数の仮説に絞る。 仮説が少ない=N が小さい=天井が低い=生き残りが本物の確率が上がる。
  2. N に discard を全部数える。 keep した 75 件だけじゃない。捨てたパラメータも全部「試行」。正直に数えると N はもっと大きい。
  3. 探索が一度も見ていない最終ホールドアウトを物理的に封印する。 keep/discard の判定に OOS を 75 回使い回した時点で、その OOS はもう学習データ。本番だけが唯一の真の初見データになっている。だから本番でだけ落ちる。

記者: 「OOS が通った」を信じる前に押すボタンが PBO だったとして、DSR は?

開発者: DSR は「そのエッジ、何回挑戦した末のものか正直に申告したら、まだ残ってる?」と聞いてくる。今回 GBPJPY は「残っていない」と答えた。

8. 教訓——向かう先は本棚じゃなくデータ

記者: 今日のまとめは?

開発者: 2 つあります。1 つは技術的な話で、PBO と DSR は補完的だが、数字の一致に意味を読むな。一致は偶然で、信用できるのは符号と方向だけ。指標を 2 つ持つことより、出た数字を疑ってノブを振ってみることの方が効く。

記者: もう 1 つは?

開発者: メタな話です。「過学習とは何か」「クロスバリデーションとは」みたいな一般論は、教科書にも講義動画にも載っている。でも「あなたの戦略が過学習か」は、データにしか答えがない。今日やったのは、本を読むことじゃなく、自分のデータに 2 つの数字を当てて、その数字を疑うことだった。

記者: 向かう先が本棚じゃなくデータだった。

開発者: はい。論文を読んだ翌日に PBO を実装し、その翌日に DSR を足して、当日中に「総当たりは無駄」という結論まで来た。学ぶべきことは動画の中じゃなく、自分の results.tsv の中にあった。次にやるのは新しい軸探しじゃなく、ホールドアウトの封印です。

記者: 探索を増やすのをやめる、という方針が立った。

開発者: 前回は「次の軸を試す」で終わった。今日は「試行を減らす」に変わった。1 日で結論が引っくり返るのは、悪いことじゃないと思います。


前回の記事: 過学習を 1 つの数字にする——autoresearch に PBO/CSCV を入れた話

この記事は Claude Code(開発担当)への実際のインタビューをもとに構成しています。

本記事はバックテスト手法の技術的検証記録であり、特定の金融商品の売買を推奨するものではありません。投資判断はご自身の責任でお願いします。