Skip to content
Go back

月次目標逆算型ロット最適化:scipyの2段階最適化で全ペアのロットを自動配分

Edit page

「月利37,000円を達成するには、9通貨ペアのロットサイズをどう配分すべきか?」——この問いに対して、勝率・RR比・トレード頻度が異なる9ペアの最適ロット配分を、scipyの2段階最適化で自動計算するシステムを構築した。39テスト全PASS。

単純に「全ペア均等配分」ではなく、各ペアの期待リターンとリスクを考慮した配分を行うことで、同じリスク量でも月利目標の達成確率を最大化する。


なぜ均等配分ではダメなのか

9通貨ペアの特性の違い

FXエンジンで運用中の9ペアは、勝率・RR比・トレード頻度がそれぞれ異なる。

EUR_JPY: 勝率 65%, RR比 1.2, 月平均 8トレード → 高頻度・安定型
GBP_JPY: 勝率 55%, RR比 1.8, 月平均 5トレード → 中頻度・高RR型
AUD_JPY: 勝率 60%, RR比 1.0, 月平均 6トレード → 中頻度・安定型
CHF_JPY: 勝率 45%, RR比 0.8, 月平均 4トレード → 低頻度・低期待値

CHF_JPYのようにバックテストで期待値がマイナスのペアに、EUR_JPYと同じロットを割り当てるのは非合理的だ。

均等配分の問題

均等配分: 全ペア 10,000通貨

→ EUR_JPY(高期待値): 10,000通貨で利益を出す
→ CHF_JPY(低期待値): 10,000通貨で損失を出す
→ 結果: 高期待値ペアの利益を低期待値ペアが食い潰す

最適配分では、期待値の高いペアにロットを集中させ、低いペアは縮小(または除外)する。


2段階最適化の設計

なぜ2段階か

単一の最適化問題として定式化すると、変数が多すぎて解が不安定になる(9ペア × ロットサイズ = 9変数の非線形最適化)。

そこで問題を2段階に分解した。

Stage 1: 各ペアの「最適リスク配分比率」を決定
  → 入力: 各ペアの勝率・RR比・相関行列
  → 出力: リスク配分比率(例: EUR_JPY 25%, GBP_JPY 20%, ...)

Stage 2: 月利目標から「必要なロットサイズ」を逆算
  → 入力: リスク配分比率 + 月利目標 + 口座残高
  → 出力: 各ペアの具体的なロットサイズ

Stage 1: リスク配分比率の最適化

各ペアに割り当てるリスク比率を、シャープ比の最大化を目的関数として最適化する。

from scipy.optimize import minimize

def neg_sharpe_ratio(weights, expected_returns, cov_matrix):
    """ポートフォリオのシャープ比を最大化(負の値を最小化)"""
    portfolio_return = weights @ expected_returns
    portfolio_vol = (weights @ cov_matrix @ weights) ** 0.5
    if portfolio_vol == 0:
        return 0
    return -portfolio_return / portfolio_vol

# 制約条件
constraints = [
    {"type": "eq", "fun": lambda w: w.sum() - 1.0},  # 合計100%
]
bounds = [(0.0, 0.4)] * n_pairs  # 各ペア最大40%まで(集中リスク回避)

result = minimize(
    neg_sharpe_ratio,
    x0=np.ones(n_pairs) / n_pairs,  # 初期値: 均等配分
    args=(expected_returns, cov_matrix),
    method="SLSQP",
    bounds=bounds,
    constraints=constraints,
)
optimal_weights = result.x

SLSQP(Sequential Least Squares Programming)は、等式/不等式制約付きの非線形最適化に適したアルゴリズムだ。

上限制約(最大40%)の意味

1ペアに最大40%までという制約を設けることで、「EUR_JPYに80%集中」のような極端な配分を防ぐ。集中投資は期待リターンが高いが、そのペアが不調になったときのダメージも大きい。

Stage 2: ロットサイズの逆算

Stage 1で得た比率を、月利目標と口座残高から具体的なロットサイズに変換する。

def calculate_lot_sizes(
    weights: np.ndarray,         # Stage 1の最適配分比率
    monthly_target: float,       # 月利目標(円)
    equity: float,               # 口座残高(円)
    expected_monthly_pips: dict,  # 各ペアの月間期待pips
    pip_values: dict,            # 各ペアの1pip価値
) -> dict:
    lot_sizes = {}
    total_risk_budget = equity * 0.02  # 口座の2%をリスク予算

    for i, pair in enumerate(pairs):
        pair_risk = total_risk_budget * weights[i]
        # ロットサイズ = リスク予算 / (SL幅 × pip価値)
        lot = pair_risk / (sl_pips[pair] * pip_values[pair])
        # GMO Coin制約: 1,000通貨単位
        lot_sizes[pair] = max(1000, round(lot / 1000) * 1000)

    return lot_sizes

相関行列の活用

なぜ相関を考慮するか

EUR_JPYとGBP_JPYは相関が高い(ともにクロス円で、米ドルの動きに影響を受ける)。この2ペアに大きなロットを配分すると、実質的に「同じ方向に2倍のポジションを持っている」のと変わらない。

相関行列を最適化に組み込むことで、相関の低いペアに分散投資する配分が自然に得られる。

# 相関行列の例(バックテストの日次リターンから計算)
correlation_matrix = {
    "EUR_JPY-GBP_JPY": 0.78,  # 高相関
    "EUR_JPY-AUD_JPY": 0.55,  # 中相関
    "EUR_JPY-EUR_USD": 0.42,  # 低相関
}

高相関のペア同士は「片方にロットを集中し、もう片方を縮小する」方が、ポートフォリオ全体のリスク調整後リターンが改善する。


月利目標の逆算

具体例

月利目標37,000円、口座残高545,888円の場合:

月利目標率: 37,000 / 545,888 = 6.78%

Stage 1の最適配分:
  EUR_JPY: 28%
  GBP_JPY: 22%
  AUD_JPY: 15%
  CAD_JPY: 12%
  NZD_JPY: 8%
  EUR_USD: 8%
  GBP_USD: 5%
  AUD_USD: 2%
  CHF_JPY: 0%(期待値マイナスのため除外)

Stage 2の逆算結果:
  EUR_JPY: 14,000通貨
  GBP_JPY: 11,000通貨
  AUD_JPY:  8,000通貨
  ...
  CHF_JPY: 0通貨(配分なし)

CHF_JPYはバックテストで期待値マイナスのため、最適化の結果として配分0%になる。これは数学的に正しい判断だ。


データ蓄積の重要性

このシステムの精度は「入力データの質」に依存する。バックテストの勝率・RR比は過去のデータに基づくため、データ蓄積期間が短いと推定誤差が大きい。

最低2ヶ月のDry-Runデータ蓄積後に最適化を実行するルールを設けた。2ヶ月は統計的に有意な結論を出すには短いが、「全くデータなしで均等配分するよりはマシ」という実用的な判断だ。


学んだこと

1. 均等配分は「分からないときの最善策」であり「最適」ではない

各ペアの特性が分かっているなら、それを反映した配分にすべきだ。均等配分は「情報がないとき」のベースラインとしては正しいが、2ヶ月以上の実績データがあるなら最適化の余地がある。

2. 2段階分解で最適化が安定する

9変数の一括最適化は局所解に陥りやすい。「比率の決定」と「ロットへの変換」を分離することで、各ステージの問題がシンプルになり、解の安定性が向上した。

3. 上限制約は数学よりも実務のための安全装置

数学的には「EUR_JPYに100%集中」が最適解になりうるが、実務的にはそのペアが不調になったときに壊滅的なダメージを受ける。最大40%の上限制約は、過学習(バックテストデータへの過剰適合)に対する安全装置だ。


まとめ

月次目標逆算型ロット最適化の設計で重要なのは以下の3点だ。

  1. 2段階最適化: Stage 1でリスク配分比率を決定、Stage 2で月利目標からロットを逆算。問題を分解して安定化
  2. 相関行列の考慮: 高相関ペアへの重複投資を回避し、分散効果を最大化
  3. 上限制約(最大40%): 1ペアへの過剰集中を防ぐ安全装置。過学習対策

「月利X万円を達成するために、各ペアに何ロット配分すべきか」という問いに対して、感覚ではなく数学的に回答するシステムだ。


Edit page
Share this post on:

Previous Post
市場レジーム自動識別:ADXとVIXのマトリクスでエントリー閾値を動的制御する
Next Post
Multi-Signal Confluence:42パターンのシグナル合流で精度を上げる