Trading-Bot-M20 / ml /position_sizer.py
raghava4u's picture
Upload folder using huggingface_hub
d53dc44 verified
Raw History Blame Contribute Delete
4.19 kB
"""
ml/position_sizer.py — Probabilistic position sizing.
Sizes positions based on:
1. ML signal confidence (P(win))
2. Regime volatility context
3. Rolling Sharpe-based scaling
4. Drawdown-based reduction (from original system)
"""
from __future__ import annotations
import logging
import numpy as np
import pandas as pd
logger = logging.getLogger("trading_system.ml.position_sizer")
class ProbabilisticSizer:
"""Position sizing that scales with ML probability edge.
Core formula:
base_risk = equity * risk_per_trade_pct
edge_scale = (P(win) - 0.5) * edge_mult (capped)
vol_scale = avg_vol / current_vol (inverse vol)
dd_scale = drawdown reduction
final_risk = base_risk * (1 + edge_scale) * vol_scale * dd_scale
Safeguards:
- Min size: 25% of base risk (never go below this)
- Max size: 200% of base risk (never exceed 2x)
- Hard cap: max_risk_pct of equity per trade
"""
def __init__(
self,
base_risk_pct: float = 1.0,
edge_multiplier: float = 2.0,
max_scale: float = 2.0,
min_scale: float = 0.25,
max_risk_pct: float = 2.5,
dd_reduction_start: float = 3.0, # start reducing at 3% DD
dd_reduction_severe: float = 5.0, # halve at 5% DD
):
self.base_risk_pct = base_risk_pct
self.edge_multiplier = edge_multiplier
self.max_scale = max_scale
self.min_scale = min_scale
self.max_risk_pct = max_risk_pct
self.dd_reduction_start = dd_reduction_start
self.dd_reduction_severe = dd_reduction_severe
def compute_position_risk(
self,
equity: float,
peak_equity: float,
ml_confidence: float,
conf_multiplier: float,
atr_current: float,
atr_avg: float,
regime_vol: float = 0.0,
strategy_risk_scale: float = 1.0,
) -> float:
"""Compute dollar risk for a single trade.
Args:
equity: Current portfolio equity.
peak_equity: Peak equity for DD calculation.
ml_confidence: ML model confidence [0, 1].
conf_multiplier: Rule-based confidence multiplier [0.5, 1.5].
atr_current: Current ATR.
atr_avg: Average ATR (e.g. 50-bar).
regime_vol: Current regime volatility level.
strategy_risk_scale: Strategy-specific scale (e.g. 0.6 for MR).
Returns: Dollar risk amount for this trade.
"""
base_risk = equity * (self.base_risk_pct / 100.0)
# 1. ML edge scaling: conservative — only small bonus for high confidence
edge = (ml_confidence - 0.5) * self.edge_multiplier # only > 50% gets bonus
edge = max(-0.3, min(0.5, edge)) # tight clamp
edge_scale = 1.0 + edge
# 2. Inverse volatility scaling
if atr_avg > 0 and atr_current > 0:
vol_scale = atr_avg / atr_current
vol_scale = max(0.5, min(1.5, vol_scale))
else:
vol_scale = 1.0
# 3. Drawdown-based reduction
dd_pct = ((peak_equity - equity) / peak_equity * 100) if peak_equity > 0 else 0
if dd_pct >= self.dd_reduction_severe:
dd_scale = 0.5
elif dd_pct >= self.dd_reduction_start:
# Linear interpolation from 1.0 at start to 0.5 at severe
frac = (dd_pct - self.dd_reduction_start) / (self.dd_reduction_severe - self.dd_reduction_start)
dd_scale = 1.0 - 0.5 * frac
else:
dd_scale = 1.0
# 4. Strategy-specific scaling + rule confidence
final_risk = (base_risk * edge_scale * vol_scale * dd_scale
* conf_multiplier * strategy_risk_scale)
# Clamp to [min, max] of base risk
final_risk = max(base_risk * self.min_scale,
min(base_risk * self.max_scale, final_risk))
# Hard cap
hard_cap = equity * (self.max_risk_pct / 100.0)
final_risk = min(final_risk, hard_cap)
return max(0.0, final_risk)