From 9501d581adbd12e9f3ea7e2edd89d466850272b4 Mon Sep 17 00:00:00 2001 From: jgrusewski Date: Tue, 3 Mar 2026 16:08:19 +0100 Subject: [PATCH] feat(fxt): add epoch financial metrics to train monitor output Add print_financial_metrics() to the monitor command, displaying per-model Sharpe ratio (color-coded green/yellow/red), win rate, max drawdown, profit factor, total return, trade count, and action distribution (BUY/SELL/HOLD percentages). Only shown when sessions report non-zero financial data. Co-Authored-By: Claude Opus 4.6 --- bin/fxt/src/commands/train/monitor.rs | 40 +++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/bin/fxt/src/commands/train/monitor.rs b/bin/fxt/src/commands/train/monitor.rs index b8a13e00f..56c32d899 100644 --- a/bin/fxt/src/commands/train/monitor.rs +++ b/bin/fxt/src/commands/train/monitor.rs @@ -101,6 +101,7 @@ fn render_snapshot(resp: &GetLiveTrainingMetricsResponse) { print_rl_diagnostics(&resp.sessions); print_hyperopt_summary(&resp.sessions); print_health_summary(&resp.sessions); + print_financial_metrics(&resp.sessions); } fn render_tui(resp: &GetLiveTrainingMetricsResponse) { @@ -232,3 +233,42 @@ fn print_health_summary(sessions: &[TrainingSession]) { total_nan, total_grad, total_ckpt ); } + +fn print_financial_metrics(sessions: &[TrainingSession]) { + let financial: Vec<_> = sessions + .iter() + .filter(|s| s.epoch_sharpe != 0.0 || s.epoch_win_rate > 0.0) + .collect(); + if financial.is_empty() { + return; + } + println!(); + println!("{}", "Epoch Financial Metrics:".bright_cyan()); + for s in &financial { + let sharpe_colored = if s.epoch_sharpe >= 2.0 { + format!("{:.2}", s.epoch_sharpe).green() + } else if s.epoch_sharpe >= 1.0 { + format!("{:.2}", s.epoch_sharpe).yellow() + } else { + format!("{:.2}", s.epoch_sharpe).red() + }; + println!( + " {}: Sharpe={} WinRate={:.1}% MaxDD={:.1}% PF={:.2} Return={:+.2}% Trades={}", + s.model.bright_white(), + sharpe_colored, + s.epoch_win_rate * 100.0, + s.epoch_max_drawdown * 100.0, + s.epoch_profit_factor, + s.epoch_total_return * 100.0, + s.epoch_total_trades, + ); + if s.action_buy_pct > 0.0 || s.action_sell_pct > 0.0 { + println!( + " Actions: BUY {:.0}% | SELL {:.0}% | HOLD {:.0}%", + s.action_buy_pct * 100.0, + s.action_sell_pct * 100.0, + s.action_hold_pct * 100.0, + ); + } + } +}