PR DMM FX 新規口座開設 + 取引で 最大30万円キャッシュバック 詳細 ▶

Optuna で EA パラメータ最適化 — 過剰最適化を避ける実装テクニック

[ 広告 / PR ]
🔰 この記事のポイント (初心者向け)

はじめての方も読めるよう、専門用語はカンタンな言葉に言い換えながら解説します。「なんとなく聞いたことある」レベルの知識で大丈夫です。

📖 この記事で出てくる用語
  • EA = Expert Advisor。MT4/MT5上で動く自動売買プログラム
  • Optuna = パラメータ最適化を自動化するPythonライブラリ
Optuna で EA パラメータ最適化 — 過剰最適化を避ける実装テクニック
イメージ画像
⚙️

パラメータ最適化 実装

📢 広告 (PR) を含む場合があります

Optuna で EA パラメータ最適化 — 過剰最適化を避ける実装テクニック

最終更新: 2026-05-05

著者
Ami Suzuki
データサイエンティスト・Kaggle Master
Web系企業でデータ分析チームリード。Optunaコミットの読み込み歴3年。

Optuna は強力ですが、使い方を誤ると過剰最適化を加速します。実際の運用で得た「やってよかった3つの実装」と「やめた方がいい1つの落とし穴」を整理します。

過剰最適化が起きるメカニズム

Optuna は目的関数の値を最大化するパラメータを探索します。バックテストPFを目的関数にすると、Optuna は「過去データに最も合うパラメータ」を返してきます。これは未来のデータでは多くの場合、性能が劣化します。

やってよかった実装 1: Walk-Forward を目的関数の中に入れる

単一期間の PF ではなく、3 つに分けた期間それぞれの PF の最小値を目的関数にします:

def objective(trial):
    p = {
        "atr_sl": trial.suggest_float("atr_sl", 1.5, 4.0),
        "atr_tp": trial.suggest_float("atr_tp", 1.5, 5.0),
        "rsi_period": trial.suggest_int("rsi_period", 7, 21),
    }
    pfs = []
    for start, end in [(2023, 2024), (2024, 2025), (2025, 2026)]:
        df = load_data(start, end)
        pf = backtest(df, p)
        pfs.append(pf)
    return min(pfs)   # 最弱期間の値を返す

この変更だけで、本番投入後の劣化幅が体感で約半分になりました。

やってよかった実装 2: パラメータ感度の罰則項

探索結果のパラメータが「微妙に動かすと結果が崩れる」尖ったピークだと、本番では再現しません。目的関数に罰則項を入れます:

def objective(trial):
    p = sample_params(trial)
    pf = backtest(p)
    # ±5% のパラメータでもPFが大きく下がらないか
    pf_minus = backtest({k: v*0.95 for k,v in p.items()})
    pf_plus  = backtest({k: v*1.05 for k,v in p.items()})
    sensitivity = max(pf - pf_minus, pf - pf_plus)
    return pf - sensitivity * 0.5

やってよかった実装 3: パラメータ数の上限

過剰最適化のリスクは概ね パラメータ数 × 試行回数 に比例します。パラメータは7個以下を上限とし、それ以上必要なら戦略を分けます。経験的にここを超えると本番劣化が顕著です。

やめた方がいい1つの落とし穴: study の使い回し

「前回の study を続きから再開する」は便利ですが、データが変わったときに過去の試行が偏った最適化を強制してきます。データが更新されたら新しい study を切るのが安全です。

実運用での Optuna 設定例

import optuna
study = optuna.create_study(
    direction="maximize",
    sampler=optuna.samplers.TPESampler(seed=42),
    pruner=optuna.pruners.MedianPruner(n_startup_trials=20),
)
study.optimize(objective, n_trials=200, n_jobs=4, show_progress_bar=True)
print("Best:", study.best_params)
print("Value:", study.best_value)

結果の見方 (大事)

Optuna が出してきた「Best」をそのまま使う前に:

  • パラメータ重要度 (optuna.importance.get_param_importances) を可視化、上位2-3個に絞る
  • plot_contour で「平らで広い高地」を狙う (尖った頂上は避ける)
  • OOS でテスト → 劣化が10%超なら採用しない

まとめ

Optuna は「過去に最も合う数字を返す機械」であり、それは本番では不利に働きます。Walk-Forward + 感度罰則 + パラメータ上限 + 新規study の4点セットで、過剰最適化を構造的に減らせます。万能ではないですが、再現性が大きく上がります。

参考にした情報源

免責: 本記事は情報提供のみを目的としており、投資勧誘・投資助言ではありません。当サイト管理人は金融商品取引業の登録を行っておらず、個別具体的な投資判断についての助言は行えません。FX/暗号資産は元本毀損のリスクがあります。最終判断はご自身の責任でお願いします。
PR · DMM FX 公式

国内口座数 No.1 — DMM FX

業界最狭水準スプレッド + スマホアプリ高評価 + 最短当日取引開始
新規口座開設で 最大 300,000円 キャッシュバック中

▶ DMM FX 公式サイトで詳細

※本サイトはアフィリエイトプログラムにより収益を得ています。投資はご自身の判断・責任で。

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


投稿をさらに読み込む