feat(ml): re-enable hyperopt action counting (fixes 62% Sharpe degradation)

This commit is contained in:
jgrusewski
2026-02-21 21:20:45 +01:00
parent 4a8513f813
commit ece9ae11d2
10 changed files with 792 additions and 72 deletions

View File

@@ -3044,15 +3044,9 @@ impl HyperparameterOptimizable for DQNTrainer {
};
// Component 2: HFT activity score (25% weight)
// P0 FIX (2025-11-20): TEMPORARILY DISABLED due to missing action counters
// Root cause: DQN trainer never populates buy_count/sell_count/hold_count in additional_metrics
// This causes false -5.0 penalty, degrading Sharpe from 0.77 to 0.29 (62% loss)
// Proper fix requires 1-2h to implement action counting in ml/src/trainers/dqn.rs
// TODO: Re-enable after implementing buy/sell/hold action counting
let hft_activity = 0.0; // DISABLED: was calculate_hft_activity_score_wave10(...)
// Log warning about disabled activity penalty
tracing::warn!("P0 FIX: Activity penalty DISABLED (action counters not implemented)");
// Re-enabled: DQN trainer now populates buy_count/sell_count/hold_count
// in additional_metrics from the 45-action factored space.
let hft_activity = calculate_hft_activity_score_wave10(buy_pct, sell_pct, hold_pct);
// Component 3: Stability penalty (15% weight)
// Penalizes gradient explosion (>50.0) and Q-value volatility (>100.0)

View File

@@ -1128,6 +1128,18 @@ impl DQNTrainer {
metrics.add_metric("top5_coverage_pct", top5_coverage_pct);
metrics.add_metric("total_actions", total_actions as f64);
// Aggregate buy/sell/hold counts from 45-action factored space
// Layout: index = exposure*9 + order*3 + urgency
// Sell (Short100 + Short50): exposure 0-1, indices 0..18
// Hold (Flat): exposure 2, indices 18..27
// Buy (Long50 + Long100): exposure 3-4, indices 27..45
let sell_count: usize = total_action_counts.iter().take(18).sum();
let hold_count: usize = total_action_counts.iter().skip(18).take(9).sum();
let buy_count: usize = total_action_counts.iter().skip(27).sum();
metrics.add_metric("buy_count", buy_count as f64);
metrics.add_metric("sell_count", sell_count as f64);
metrics.add_metric("hold_count", hold_count as f64);
}
if early_stopped {