自動売買のパラメータを改善したい。しかし「新パラメータが本番で悪化したらどうするか」が常につきまとう問題だ。バックテストで良い結果が出ても、実運用で同じ結果になる保証はない。
この問題を解決するために、2つの仕組みを構築した。
- A/Bテストフレームワーク(NEW-16): 新旧パラメータを並走させ、実データで比較する
- パラメータ陳腐化自動検知(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点だ。
- A/Bテスト基盤: Production/Pre/Devの3ワークスペースで新旧パラメータを安全に並走比較
- 陳腐化自動検知: 勝率・PF・頻度・連敗の4指標を監視し、劣化を自動検出
- 人間判断の保持: 自動検知・自動提案はするが、最終Go/No-Goは人間が判断。完全自動化の誘惑に負けない