From 2aa955f0ddea5baa0f656726f704425d6a1dbf0d Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Fri, 17 Apr 2026 20:48:35 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20log=20full=20validation=20backtest=20me?= =?UTF-8?q?trics=20=E2=80=94=20Sharpe=20+=20Sortino=20+=20WinRate=20+=20Ma?= =?UTF-8?q?xDD=20+=20Trades=20+=20Calmar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit compute_validation_loss only returned Sharpe, discarding all other backtest metrics. Now logs the complete picture on every epoch so we can verify if the learning system actually works on out-of-sample data. Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/ml/src/trainers/dqn/trainer/metrics.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/crates/ml/src/trainers/dqn/trainer/metrics.rs b/crates/ml/src/trainers/dqn/trainer/metrics.rs index f475e0102..a441e5c87 100644 --- a/crates/ml/src/trainers/dqn/trainer/metrics.rs +++ b/crates/ml/src/trainers/dqn/trainer/metrics.rs @@ -554,10 +554,16 @@ impl DQNTrainer { ) }.map_err(|e| anyhow::anyhow!("GPU backtest evaluate_dqn_graphed: {e}"))?; - // Single window — take its Sharpe directly - let val_sharpe = metrics.first() - .map(|m| m.sharpe as f64) - .unwrap_or(0.0); + // Single window — log full validation metrics + let val_sharpe = if let Some(m) = metrics.first() { + tracing::info!( + "Validation backtest: Sharpe={:.2} Sortino={:.2} WinRate={:.1}% MaxDD={:.3}% Trades={:.0} Calmar={:.2}", + m.sharpe, m.sortino, m.win_rate * 100.0, m.max_drawdown * 100.0, m.total_trades, m.calmar, + ); + m.sharpe as f64 + } else { + 0.0 + }; Ok(-val_sharpe) }