drl-trading-bot-dev2 / src /models /confidence_engine.py
DRL Trading Bot
Feature: HTF Agent integration — live trading, API endpoints, UI tab
fc115d5
Raw
History Blame Contribute Delete
3.63 kB
"""
Confidence Engine (Phase 11.6)
Scales trade position sizes based on the predictive uncertainty
of the ensemble agents.
Calculates a Confidence Multiplier based on:
1. Ensemble Agreement (HMM probability alignment)
2. Historical Win Rate of similar confidence trades
"""
import numpy as np
import logging
from typing import Dict, List
logger = logging.getLogger(__name__)
class ConfidenceEngine:
"""
Translates model confidence into position sizing multipliers.
"""
def __init__(
self,
min_multiplier: float = 0.25,
max_multiplier: float = 2.0,
baseline_confidence: float = 0.5,
):
self.min_multiplier = min_multiplier
self.max_multiplier = max_multiplier
self.baseline_confidence = baseline_confidence
# Track historical confidence vs outcome
self.confidence_history: List[float] = []
self.outcome_history: List[float] = []
def get_position_multiplier(self, raw_confidence: float) -> float:
"""
Convert raw model confidence [0.0 - 1.0] to a position multiplier.
Args:
raw_confidence: The agreement score from the EnsembleOrchestrator
Returns:
multiplier (float): to be multiplied with base position size
"""
# If confidence is below baseline, scale down linearly
if raw_confidence < self.baseline_confidence:
scale = raw_confidence / self.baseline_confidence
multiplier = self.min_multiplier + (1.0 - self.min_multiplier) * scale
# If confidence is above baseline, scale up
else:
scale = (raw_confidence - self.baseline_confidence) / (1.0 - self.baseline_confidence)
multiplier = 1.0 + (self.max_multiplier - 1.0) * (scale ** 1.5) # Exponential scale up
return np.clip(multiplier, self.min_multiplier, self.max_multiplier)
def apply_confidence(self, base_size: float, raw_confidence: float) -> float:
"""Calculate final position size."""
multiplier = self.get_position_multiplier(raw_confidence)
# Base size * multiplier
final_size = base_size * multiplier
logger.info(
f"🧠 Confidence Engine: Raw={raw_confidence:.2f} -> "
f"Mult={multiplier:.2f}x -> Size={base_size:.2%} to {final_size:.2%}"
)
return final_size
def record_outcome(self, confidence: float, pnl_pct: float):
"""Record trade outcome to map confidence correlations later."""
self.confidence_history.append(confidence)
self.outcome_history.append(pnl_pct)
if len(self.confidence_history) > 1000:
self.confidence_history.pop(0)
self.outcome_history.pop(0)
def get_confidence_reliability(self) -> float:
"""Calculate Pearson correlation between confidence and P&L."""
if len(self.confidence_history) < 20:
return 0.0
try:
corr = np.corrcoef(self.confidence_history, self.outcome_history)[0, 1]
return float(corr) if not np.isnan(corr) else 0.0
except Exception:
return 0.0
# Usage example
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
engine = ConfidenceEngine()
print("-" * 40)
print("Confidence Multiplier Curve")
print("-" * 40)
for conf in [0.1, 0.3, 0.5, 0.7, 0.9, 1.0]:
mult = engine.get_position_multiplier(conf)
print(f"Conf: {conf:.2f} -> Mult: {mult:.2f}x")