diff --git a/adaptive-strategy/src/risk/mod.rs b/adaptive-strategy/src/risk/mod.rs index a8b82aa53..33e5ee736 100644 --- a/adaptive-strategy/src/risk/mod.rs +++ b/adaptive-strategy/src/risk/mod.rs @@ -19,7 +19,7 @@ use anyhow::Result; use num_traits::ToPrimitive; use serde::{Deserialize, Serialize}; use std::collections::HashMap; -use tracing::{debug, info}; +use tracing::{debug, info, warn}; // Add missing core types use super::config::{PositionSizingMethod, RiskConfig}; @@ -382,26 +382,50 @@ impl RiskManager { symbol, expected_return ); - // Use enhanced Kelly sizer if available and method is Kelly + // Use enhanced Kelly sizer if available and method is Kelly. + // Falls back to standard sizing if historical data is unavailable. if let PositionSizingMethod::Kelly = &self.config.position_sizing_method { if self.kelly_sizer.is_some() { - return self + match self .calculate_kelly_position_size( symbol, expected_return, confidence, current_price, ) - .await; + .await + { + Ok(recommendation) => return Ok(recommendation), + Err(e) => { + warn!( + symbol = %symbol, + error = %e, + "Kelly sizing failed (no historical data?), falling back to fixed-fraction sizing" + ); + // Fall through to standard sizing below + } + } } } - // Use PPO sizer if available and method is PPO + // Use PPO sizer if available and method is PPO. + // Falls back to standard sizing if historical data is unavailable. if let PositionSizingMethod::PPO = &self.config.position_sizing_method { if self.ppo_sizer.is_some() { - return self + match self .calculate_ppo_position_size(symbol, expected_return, confidence, current_price) - .await; + .await + { + Ok(recommendation) => return Ok(recommendation), + Err(e) => { + warn!( + symbol = %symbol, + error = %e, + "PPO sizing failed (no historical data?), falling back to fixed-fraction sizing" + ); + // Fall through to standard sizing below + } + } } } @@ -555,15 +579,17 @@ impl RiskManager { }) } - /// Get historical returns for a symbol (production implementation) - async fn get_historical_returns(&self, _symbol: &str) -> Result> { - // In production, this would fetch from market data service - // For now, return sample data - Ok(vec![ - 0.05_f64, -0.02_f64, 0.08_f64, -0.03_f64, 0.06_f64, -0.01_f64, 0.04_f64, -0.02_f64, - 0.07_f64, -0.01_f64, 0.03_f64, -0.04_f64, 0.09_f64, -0.02_f64, 0.05_f64, -0.03_f64, - 0.06_f64, -0.01_f64, 0.08_f64, -0.02_f64, - ]) + /// Get historical returns for a symbol. + /// + /// Returns an error because no market data feed is connected yet. + /// Callers should fall back to fixed-fraction position sizing when this fails. + async fn get_historical_returns(&self, symbol: &str) -> Result> { + anyhow::bail!( + "No historical return data available for '{}'. \ + A market data service must be integrated to provide real return history. \ + Falling back to fixed-fraction sizing is recommended.", + symbol + ) } /// Build market data for Kelly calculation