refactor(adaptive-strategy): remove dead code from kelly_position_sizer
- Delete dead methods: calculate_base_kelly, calculate_variance (never called) - Delete unused enum variants: VolatilityModelType::Garch/RangeBased/Realized - Prefix 30+ unused struct fields with _ instead of #[allow(dead_code)] - Remove all #[allow(dead_code)] attributes (24 total removed) - Make calculate_win_loss_stats pub (used in tests) - 80/80 tests pass, zero warnings Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -201,8 +201,7 @@ pub struct DynamicRiskAdjuster {
|
||||
/// Portfolio drawdown tracker
|
||||
drawdown_tracker: DrawdownTracker,
|
||||
/// Volatility environment (reserved for volatility-adjusted sizing)
|
||||
#[allow(dead_code)]
|
||||
volatility_regime: VolatilityRegime,
|
||||
_volatility_regime: VolatilityRegime,
|
||||
}
|
||||
|
||||
// MarketRegime is already imported from ml::prelude at the top
|
||||
@@ -225,225 +224,162 @@ pub enum VolatilityRegime {
|
||||
|
||||
/// Portfolio concentration monitoring
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct ConcentrationMonitor {
|
||||
/// Current position concentrations by symbol
|
||||
concentrations: HashMap<String, f64>,
|
||||
/// Sector concentrations
|
||||
#[allow(dead_code)]
|
||||
sector_concentrations: HashMap<String, f64>,
|
||||
_sector_concentrations: HashMap<String, f64>,
|
||||
/// Geographic concentrations
|
||||
#[allow(dead_code)]
|
||||
geographic_concentrations: HashMap<String, f64>,
|
||||
_geographic_concentrations: HashMap<String, f64>,
|
||||
/// Asset class concentrations
|
||||
#[allow(dead_code)]
|
||||
asset_class_concentrations: HashMap<String, f64>,
|
||||
_asset_class_concentrations: HashMap<String, f64>,
|
||||
/// Correlation matrix
|
||||
#[allow(dead_code)]
|
||||
correlation_matrix: CorrelationMatrix,
|
||||
_correlation_matrix: CorrelationMatrix,
|
||||
}
|
||||
|
||||
/// Correlation matrix for position sizing adjustments
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct CorrelationMatrix {
|
||||
/// Symbols included in matrix
|
||||
#[allow(dead_code)]
|
||||
symbols: Vec<String>,
|
||||
_symbols: Vec<String>,
|
||||
/// Correlation coefficients (symmetric matrix)
|
||||
#[allow(dead_code)]
|
||||
correlations: Vec<Vec<f64>>,
|
||||
_correlations: Vec<Vec<f64>>,
|
||||
/// Last update timestamp
|
||||
#[allow(dead_code)]
|
||||
last_update: DateTime<Utc>,
|
||||
_last_update: DateTime<Utc>,
|
||||
/// Average correlation
|
||||
#[allow(dead_code)]
|
||||
avg_correlation: f64,
|
||||
_avg_correlation: f64,
|
||||
}
|
||||
|
||||
/// Volatility-based position optimization
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct VolatilityOptimizer {
|
||||
/// Volatility estimates by symbol
|
||||
volatility_estimates: HashMap<String, VolatilityEstimate>,
|
||||
/// Target portfolio volatility
|
||||
target_volatility: f64,
|
||||
/// Current portfolio volatility
|
||||
#[allow(dead_code)]
|
||||
current_volatility: f64,
|
||||
_current_volatility: f64,
|
||||
/// Volatility forecasting model
|
||||
#[allow(dead_code)]
|
||||
volatility_model: VolatilityModel,
|
||||
_volatility_model: VolatilityModel,
|
||||
}
|
||||
|
||||
/// Volatility estimate with confidence intervals
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct VolatilityEstimate {
|
||||
/// Current volatility estimate (annualized)
|
||||
pub(super) current: f64,
|
||||
/// 1-day ahead forecast
|
||||
#[allow(dead_code)]
|
||||
forecast_1d: f64,
|
||||
pub(super) _forecast_1d: f64,
|
||||
/// 5-day ahead forecast
|
||||
#[allow(dead_code)]
|
||||
forecast_5d: f64,
|
||||
pub(super) _forecast_5d: f64,
|
||||
/// Confidence interval (95%)
|
||||
#[allow(dead_code)]
|
||||
confidence_interval: (f64, f64),
|
||||
pub(super) _confidence_interval: (f64, f64),
|
||||
/// Model used for estimation
|
||||
#[allow(dead_code)]
|
||||
model_type: VolatilityModelType,
|
||||
pub(super) _model_type: VolatilityModelType,
|
||||
/// Last update timestamp
|
||||
#[allow(dead_code)]
|
||||
last_update: DateTime<Utc>,
|
||||
pub(super) _last_update: DateTime<Utc>,
|
||||
}
|
||||
|
||||
/// Volatility forecasting models
|
||||
#[derive(Debug, Clone)]
|
||||
pub(super) enum VolatilityModelType {
|
||||
/// GARCH(1,1) model
|
||||
#[allow(dead_code)]
|
||||
Garch,
|
||||
/// Exponentially weighted moving average
|
||||
Ewma,
|
||||
/// Range-based volatility
|
||||
#[allow(dead_code)]
|
||||
RangeBased,
|
||||
/// Realized volatility
|
||||
#[allow(dead_code)]
|
||||
Realized,
|
||||
}
|
||||
|
||||
/// Volatility forecasting model
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct VolatilityModel {
|
||||
/// Model parameters
|
||||
#[allow(dead_code)]
|
||||
parameters: HashMap<String, f64>,
|
||||
_parameters: HashMap<String, f64>,
|
||||
/// Model type
|
||||
#[allow(dead_code)]
|
||||
model_type: VolatilityModelType,
|
||||
_model_type: VolatilityModelType,
|
||||
/// Calibration history
|
||||
#[allow(dead_code)]
|
||||
calibration_history: Vec<CalibrationRecord>,
|
||||
_calibration_history: Vec<CalibrationRecord>,
|
||||
}
|
||||
|
||||
/// Volatility model calibration record
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct CalibrationRecord {
|
||||
/// Calibration timestamp
|
||||
#[allow(dead_code)]
|
||||
timestamp: DateTime<Utc>,
|
||||
_timestamp: DateTime<Utc>,
|
||||
/// Model parameters at calibration
|
||||
#[allow(dead_code)]
|
||||
parameters: HashMap<String, f64>,
|
||||
_parameters: HashMap<String, f64>,
|
||||
/// In-sample error metrics
|
||||
#[allow(dead_code)]
|
||||
in_sample_error: f64,
|
||||
_in_sample_error: f64,
|
||||
/// Out-of-sample error metrics
|
||||
#[allow(dead_code)]
|
||||
out_of_sample_error: Option<f64>,
|
||||
_out_of_sample_error: Option<f64>,
|
||||
}
|
||||
|
||||
/// Portfolio drawdown tracking
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct DrawdownTracker {
|
||||
/// High water mark
|
||||
#[allow(dead_code)]
|
||||
high_water_mark: f64,
|
||||
_high_water_mark: f64,
|
||||
/// Current drawdown
|
||||
#[allow(dead_code)]
|
||||
current_drawdown: f64,
|
||||
_current_drawdown: f64,
|
||||
/// Maximum drawdown
|
||||
#[allow(dead_code)]
|
||||
max_drawdown: f64,
|
||||
_max_drawdown: f64,
|
||||
/// Drawdown start time
|
||||
#[allow(dead_code)]
|
||||
drawdown_start: Option<DateTime<Utc>>,
|
||||
_drawdown_start: Option<DateTime<Utc>>,
|
||||
/// Recovery factor (how much to reduce risk during drawdowns)
|
||||
pub(super) recovery_factor: f64,
|
||||
}
|
||||
|
||||
/// Performance tracking for Kelly optimization
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct PerformanceTracker {
|
||||
/// Daily returns history
|
||||
#[allow(dead_code)]
|
||||
returns_history: Vec<DailyReturn>,
|
||||
_returns_history: Vec<DailyReturn>,
|
||||
/// Kelly sizing performance
|
||||
pub(super) kelly_performance: KellyPerformanceMetrics,
|
||||
/// Model accuracy tracking
|
||||
#[allow(dead_code)]
|
||||
accuracy_tracker: AccuracyTracker,
|
||||
_accuracy_tracker: AccuracyTracker,
|
||||
}
|
||||
|
||||
/// Daily return record
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct DailyReturn {
|
||||
/// Date
|
||||
#[allow(dead_code)]
|
||||
date: NaiveDate,
|
||||
_date: NaiveDate,
|
||||
/// Portfolio return
|
||||
#[allow(dead_code)]
|
||||
portfolio_return: f64,
|
||||
_portfolio_return: f64,
|
||||
/// Kelly-sized positions return
|
||||
#[allow(dead_code)]
|
||||
kelly_return: f64,
|
||||
_kelly_return: f64,
|
||||
/// Attribution by position
|
||||
#[allow(dead_code)]
|
||||
position_attribution: HashMap<String, f64>,
|
||||
_position_attribution: HashMap<String, f64>,
|
||||
}
|
||||
|
||||
/// Kelly performance metrics
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct KellyPerformanceMetrics {
|
||||
/// Sharpe ratio
|
||||
#[allow(dead_code)]
|
||||
sharpe_ratio: f64,
|
||||
_sharpe_ratio: f64,
|
||||
/// Sortino ratio
|
||||
#[allow(dead_code)]
|
||||
sortino_ratio: f64,
|
||||
_sortino_ratio: f64,
|
||||
/// Maximum drawdown
|
||||
#[allow(dead_code)]
|
||||
max_drawdown: f64,
|
||||
_max_drawdown: f64,
|
||||
/// Calmar ratio
|
||||
#[allow(dead_code)]
|
||||
calmar_ratio: f64,
|
||||
_calmar_ratio: f64,
|
||||
/// Win rate
|
||||
#[allow(dead_code)]
|
||||
win_rate: f64,
|
||||
_win_rate: f64,
|
||||
/// Average win/loss ratio
|
||||
#[allow(dead_code)]
|
||||
win_loss_ratio: f64,
|
||||
_win_loss_ratio: f64,
|
||||
/// Kelly criterion effectiveness
|
||||
#[allow(dead_code)]
|
||||
kelly_effectiveness: f64,
|
||||
_kelly_effectiveness: f64,
|
||||
}
|
||||
|
||||
/// Model accuracy tracking
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub(super) struct AccuracyTracker {
|
||||
/// Prediction accuracy by horizon
|
||||
#[allow(dead_code)]
|
||||
accuracy_by_horizon: HashMap<String, f64>,
|
||||
_accuracy_by_horizon: HashMap<String, f64>,
|
||||
/// Calibration score
|
||||
#[allow(dead_code)]
|
||||
calibration_score: f64,
|
||||
_calibration_score: f64,
|
||||
/// Information coefficient
|
||||
#[allow(dead_code)]
|
||||
information_coefficient: f64,
|
||||
_information_coefficient: f64,
|
||||
/// Hit rate
|
||||
#[allow(dead_code)]
|
||||
hit_rate: f64,
|
||||
_hit_rate: f64,
|
||||
}
|
||||
|
||||
/// Enhanced Kelly position recommendation
|
||||
@@ -639,61 +575,8 @@ impl KellyPositionSizer {
|
||||
Ok(recommendation)
|
||||
}
|
||||
|
||||
/// Calculate base Kelly fraction using multiple methods
|
||||
#[allow(dead_code)]
|
||||
fn calculate_base_kelly(
|
||||
&self,
|
||||
_symbol: &str,
|
||||
expected_return: f64,
|
||||
historical_returns: &[f64],
|
||||
) -> Result<f64> {
|
||||
if historical_returns.is_empty() {
|
||||
return Ok(0.0);
|
||||
}
|
||||
|
||||
// Method 1: Classic Kelly formula
|
||||
let variance = self.calculate_variance(historical_returns);
|
||||
let classic_kelly = if variance > 0.0 {
|
||||
expected_return / variance
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
// Method 2: Win/loss statistics Kelly
|
||||
let (win_rate, avg_win, avg_loss) = self.calculate_win_loss_stats(historical_returns);
|
||||
let empirical_kelly = if avg_loss > 0.0 {
|
||||
let odds = avg_win / avg_loss;
|
||||
(win_rate * odds - (1.0 - win_rate)) / odds
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
|
||||
// Method 3: Fractional Kelly for safety
|
||||
let fractional_kelly = classic_kelly * 0.5; // Half Kelly for safety
|
||||
|
||||
// Combine methods with weighting
|
||||
let combined_kelly = 0.4 * classic_kelly + 0.4 * empirical_kelly + 0.2 * fractional_kelly;
|
||||
|
||||
Ok(combined_kelly.clamp(0.0, self.config.max_fraction))
|
||||
}
|
||||
|
||||
/// Calculate variance of historical returns
|
||||
#[allow(dead_code)]
|
||||
fn calculate_variance(&self, returns: &[f64]) -> f64 {
|
||||
if returns.len() < 2 {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
let mean = returns.iter().sum::<f64>() / returns.len() as f64;
|
||||
let variance =
|
||||
returns.iter().map(|r| (r - mean).powi(2)).sum::<f64>() / returns.len() as f64;
|
||||
|
||||
variance
|
||||
}
|
||||
|
||||
/// Calculate win/loss statistics
|
||||
#[allow(dead_code)]
|
||||
fn calculate_win_loss_stats(&self, returns: &[f64]) -> (f64, f64, f64) {
|
||||
pub fn calculate_win_loss_stats(&self, returns: &[f64]) -> (f64, f64, f64) {
|
||||
let wins: Vec<f64> = returns.iter().filter(|&&r| r > 0.0).copied().collect();
|
||||
let losses: Vec<f64> = returns.iter().filter(|&&r| r < 0.0).map(|r| -r).collect();
|
||||
|
||||
@@ -814,7 +697,7 @@ impl DynamicRiskAdjuster {
|
||||
current_regime: MarketRegime::Unknown,
|
||||
regime_scalers,
|
||||
drawdown_tracker: DrawdownTracker::new(config),
|
||||
volatility_regime: VolatilityRegime::Normal,
|
||||
_volatility_regime: VolatilityRegime::Normal,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -903,10 +786,10 @@ impl ConcentrationMonitor {
|
||||
pub(super) fn new(_config: &KellyConfig) -> Result<Self> {
|
||||
Ok(Self {
|
||||
concentrations: HashMap::new(),
|
||||
sector_concentrations: HashMap::new(),
|
||||
geographic_concentrations: HashMap::new(),
|
||||
asset_class_concentrations: HashMap::new(),
|
||||
correlation_matrix: CorrelationMatrix::new(),
|
||||
_sector_concentrations: HashMap::new(),
|
||||
_geographic_concentrations: HashMap::new(),
|
||||
_asset_class_concentrations: HashMap::new(),
|
||||
_correlation_matrix: CorrelationMatrix::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -977,8 +860,8 @@ impl VolatilityOptimizer {
|
||||
Ok(Self {
|
||||
volatility_estimates: HashMap::new(),
|
||||
target_volatility: 0.15, // 15% target volatility
|
||||
current_volatility: 0.0,
|
||||
volatility_model: VolatilityModel::new()?,
|
||||
_current_volatility: 0.0,
|
||||
_volatility_model: VolatilityModel::new()?,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1014,9 +897,9 @@ impl VolatilityOptimizer {
|
||||
impl VolatilityModel {
|
||||
pub(super) fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
parameters: HashMap::new(),
|
||||
model_type: VolatilityModelType::Ewma,
|
||||
calibration_history: Vec::new(),
|
||||
_parameters: HashMap::new(),
|
||||
_model_type: VolatilityModelType::Ewma,
|
||||
_calibration_history: Vec::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1036,10 +919,10 @@ impl DrawdownTracker {
|
||||
/// A new `DrawdownTracker` instance ready for monitoring
|
||||
pub fn new(_config: &KellyConfig) -> Self {
|
||||
Self {
|
||||
high_water_mark: 100000.0, // Initial portfolio value
|
||||
current_drawdown: 0.0,
|
||||
max_drawdown: 0.0,
|
||||
drawdown_start: None,
|
||||
_high_water_mark: 100000.0, // Initial portfolio value
|
||||
_current_drawdown: 0.0,
|
||||
_max_drawdown: 0.0,
|
||||
_drawdown_start: None,
|
||||
recovery_factor: 1.0,
|
||||
}
|
||||
}
|
||||
@@ -1048,9 +931,9 @@ impl DrawdownTracker {
|
||||
impl PerformanceTracker {
|
||||
pub(super) fn new() -> Result<Self> {
|
||||
Ok(Self {
|
||||
returns_history: Vec::new(),
|
||||
_returns_history: Vec::new(),
|
||||
kelly_performance: KellyPerformanceMetrics::default(),
|
||||
accuracy_tracker: AccuracyTracker::new(),
|
||||
_accuracy_tracker: AccuracyTracker::new(),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1066,13 +949,13 @@ impl PerformanceTracker {
|
||||
impl Default for KellyPerformanceMetrics {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
sharpe_ratio: 0.0,
|
||||
sortino_ratio: 0.0,
|
||||
max_drawdown: 0.0,
|
||||
calmar_ratio: 0.0,
|
||||
win_rate: 0.0,
|
||||
win_loss_ratio: 0.0,
|
||||
kelly_effectiveness: 0.0,
|
||||
_sharpe_ratio: 0.0,
|
||||
_sortino_ratio: 0.0,
|
||||
_max_drawdown: 0.0,
|
||||
_calmar_ratio: 0.0,
|
||||
_win_rate: 0.0,
|
||||
_win_loss_ratio: 0.0,
|
||||
_kelly_effectiveness: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1080,10 +963,10 @@ impl Default for KellyPerformanceMetrics {
|
||||
impl AccuracyTracker {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
accuracy_by_horizon: HashMap::new(),
|
||||
calibration_score: 0.0,
|
||||
information_coefficient: 0.0,
|
||||
hit_rate: 0.0,
|
||||
_accuracy_by_horizon: HashMap::new(),
|
||||
_calibration_score: 0.0,
|
||||
_information_coefficient: 0.0,
|
||||
_hit_rate: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1091,10 +974,10 @@ impl AccuracyTracker {
|
||||
impl CorrelationMatrix {
|
||||
pub(super) fn new() -> Self {
|
||||
Self {
|
||||
symbols: Vec::new(),
|
||||
correlations: Vec::new(),
|
||||
last_update: Utc::now(),
|
||||
avg_correlation: 0.0,
|
||||
_symbols: Vec::new(),
|
||||
_correlations: Vec::new(),
|
||||
_last_update: Utc::now(),
|
||||
_avg_correlation: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,11 +339,11 @@ async fn test_volatility_estimates_update() {
|
||||
let mut estimates = HashMap::new();
|
||||
estimates.insert(TEST_SYMBOL_1.to_string(), kelly_position_sizer::VolatilityEstimate {
|
||||
current: 0.18,
|
||||
forecast_1d: 0.19,
|
||||
forecast_5d: 0.20,
|
||||
confidence_interval: (0.15, 0.22),
|
||||
model_type: kelly_position_sizer::VolatilityModelType::Garch,
|
||||
last_update: chrono::Utc::now(),
|
||||
_forecast_1d: 0.19,
|
||||
_forecast_5d: 0.20,
|
||||
_confidence_interval: (0.15, 0.22),
|
||||
_model_type: kelly_position_sizer::VolatilityModelType::Ewma,
|
||||
_last_update: chrono::Utc::now(),
|
||||
});
|
||||
|
||||
let result = sizer.update_volatility_estimates(estimates).await;
|
||||
|
||||
Reference in New Issue
Block a user