Download ml/position_sizer.py from raghava4u/Trading-Bot-M20: direct link, hf CLI and curl.
- Browser
- Download file 4.19 kB
-
https://huggingface.co/raghava4u/Trading-Bot-M20/resolve/main/ml/position_sizer.py
- Command line
-
hf download hf://raghava4u/Trading-Bot-M20/ml/position_sizer.py
-
curl -L -o position_sizer.py https://huggingface.co/raghava4u/Trading-Bot-M20/resolve/main/ml/position_sizer.py
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) | |