ケリー基準で最適ポジションサイズを計算する方法

基礎知識・戦略

「何株買えばいいか?」「資金の何割をこのトレードに使えばいいか?」——ポジションサイズの決め方は、勝てる戦略を持っていても資金を溶かす大きな要因になりえます。ケリー基準は数学的に最適なポジションサイズを導き出す理論です。

ケリー基準とは?

1956年にベル研究所のジョン・ケリーが情報理論として発表した公式で、長期的な資産成長を最大化するためのベット(投資)サイズを計算します。

ケリー比率 f* = (bp – q) / b

  • b = 勝ち負けの損益比(平均利益 / 平均損失)
  • p = 勝率
  • q = 敗率(1 – p)

シンプルなケリー基準の計算

def kelly_criterion(win_rate, avg_win, avg_loss):
    """
    ケリー基準でポジションサイズを計算する
    
    Args:
        win_rate: 勝率(例: 0.55 = 55%)
        avg_win: 平均利益率(例: 0.03 = 3%)
        avg_loss: 平均損失率(例: 0.02 = 2%)
    
    Returns:
        float: 最適なポジションサイズ(資金の比率)
    """
    b = avg_win / avg_loss  # 損益比
    p = win_rate
    q = 1 - p
    
    kelly = (b * p - q) / b
    return kelly

# 例:勝率55%、平均利益3%、平均損失2%
f = kelly_criterion(0.55, 0.03, 0.02)
print(f"ケリー比率: {f:.1%}")
print(f"100万円の場合: {f * 1_000_000:,.0f}円を投資")

Pythonで取引履歴からケリー比率を自動計算

import yfinance as yf
import pandas as pd
import numpy as np

def calculate_kelly_from_strategy(returns, threshold=0):
    """
    実際のトレード履歴からケリー比率を計算する
    
    Args:
        returns: トレードごとのリターンSeries
        threshold: 勝ち負けの閾値(デフォルト0)
    """
    wins = returns[returns > threshold]
    losses = returns[returns <= threshold]
    
    if len(wins) == 0 or len(losses) == 0:
        return None
    
    win_rate = len(wins) / len(returns)
    avg_win = wins.mean()
    avg_loss = abs(losses.mean())
    
    b = avg_win / avg_loss  # 損益比
    p = win_rate
    q = 1 - p
    kelly = (b * p - q) / b
    
    print(f"勝率: {win_rate:.1%}")
    print(f"敗率: {q:.1%}")
    print(f"平均利益: {avg_win:.2%}")
    print(f"平均損失: {avg_loss:.2%}")
    print(f"損益比: {b:.2f}")
    print(f"ケリー比率: {kelly:.1%}")
    
    return kelly, win_rate, b

# 移動平均クロス戦略のケリー比率を計算
df = yf.download("7203.T", period="5y", progress=False)
df['MA25'] = df['Close'].rolling(25).mean()
df['MA75'] = df['Close'].rolling(75).mean()
df['Signal'] = np.where(df['MA25'] > df['MA75'], 1, 0).shift(1)
df['Trade_Return'] = df['Close'].pct_change() * df['Signal']
df = df.dropna()

# シグナルが変わった日(実際のトレード)のみ抽出
trade_days = df[df['Signal'].diff().ne(0) | (df['Signal'] == 1)]
kelly, win_rate, profit_ratio = calculate_kelly_from_strategy(trade_days['Trade_Return'])

ハーフケリー:実践での推奨

理論上の最適値であるフルケリーは非常に変動が大きく、精神的・資金的に耐えられないことが多いです。実務ではハーフケリー(ケリー比率の半分)が推奨されています。

def practical_kelly(win_rate, avg_win, avg_loss, 
                    kelly_fraction=0.5, max_position=0.25):
    """
    実践的なケリー基準(上限あり)
    
    Args:
        kelly_fraction: ケリー比率の適用割合(デフォルト0.5 = ハーフケリー)
        max_position: ポジションサイズの上限(デフォルト25%)
    
    Returns:
        推奨ポジションサイズ
    """
    full_kelly = kelly_criterion(win_rate, avg_win, avg_loss)
    
    if full_kelly <= 0:
        return 0, "期待値がマイナス:投資不推奨"
    
    half_kelly = full_kelly * kelly_fraction
    capped_kelly = min(half_kelly, max_position)
    
    return capped_kelly, f"推奨: {capped_kelly:.1%}(上限{max_position:.0%}、ハーフケリー)"

# 使用例
position, message = practical_kelly(
    win_rate=0.55,
    avg_win=0.03,
    avg_loss=0.02
)
print(f"フルケリー: {kelly_criterion(0.55, 0.03, 0.02):.1%}")
print(f"{message}")

ポジションサイズと資産成長のシミュレーション

import matplotlib.pyplot as plt

def simulate_growth(win_rate, avg_win, avg_loss, 
                    n_trades=200, n_simulations=1000,
                    position_sizes=None):
    """
    異なるポジションサイズによる資産成長をシミュレーション
    """
    if position_sizes is None:
        full_kelly = kelly_criterion(win_rate, avg_win, avg_loss)
        position_sizes = {
            'ハーフケリー': full_kelly * 0.5,
            'フルケリー': full_kelly,
            '1.5倍ケリー(過大)': full_kelly * 1.5,
            '固定5%': 0.05
        }
    
    fig, ax = plt.subplots(figsize=(12, 7))
    
    for label, f in position_sizes.items():
        final_wealths = []
        for _ in range(n_simulations):
            wealth = 1.0
            for _ in range(n_trades):
                if np.random.random() < win_rate:
                    wealth *= (1 + f * avg_win / avg_loss * avg_loss)
                else:
                    wealth *= (1 - f * avg_loss)
            final_wealths.append(wealth)
        
        median_wealth = np.median(final_wealths)
        ax.hist(np.log(final_wealths), bins=50, alpha=0.6, 
                label=f'{label} (中央値: {median_wealth:.1f}倍)')
    
    ax.set_xlabel("log(最終資産)")
    ax.set_ylabel("頻度")
    ax.set_title(f"200トレード後の資産分布(勝率{win_rate:.0%})")
    ax.legend()
    plt.tight_layout()
    plt.show()

simulate_growth(0.55, 0.03, 0.02)

ケリー基準の注意点

1. 勝率・損益比の推定誤差

ケリー基準は正確な勝率と損益比が前提です。実際はこれらは変動するため、保守的なハーフケリーが安全です。

2. 長期収束が前提

ケリー基準は無限回の取引で最適ですが、短期では大きなドローダウンが発生する可能性があります。

3. 相関リスク

複数ポジションを保有する際は、相関を考慮したマルチアセット版ケリーが必要になります。

まとめ:実践的なポジションサイズ戦略

方法 特徴 リスク
フルケリー 長期資産成長を最大化 ドローダウンが大きい
ハーフケリー(推奨) バランスが良い フルより成長は遅いが安全
固定比率(例:2%) シンプルで安定 最適ではないが初心者に向く
固定ロット 最もシンプル 資金規模に応じた調整不可

ケリー基準は強力なツールですが、ハーフケリー+上限設定で使うのが実践的です。まずは固定2%ルールから始め、実績が積まれたらケリー基準に移行することをオススメします。

タイトルとURLをコピーしました