Conviction Allocator(動的資本配分機構)¶
概要¶
Conviction Allocator は、口座残高と確信度スコアに応じてポジションサイズと分散度を動的に調整する資本配分機構です。
設計思想
小資本時は集中投資で資本成長を優先し、大資本時は分散投資で安定収益を優先する。 各ポジションのサイズは「確信度スコア」に応じて動的に厚みを変える。
コンセプト: Capital Velocity¶
Capital Velocity = 資本の成長速度を制御する
graph LR
A[小資本<br/>$13k-$20k] -->|集中投資<br/>高リスク| B[中資本<br/>$20k-$50k]
B -->|バランス| C[大資本<br/>$50k+]
C -->|分散投資<br/>安定収益| D[複利成長]
style A fill:#ff6b6b
style B fill:#ffd93d
style C fill:#6bcf7f
style D fill:#4ecdc4
2階建て配分アーキテクチャ¶
マクロレベル: 資本段階¶
口座残高に応じて総リスクバジェットと目標分散度を決定
graph TD
A[口座残高] --> B{段階判定}
B -->|≤$20k| C[Seed Stage]
B -->|$20k-$50k| D[Transition Stage]
B -->|≥$50k| E[Harvest Stage]
C --> F[集中投資<br/>目標3-8銘柄<br/>リスク20%]
D --> G[バランス<br/>目標8-15銘柄<br/>リスク15%]
E --> H[分散投資<br/>目標15-25銘柄<br/>リスク12%]
ミクロレベル: 確信度配分¶
各ポジションの確信度スコアに応じてリスクバジェットを再配分
graph LR
A[シグナル候補] --> B[確信度スコア計算]
B --> C[MTF一致度<br/>0-30点]
B --> D[GEXレジーム<br/>0-30点]
B --> E[IV Rank適正<br/>0-20点]
B --> F[流動性<br/>0-10点]
B --> G[モメンタム<br/>0-10点]
C --> H[総合スコア<br/>0-100]
D --> H
E --> H
F --> H
G --> H
H --> I{ソフトマックス<br/>配分}
I --> J[高確信: 1.5x]
I --> K[標準: 1.0x]
I --> L[低確信: 0.7x]
資本段階別パラメータ¶
Seed Stage(種まき期): ≤ $20,000¶
| パラメータ | 値 | 説明 |
|---|---|---|
| 目標ポジション数 | 3-8 | 集中投資 |
| 1トレードリスク | 2.5% | アグレッシブ |
| 総リスクバジェット | 20% | 高リスク許容 |
| 最大単一リスク | 8% | 高集中許容 |
| β(集中度) | 3.0 | 高確信に厚く |
思想: 資本を増やすフェーズ。分散しても1ポジションが小さすぎて非効率。
Transition Stage(遷移期): $20,000 - $50,000¶
| パラメータ | 値 | 説明 |
|---|---|---|
| 目標ポジション数 | 8-15 | バランス |
| 1トレードリスク | 1.5% | 標準 |
| 総リスクバジェット | 15% | 中リスク |
| 最大単一リスク | 5% | 中集中 |
| β(集中度) | 2.0 | バランス配分 |
思想: 成長と安定のバランス。段階的にリスクを縮小。
Harvest Stage(収穫期): ≥ $50,000¶
| パラメータ | 値 | 説明 |
|---|---|---|
| 目標ポジション数 | 15-25 | 分散投資 |
| 1トレードリスク | 0.8% | 保守的 |
| 総リスクバジェット | 12% | 低リスク |
| 最大単一リスク | 3% | 低集中 |
| β(集中度) | 1.5 | 均等分散 |
思想: 資本を守るフェーズ。利益率5%でも$2,500/月。分散でドローダウン抑制。
段階間の連続補間¶
段階が変わっても急激な変化を避けるため、パラメータを滑らかに補間:
g(E) = clip((E - 20000) / 30000, 0, 1)
N_target(E) = N_S1 + (N_S3 - N_S1) * g(E)
r_per_trade(E) = r_S1 - (r_S1 - r_S3) * g(E)
例: $35,000の場合 - g(E) = (35000 - 20000) / 30000 = 0.5 - N_target = 5 + (20 - 5) × 0.5 = 12.5 → 12銘柄 - r_per_trade = 2.5% - (2.5% - 0.8%) × 0.5 = 1.65%
確信度スコア(Conviction Score)¶
計算式¶
\[
S_i = w_\text{MTF} \cdot C^\text{MTF}_i + w_\text{GEX} \cdot C^\text{GEX}_i + w_\text{IV} \cdot C^\text{IV}_i
\]
成分定義¶
| 成分 | 重み | 計算方法 | 範囲 |
|---|---|---|---|
| MTF一致度 | 0.4 | 日足・1時間足・5分足の方向一致 | [0, 1] |
| GEXレジーム適合 | 0.3 | 現在のGEXレジームと戦略の相性 | [0, 1] |
| IV Rank適正 | 0.3 | 戦略に適したIV環境か | [0, 1] |
MTF一致度(C_mtf)の計算例¶
# 例: 日足上昇 + 1時間足上昇 + 5分足上昇 = 完全一致
if daily_trend == hourly_trend == minute_trend == entry_direction:
c_mtf = 1.0
elif daily_trend == entry_direction:
c_mtf = 0.7 # 上位足のみ一致
elif hourly_trend == minute_trend == entry_direction:
c_mtf = 0.6 # 下位足のみ一致
else:
c_mtf = 0.3 # 不一致
GEXレジーム適合(C_gex)の計算例¶
# 例: Put Wall Supportレジームでショート戦略
if regime == GexRegime.PUT_WALL_SUPPORT and strategy == "short":
c_gex = 1.0 # 最適
elif regime == GexRegime.CALL_WALL_RESISTANCE and strategy == "short":
c_gex = 0.8 # やや有利
elif regime == GexRegime.NEAR_ZERO_GAMMA:
c_gex = 0.4 # 中立
else:
c_gex = 0.2 # 不利
IV Rank適正(C_iv)の計算例¶
# 例: プレミアムショート戦略
if iv_rank >= 0.7:
c_iv = 1.0 # 高IVで有利
elif iv_rank >= 0.5:
c_iv = 0.7 # やや有利
elif iv_rank >= 0.3:
c_iv = 0.4 # 中立
else:
c_iv = 0.2 # 不利
ソフトマックス配分¶
確信度が高い銘柄に非線形に厚く配分:
\[
w_i^\text{raw} = \exp(\beta S_i)
\]
\[
w_i = \frac{w_i^\text{raw}}{\sum_j w_j^\text{raw}}
\]
β(集中度パラメータ)の影響¶
| β値 | 特性 | 適用段階 |
|---|---|---|
| 4.0 | 極度に集中 | Seed(小資本) |
| 3.0 | 集中的 | Seed |
| 2.0 | バランス | Transition |
| 1.5 | やや分散 | Harvest |
| 1.0 | 均等分散 | Harvest(大資本) |
例: 3つのシグナル(S=0.8, 0.6, 0.4)の場合
| β | 配分比率 |
|---|---|
| 1.0 | 34% / 33% / 33% (均等) |
| 2.0 | 48% / 32% / 20% (やや集中) |
| 3.0 | 58% / 27% / 15% (集中) |
ポジションサイジング¶
計算手順¶
graph TD
A[口座残高 E] --> B[段階判定]
B --> C[総リスクバジェット<br/>R_tot = E × r_total_pct]
D[確信度スコア S_i] --> E[ソフトマックス]
E --> F[相対ウェイト w_i]
C --> G[リスク配分<br/>Risk_i = w_i × R_tot]
F --> G
G --> H[ポジションサイズ<br/>size_i = Risk_i / risk_per_unit]
H --> I{制約チェック}
I -->|上限超過| J[r_maxで制限]
I -->|最小以下| K[最小ロット適用]
I -->|OK| L[確定サイズ]
J --> L
K --> L
制約¶
| 制約 | 内容 | 目的 |
|---|---|---|
| 最大単一リスク | r_max(段階依存) | 1ポジションへの過度な集中防止 |
| 最小ポジション | $100 | 手数料・スリッページ対策 |
| 同一シンボル上限 | 15% | 同一銘柄への集中防止 |
実装インターフェース¶
データクラス¶
@dataclass
class SignalCandidate:
"""入力: トレードシグナル候補"""
symbol: str
side: str # "long" / "short"
c_mtf: float # MTF一致度 [0,1]
c_gex: float # GEXレジーム適合 [0,1]
c_iv: float # IV適正度 [0,1]
risk_per_unit: float # 1契約あたり$リスク
max_units: int # 最大取引可能サイズ
@dataclass
class AllocationResult:
"""出力: 計算されたポジションサイズ"""
symbol: str
conviction_score: float # S_i ∈ [0,1]
raw_weight: float # 制約前ウェイト
final_weight: float # 制約後ウェイト
target_units: int # ポジションサイズ
risk_amount: float # ドルリスク
risk_ratio: float # 口座に対する%
capped: bool # 制約に引っかかったか
メインAPI¶
class ConvictionAllocator:
def allocate(
self,
equity: float,
signals: List[SignalCandidate]
) -> List[AllocationResult]:
"""
メインエントリーポイント
Args:
equity: 現在の口座残高
signals: トレード候補リスト
Returns:
各シグナルのポジションサイズと配分詳細
"""
アルゴリズム(ステップバイステップ)¶
Step 1: 段階判定¶
def get_stage(equity: float) -> Tuple[CapitalStage, StageConfig]:
g = clip((equity - 20000) / 30000, 0, 1)
# パラメータを補間
n_target = 5 + (20 - 5) * g
r_per_trade = 0.025 - (0.025 - 0.008) * g
r_total = 0.20 - (0.20 - 0.12) * g
beta = 3.0 - (3.0 - 1.5) * g
return StageConfig(n_target, r_per_trade, r_total, beta)
Step 2: 確信度スコア計算¶
def compute_conviction(signal: SignalCandidate) -> float:
return (
0.4 * signal.c_mtf +
0.3 * signal.c_gex +
0.3 * signal.c_iv
)
Step 3: ソフトマックス配分¶
def softmax_weights(scores: List[float], beta: float) -> List[float]:
raw = [exp(beta * s) for s in scores]
total = sum(raw)
return [w / total for w in raw]
Step 4: リスク分配¶
def distribute_risk(
equity: float,
weights: List[float],
r_total_pct: float
) -> List[float]:
total_budget = equity * r_total_pct
return [w * total_budget for w in weights]
Step 5: ポジションサイジング¶
def calculate_position_size(
risk_amount: float,
risk_per_unit: float,
max_units: int,
r_max_pct: float,
equity: float
) -> Tuple[int, bool]:
# 制約1: 最大単一リスク
max_risk = equity * r_max_pct
capped = False
if risk_amount > max_risk:
risk_amount = max_risk
capped = True
# 制約2: ユニット数計算
units = int(risk_amount / risk_per_unit)
units = min(units, max_units)
return units, capped
パラメータキャリブレーション¶
バックテストからの調整¶
def calibrate_from_backtest(trades: List[Trade]):
"""
バックテスト結果から確信度→勝率のマッピングを作成
"""
# 確信度帯ごとの勝率・平均リターンを集計
bins = [(0, 0.3), (0.3, 0.5), (0.5, 0.7), (0.7, 1.0)]
for low, high in bins:
subset = [t for t in trades if low <= t.conviction < high]
if not subset:
continue
win_rate = sum(1 for t in subset if t.pnl > 0) / len(subset)
avg_return = mean([t.pnl for t in subset])
avg_risk = mean([t.risk for t in subset])
print(f"確信度 {low:.1f}-{high:.1f}:")
print(f" 勝率: {win_rate:.1%}")
print(f" 平均リターン: {avg_return:.2f}")
print(f" 平均リスク: {avg_risk:.2f}")
print(f" リスクリワード比: {avg_return/avg_risk:.2f}")
重み最適化(w_mtf, w_gex, w_iv)¶
from scipy.optimize import differential_evolution
def optimize_weights(backtest_data):
"""
ベイズ最適化またはグリッドサーチで最適重みを探索
"""
def objective(weights):
w_mtf, w_gex, w_iv = weights
# 正規化
total = w_mtf + w_gex + w_iv
w_mtf, w_gex, w_iv = w_mtf/total, w_gex/total, w_iv/total
# シャープレシオを最大化
returns = simulate_with_weights(backtest_data, w_mtf, w_gex, w_iv)
sharpe = mean(returns) / std(returns)
return -sharpe # 最小化問題に変換
bounds = [(0.1, 0.7), (0.1, 0.7), (0.1, 0.7)]
result = differential_evolution(objective, bounds)
return result.x
ケリー基準との関係(上位設計)¶
より理論的なアプローチとして、分数ケリーとの統合も可能:
ケリー比率¶
\[
f_i^\text{Kelly} = \frac{b_i p_i - (1 - p_i)}{b_i}
\]
- \(p_i\): 勝率
- \(b_i\): ペイオフ比(リスクリワード比)
確信度→勝率のマッピング¶
バックテストから確信度ごとの勝率を推定:
# 例: 確信度0.8 → 勝率65%, RR比2.0
conviction_to_winrate = {
0.9: (0.70, 2.2),
0.8: (0.65, 2.0),
0.7: (0.60, 1.8),
0.6: (0.55, 1.5),
0.5: (0.50, 1.3),
}
分数ケリー(リスク抑制)¶
実装ファイル¶
| ファイル | 役割 |
|---|---|
core/conviction_allocator/types.py |
データクラス定義 |
core/conviction_allocator/stage.py |
資本段階判定 |
core/conviction_allocator/conviction.py |
確信度スコア計算 |
core/conviction_allocator/allocator.py |
メイン配分エンジン |
core/conviction_allocator/constraints.py |
制約とリミット |
RiskGuardianとの統合¶
既存のRiskGuardianにConvictionAllocatorを統合:
class RiskGuardian:
def __init__(self, ...):
# 既存の設定
self.config = RiskConfig()
# 新規: Conviction Allocator
self.conviction_allocator = ConvictionAllocator()
def calculate_position_size(
self,
equity: float,
signals: List[SignalCandidate]
) -> List[AllocationResult]:
"""
従来の固定リスク計算からConviction-based配分へ移行
"""
return self.conviction_allocator.allocate(equity, signals)
使用例¶
# シグナル候補を準備
signals = [
SignalCandidate(
symbol="AAPL",
side="short",
c_mtf=0.8, # MTF一致度高
c_gex=0.7, # GEXレジーム適合
c_iv=0.9, # IV環境良好
risk_per_unit=50.0, # 1契約$50リスク
max_units=10
),
SignalCandidate(
symbol="MSFT",
side="short",
c_mtf=0.5, # MTF一致度低
c_gex=0.6,
c_iv=0.7,
risk_per_unit=60.0,
max_units=8
),
]
# 配分計算
allocator = ConvictionAllocator()
results = allocator.allocate(equity=25_000, signals=signals)
for r in results:
print(f"{r.symbol}: {r.target_units}枚 (確信度: {r.conviction_score:.2f}, リスク: ${r.risk_amount:.0f})")
出力例:
検証とチューニング¶
バックテストでの検証項目¶
- 段階別パフォーマンス
-
Seed / Transition / Harvest各段階での:
- シャープレシオ
- 最大ドローダウン
- 平均リターン
-
確信度の有効性
- 高確信トレード(S > 0.7)vs 低確信(S < 0.5)の勝率比較
-
確信度とリターンの相関係数
-
βパラメータ感度分析
- β = 1.0, 2.0, 3.0, 4.0 での比較
-
各段階で最適なβを特定
-
資本閾値の妥当性
- $20k, $50k が適切か
- ドローダウン・リターン・分散のバランスから検証
今後のチューニングポイント¶
- w_mtf, w_gex, w_ivの最適化(ベイズ最適化)
- 段階ごとのβキャリブレーション
- ソフトマックス以外の変換関数との比較(べき乗等)
- 分数ケリーとの統合検証
- 相関構造を考慮したリスクパリティ × 確信度のハイブリッド
関連ページ¶
- RiskGuardian - コツコツドカン防止
- MTF Analyzer - マルチタイムフレーム分析
- Strategy Manager - 戦略切替ロジック