test: 80-epoch convergence test — C51 warmup headroom

Extended convergence test from 50 → 80 epochs to give C51 distributional
loss proper headroom after warmup transition at epoch 5.

80-epoch results (RTX 3050, hidden=[64,64]):
  Best Sharpe: 9.08 at epoch 29
  Final Sharpe: 4.09 at epoch 80
  Grad norm: 0.696→0.716 (stable nonzero throughout)
  Q-values: 0.18→0.78 (growing, stable)
  Loss: 14.5→4.5 (converging)
  MaxDD: 3-17% range
  Trades: 42-74 per epoch

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-03-30 16:49:29 +02:00
parent bbf9de3ea1
commit ff79fa34f6

View File

@@ -305,10 +305,10 @@ fn test_50_epoch_convergence() -> anyhow::Result<()> {
let data_dir = test_data_dir()
.expect("FOXHUNT_TEST_DATA or test_data/ must exist");
let mut params = smoke_params();
params.epochs = 50;
params.epochs = 80;
params.early_stopping_enabled = false; // Run all epochs — we need the loss trajectory
params.gradient_collapse_patience = 50000; // Disable gradient collapse (readback is deferred, reports 0 per-step)
params.min_epochs_before_stopping = 50; // Must complete all 50 epochs
params.gradient_collapse_patience = 50000; // Disable gradient collapse detector
params.min_epochs_before_stopping = 80; // Must complete all 80 epochs
let mut trainer = smoke_trainer_with(params)?;
let rt = tokio::runtime::Builder::new_current_thread()
.enable_all()
@@ -317,7 +317,7 @@ fn test_50_epoch_convergence() -> anyhow::Result<()> {
Ok("skip".to_owned())
}))?;
assert!(metrics.epochs_trained >= 10, "Must complete at least 10 epochs, got {}", metrics.epochs_trained);
assert!(metrics.epochs_trained >= 50, "Must complete at least 50 epochs (C51 warmup at 5), got {}", metrics.epochs_trained);
// GPU trade stats: 50 epochs must produce meaningful trade count
let total_trades = metrics.additional_metrics.get("total_trades").copied().unwrap_or(0.0) as usize;