Skip to content
Go back

新旧パラメータ並走A/Bテストと陳腐化自動検知:本番を壊さずに改善を続ける仕組み

Edit page

自動売買のパラメータを改善したい。しかし「新パラメータが本番で悪化したらどうするか」が常につきまとう問題だ。バックテストで良い結果が出ても、実運用で同じ結果になる保証はない。

この問題を解決するために、2つの仕組みを構築した。

  1. A/Bテストフレームワーク(NEW-16): 新旧パラメータを並走させ、実データで比較する
  2. パラメータ陳腐化自動検知(NEW-18): 運用中のパラメータの劣化を自動検出し、再最適化のトリガーを引く

A/Bテストフレームワーク(NEW-16)

「本番でいきなり切り替え」の危険性

パラメータ変更のよくある失敗パターンはこうだ。

1. バックテストで新パラメータが20%改善
2. 「よし、本番に適用しよう」
3. 本番で3日間連続損失
4. パニックで元に戻す
5. 「新パラメータは使えなかった」と結論

この判断は正しいか? 3日間の連続損失は、勝率55%の戦略でも統計的に起こり得る(発生確率 = 0.45³ = 9.1%)。にもかかわらず、「体感」で判断してしまう。

3ワークスペースモデル

A/Bテストの基盤として、3つの実行環境(ワークスペース)を構築した。

Production(本番):
  → 実際に発注する環境
  → 現行パラメータで運用

Pre(プリプロダクション):
  → 本番と同じ市場データを受け取るが、発注はしない
  → 新パラメータでDry-Run(疑似取引)を実行

Dev(開発):
  → バックテスト・単体テスト用
  → 実験的なパラメータで自由に検証

並走テストの流れ

Week 1-2: Dev環境でバックテスト → 新パラメータ候補を特定
Week 3-6: Pre環境でDry-Run → 本番と同じデータで新旧を並走比較
Week 7:   統計的評価 → Go/No-Go判断
Week 8:   GOなら本番に適用、NO-GOならパラメータを再調整

Pre環境は本番と完全に同じ市場データ(価格・出来高・経済指標)を受け取る。違いは「実際に注文を出すか否か」だけだ。これにより、新パラメータの「本番での挙動」を安全に検証できる。

評価基準

並走テストの評価は、感覚ではなく定量基準で行う。

判定基準(すべて満たすこと):
  1. 新パラメータの月間PnL ≥ 旧パラメータの月間PnL × 0.9
     → 10%以上の悪化がないこと
  2. 新パラメータの最大DD ≤ 旧パラメータの最大DD × 1.2
     → ドローダウンが20%以上悪化しないこと
  3. サンプル数 ≥ 30トレード
     → Wilson信頼区間で統計的に有意な比較が可能
  4. 新パラメータの勝率Wilson下限 > 40%
     → 最悪ケースでも期待値プラス

パラメータ陳腐化自動検知(NEW-18)

パラメータは「腐る」

最適化したパラメータは永遠に有効ではない。市場の構造変化(ボラティリティの変化、流動性の変化、参加者の変化)によって、かつて最適だったパラメータが次第に効かなくなる。これを「陳腐化(パラメータ・ディケイ)」と呼ぶ。

陳腐化の兆候

以下の4つの指標を監視し、閾値を超えたら「陳腐化の疑い」としてアラートを出す。

1. 勝率の低下:
   直近30トレードの勝率が、全期間平均から-10%以上乖離

2. PF(Profit Factor)の低下:
   直近30トレードのPFが1.0を下回る(総損失が総利益を上回る)

3. トレード頻度の変化:
   ポアソン検定でp値 < 0.05(期待頻度から統計的に逸脱)

4. 連敗の増加:
   直近の最大連敗数が、全期間の95パーセンタイルを超える

自動検知の実装

def check_parameter_staleness(
    recent_trades: list,       # 直近30トレード
    historical_stats: dict,    # 全期間の統計値
) -> dict:
    recent_win_rate = sum(1 for t in recent_trades if t.pnl > 0) / len(recent_trades)
    win_rate_drift = recent_win_rate - historical_stats["win_rate"]

    recent_pf = (
        sum(t.pnl for t in recent_trades if t.pnl > 0) /
        abs(sum(t.pnl for t in recent_trades if t.pnl < 0))
    )

    alerts = []
    if win_rate_drift < -0.10:
        alerts.append(f"WIN_RATE_DRIFT: {win_rate_drift:.1%}")
    if recent_pf < 1.0:
        alerts.append(f"PF_BELOW_1: {recent_pf:.2f}")

    return {
        "is_stale": len(alerts) > 0,
        "alerts": alerts,
        "recommendation": "RE_OPTIMIZE" if len(alerts) >= 2 else "MONITOR",
    }

アラート発火時のフロー

陳腐化検知

Slack通知(「EUR_JPYのパラメータ陳腐化の疑い:勝率-12%乖離」)

自動でバックテスト再実行(直近6ヶ月データ)

新パラメータ候補を提案

Pre環境でA/Bテスト開始(自動)

人間がGo/No-Go判断

陳腐化の検知から再最適化候補の提案までは自動で行い、最終判断のみ人間が行う。「完全自動」ではなく「自動検知+自動提案+人間判断」の設計だ。


学んだこと

1. 「3日間の連敗」で判断してはいけない

勝率55%でも3連敗は9.1%の確率で起きる。パラメータ変更の評価は30トレード以上のサンプルで、Wilson信頼区間を用いて行うべきだ。

2. パラメータには「賞味期限」がある

市場環境は変化する。6ヶ月前に最適化したパラメータが今も最適とは限らない。定期的な陳腐化チェックが、「気づいたら損失が膨らんでいた」を防ぐ。

3. Pre環境は「保険」である

Pre環境の運用コスト(サーバーリソース・メンテナンス)は、新パラメータが本番で失敗した場合の損失に比べれば微々たるものだ。


まとめ

パラメータ管理で重要なのは以下の3点だ。

  1. A/Bテスト基盤: Production/Pre/Devの3ワークスペースで新旧パラメータを安全に並走比較
  2. 陳腐化自動検知: 勝率・PF・頻度・連敗の4指標を監視し、劣化を自動検出
  3. 人間判断の保持: 自動検知・自動提案はするが、最終Go/No-Goは人間が判断。完全自動化の誘惑に負けない

Edit page
Share this post on:

Previous Post
マルチタイムフレーム整合性ボーナス:H4エントリーにD足トレンド方向の確認を加える
Next Post
外国人投資家フロー連動フィルター:需給環境でエントリーを制御する