あらゆる主張に誤差範囲を
バックテストが「戦略は1日0.05%稼いだ」と言うとします。実力か運か。仮説検定はp値で答えます。真の平均がゼロなら、標本がこれほど良く見える頻度はどれくらいか、ということです。stats.ttest_1samp(r, 0.0) は1つの平均を検定し、stats.ttest_ind(a, b, equal_var=False) は2つの資産を、同じ変動とは仮定せずに比べます(ウェルチの検定、安全な既定の選択)。stats.jarque_bera(r) は歪度と尖度からリターンが正規かを調べます。小さなp値は検定した考えに反する証拠であって、好きな考えの証明ではありません。また検定は前提次第で、t検定は薄い裾を仮定しますが、日次リターンの裾は薄くありません。
数式が怪しいときは、再標本化します。ブートストラップはデータから復元抽出で多数の標本を作り、そのたびに統計量(平均、シャープレシオ、分位点)を計算し直して、結果のばらつきから区間を読み取ります:stats.bootstrap((r,), stat, method='percentile', random_state=np.random.default_rng(seed))。SciPyは再標本をまとめて渡すので、統計量は axis 引数を受け取る必要があり、シードで答えが再現できます。置換検定は2グループのラベルを混ぜ、偶然だけで観測された差と同じ大きさの差がどれだけ出るかを見ます。最後に、62資産を5%水準で検定すれば、運だけで約3つが有意に見えます。stats.false_discovery_control(p) はベンジャミニ–ホッホベルク補正を適用し、どの発見が残るかを示します。
実データが語ること直近2,500営業日で、SPYの平均日次リターンは0.046%、t=2.80、p=0.005 でした。年率換算のシャープレシオは 0.89 で、95%ブートストラップ区間は 0.26 から 1.53 まで、データはそれ以上には絞り込めません。62資産のうち22資産は平均がゼロでないという5%検定に通りますが、ベンジャミニ–ホッホベルク補正を生き残るのは12資産だけです。ジャルク・ベラ検定はSPYの正規性をp値0で棄却します。
- 既定はウェルチ:2つの資産が同じ変動をもつと仮定しない。
- 迷ったら再標本化:ブートストラップには
axis引数付きの統計量とシードが必要。 - 検定の数を数える:5%で62回検定すれば偽の発見が約3つ出る。補正すること。
ラボ:採点される内容
- 平均はゼロか8点
- 2つの資産、2つの変動8点
- 正規性の検定6点
- ブートストラップ区間18点
- 年率シャープレシオ8点
- 誤差範囲付きシャープレシオ10点
- 置換検定14点
- 偽発見を数える12点
- 研究全体16点