Table of Contents
機械学習モデルの出力に対して「どの値ならエントリーするか」を決める閾値(threshold)を、探索する。
単一モデルであれば、手動で少しずつ値を変えながら試すこともできる。しかし、複数モデルを組み合わせたアンサンブル戦略では話が変わる。
閾値の組み合わせ数が爆発するからだ。
例えば、以下のように複数の条件がある場合。
sub_thrmean_thrlow_thr
それぞれを細かく探索しようとすると、総当たり(グリッドサーチ)は現実的ではなくなる。
そこで使うのが 遺伝的アルゴリズム(Genetic Algorithm / GA)
なぜGAなのか
GAの利点は、広い探索空間の中から「良いパラメーター」を効率的に見つけられることにある。
特に、閾値同士の相互作用が強い場合に有効だ。
例えば、
mean_thrを少し緩める- その代わり
sub_thrを厳しくする
といった「組み合わせ最適化」が自然に行われる。
手動チューニングでは見つけづらい領域を探索できるのが強い。
Fitness関数が戦略の方向性を決める
GAでは、何を「良い個体」とするかを決めるために Fitness関数 を設計する。
今回は、単純な総利益ではなく、
- 平均 pips を重視
- トレード数が少なすぎる場合はペナルティ
という方向で設計した。
実際の式は以下。
fitness = ( avg * np.sqrt(trades) * min(1.0, trades / 220))考え方としては、
-
avg→ 1トレードあたりの質を重視 -
sqrt(trades)→ トレード数が多いほど評価するが、過剰に効きすぎないように緩やかに増加 -
min(1.0, trades / 220)→ 220トレード未満を軽くペナルティ
平均利益だけを最適化すると、
数回しかトレードしない超高勝率戦略
が生まれやすい。
例えば、5回だけトレードして全部勝つ設定は、バックテストでは強く見えてもライブでは再現性が低い。
そのため、最低限のサンプル数を要求する目的で、220トレード未満にペナルティを入れた。
最適化は「何を勝者と定義するか」で結果が大きく変わる。
GAそのものより、Fitness設計の方が重要だと思う。
最適化結果
30世代で収束し、以下のパラメーターが選ばれた。
=== GEN 1 ===Best Fitness: 57.52974Trades: 259Pips: 925.85Avg: 3.575
...
=== GEN 30 ===Best Fitness: 60.60548Trades: 243Pips: 944.75Avg: 3.888sub_thr = 0.10562mean_thr = 0.04674low_thr = -0.04310結果として、
| 指標 | 値 |
|---|---|
| Trades | 243 |
| Total Pips | 944.75 |
| Avg Pips / Trade | 3.888 |
| Fitness | 60.61 |
となった。
ただし、オーバーフィットは常に疑う
GAは強力な最適化手法だが、そのぶん 「探索に使った期間」に過剰適合しやすい。
過去データに、綺麗に都合よく合わせたパラメーターを作ってしまう。
バックテストで綺麗な右肩上がりになっても、それだけでは信用できない。
対策
1. 探索期間を長く取る
短期間だけだと、偶然の相場環境に最適化されやすい。
2. 期間分割
データを前半・後半に分ける。
例えば、前半でパラメーター探索を行い、後半で検証する。
探索に使っていない期間でも成績が維持されるかを見る。
3. 複数期間のサンプリング
期間を切り出して複数回評価する。
いわゆる Bootstrap Sampling / Bagging 的な考え方で、特定期間にだけ強いという設定を避ける。
ライブ向けの位置付け
最終的にGAは、ライブ投入前の微調整として使うのが良い。
- Trainでモデル作成
- Validationで戦略確認
- Unknown Forwardで耐性確認
- 最後にGAで閾値微調整
ライブトレードでは、成績は劣化するので、
バックテスト結果の 40%〜120%程度
で考えれば良い。
下振れも上振れもある。
逆に、40%以下などだと、過学習を疑った方が良いだろう。