"""Core data models for the autonomous trading engine. Defines dataclasses for risk tier configuration, portfolio state, trading decisions, position sizing results, stop levels, and performance metrics used across all trading engine components. """ from __future__ import annotations from dataclasses import dataclass, field from datetime import datetime, timedelta # --------------------------------------------------------------------------- # Risk Tier Configuration # --------------------------------------------------------------------------- @dataclass class RiskTierConfig: """Parameters for a named risk tier (conservative/moderate/aggressive).""" name: str min_confidence: float max_position_pct: float stop_loss_atr_multiplier: float reward_risk_ratio: float max_sector_pct: float max_portfolio_heat: float RISK_TIER_DEFAULTS: dict[str, RiskTierConfig] = { "conservative": RiskTierConfig( name="conservative", min_confidence=0.75, max_position_pct=0.05, stop_loss_atr_multiplier=1.5, reward_risk_ratio=2.0, max_sector_pct=0.20, max_portfolio_heat=0.10, ), "moderate": RiskTierConfig( name="moderate", min_confidence=0.55, max_position_pct=0.10, stop_loss_atr_multiplier=2.0, reward_risk_ratio=1.5, max_sector_pct=0.30, max_portfolio_heat=0.20, ), "aggressive": RiskTierConfig( name="aggressive", min_confidence=0.40, max_position_pct=0.15, stop_loss_atr_multiplier=2.5, reward_risk_ratio=1.2, max_sector_pct=0.40, max_portfolio_heat=0.30, ), } # --------------------------------------------------------------------------- # Portfolio State # --------------------------------------------------------------------------- @dataclass class PortfolioState: """Snapshot of the current portfolio used for decision-making.""" positions: list = field(default_factory=list) total_value: float = 0.0 cash: float = 0.0 active_pool: float = 0.0 reserve_pool: float = 0.0 sector_exposure: dict[str, float] = field(default_factory=dict) portfolio_heat: float = 0.0 open_position_count: int = 0 # --------------------------------------------------------------------------- # Trading Decision # --------------------------------------------------------------------------- @dataclass class TradingDecision: """Record of a trading decision (act or skip), persisted for audit trail.""" id: str recommendation_id: str | None decision: str skip_reason: str | None ticker: str computed_position_size: float | None computed_share_quantity: int | None risk_tier_at_decision: str portfolio_heat_at_decision: float | None active_pool_at_decision: float | None reserve_pool_at_decision: float | None circuit_breaker_status: str correlation_check_result: dict = field(default_factory=dict) sector_exposure_check_result: dict = field(default_factory=dict) earnings_proximity_flag: bool = False is_micro_trade: bool = False decision_trace: dict = field(default_factory=dict) created_at: datetime = field(default_factory=datetime.utcnow) # --------------------------------------------------------------------------- # Position Sizing # --------------------------------------------------------------------------- @dataclass class PositionSizeResult: """Output of the position sizer computation.""" dollar_amount: float share_quantity: int allocation_pct: float adjustments: list[str] = field(default_factory=list) rejected: bool = False rejection_reason: str = "" # --------------------------------------------------------------------------- # Stop-Loss / Take-Profit Levels # --------------------------------------------------------------------------- @dataclass class StopLevels: """Current stop-loss and take-profit levels for an open position.""" stop_loss_price: float take_profit_price: float trailing_stop_active: bool atr_value: float atr_multiplier: float reward_risk_ratio: float last_updated: datetime = field(default_factory=datetime.utcnow) # --------------------------------------------------------------------------- # Open / Closed Positions # --------------------------------------------------------------------------- @dataclass class OpenPosition: """Representation of a currently held position.""" ticker: str quantity: int entry_price: float current_price: float unrealized_pnl: float market_value: float sector: str stop_loss_price: float take_profit_price: float signal_confidence: float is_micro_trade: bool = False @dataclass class ClosedTrade: """Record of a completed (closed) trade.""" ticker: str entry_price: float exit_price: float quantity: int pnl: float pnl_pct: float hold_duration: timedelta recommendation_id: str | None = None is_micro_trade: bool = False # --------------------------------------------------------------------------- # Performance Metrics # --------------------------------------------------------------------------- @dataclass class PerformanceMetrics: """Portfolio-wide performance metrics computed periodically.""" total_portfolio_value: float active_pool: float reserve_pool: float unrealized_pnl: float realized_pnl: float daily_pnl: float win_count: int loss_count: int win_rate: float avg_win: float avg_loss: float profit_factor: float sharpe_ratio: float max_drawdown: float current_drawdown_pct: float portfolio_heat: float computed_at: datetime = field(default_factory=datetime.utcnow) # --------------------------------------------------------------------------- # Circuit Breaker # --------------------------------------------------------------------------- @dataclass class CircuitBreakerState: """Current state of the circuit breaker safety mechanism.""" active: bool = False trigger_type: str | None = None triggered_at: datetime | None = None cooldown_expires: datetime | None = None ticker_cooldowns: dict[str, datetime] = field(default_factory=dict) # --------------------------------------------------------------------------- # Reserve Pool # --------------------------------------------------------------------------- @dataclass class ReservePoolState: """Current state of the reserve pool.""" balance: float = 0.0 total_deposits: float = 0.0 total_withdrawals: float = 0.0 last_updated: datetime = field(default_factory=datetime.utcnow) # --------------------------------------------------------------------------- # Stop Trigger # --------------------------------------------------------------------------- @dataclass class StopTrigger: """A triggered stop-loss or take-profit event for a position.""" ticker: str trigger_type: str # "stop_loss" or "take_profit" current_price: float trigger_price: float