Bug #8 (CRITICAL): Fixed action selection frequency catastrophe - Root cause: execute_action called during training (522,713 orders/epoch) - Fix: Removed execute_action from experience collection loop (line 928-936) - Impact: 522,713 → 0 orders/epoch (100% reduction) - Transaction costs: $338K → $0 (eliminated) - Test suite: ml/tests/action_selection_frequency_test.rs (3/3 passing) P2-A: Configurable Initial Capital - CLI argument: --initial-capital (default: $100K, min: $1K) - Files modified: trainers/dqn.rs, train_dqn.rs, hyperopt adapter - Test suite: ml/tests/configurable_capital_test.rs (8/8 passing) - Supports: Small accounts ($10K), Standard ($100K), Institutional ($500K+) P2-B: Cash Reserve Requirement - CLI argument: --cash-reserve-percent (default: 0%, range: 0-100%) - Reserve enforcement: BUY trades only (SELL always allowed) - Dynamic reserve adjusts with portfolio value - Files modified: portfolio_tracker.rs (70 lines), trainers/dqn.rs, train_dqn.rs - Test suite: ml/tests/cash_reserve_requirement_test.rs (10/10 passing) Test Status: 21/21 core tests passing (P2-C deferred due to API mismatch) Wave 16S-V11 Agents: - Agent #1: Bug #8 investigation (transaction cost analysis) - Agent #2: P2-A implementation (configurable capital) - Agent #3: P2-B implementation + test fix (cash reserve) - Agent #4: Integration validation (certification report)
127 lines
3.9 KiB
Rust
127 lines
3.9 KiB
Rust
/// Wave 16M: Test log size reduction from 2.8MB → <1MB
|
|
///
|
|
/// Validates that 1-epoch training produces <100KB of INFO-level logs
|
|
/// (scaling to <1MB for 10 epochs).
|
|
///
|
|
/// **Test Strategy**:
|
|
/// 1. Run 1-epoch training with RUST_LOG=info
|
|
/// 2. Capture log output to file
|
|
/// 3. Verify file size <100KB (10x scaling → <1MB for 10 epochs)
|
|
/// 4. Verify essential metrics still visible (epoch summary, trading stats)
|
|
|
|
use std::fs::File;
|
|
use std::io::Write;
|
|
use std::process::Command;
|
|
|
|
#[test]
|
|
fn test_log_size_under_1mb() {
|
|
// Create temp log file
|
|
let log_file = "/tmp/test_log_size.log";
|
|
|
|
// Run 1-epoch training with INFO-level logging
|
|
let output = Command::new("cargo")
|
|
.args(&[
|
|
"run",
|
|
"-p",
|
|
"ml",
|
|
"--example",
|
|
"train_dqn",
|
|
"--release",
|
|
"--features",
|
|
"cuda",
|
|
"--",
|
|
"--epochs",
|
|
"1",
|
|
])
|
|
.env("RUST_LOG", "info")
|
|
.output()
|
|
.expect("Failed to run training");
|
|
|
|
// Write output to file
|
|
let mut file = File::create(log_file).expect("Failed to create log file");
|
|
file.write_all(&output.stdout).expect("Failed to write stdout");
|
|
file.write_all(&output.stderr).expect("Failed to write stderr");
|
|
|
|
// Check log size
|
|
let metadata = std::fs::metadata(log_file).expect("Failed to read log file");
|
|
let size_bytes = metadata.len();
|
|
let size_kb = size_bytes as f64 / 1_024.0;
|
|
let size_mb = size_bytes as f64 / 1_048_576.0;
|
|
|
|
println!("Log size: {:.2} KB ({:.3} MB)", size_kb, size_mb);
|
|
|
|
// 1 epoch should produce <100KB (10 epochs → <1MB)
|
|
assert!(
|
|
size_kb < 100.0,
|
|
"1-epoch log should be <100KB, got {:.2}KB ({:.3}MB). 10-epoch projection: {:.2}MB",
|
|
size_kb,
|
|
size_mb,
|
|
size_mb * 10.0
|
|
);
|
|
|
|
// Verify essential metrics are still present (INFO level)
|
|
let log_content = std::fs::read_to_string(log_file).expect("Failed to read log file");
|
|
|
|
// Essential metrics that MUST be visible at INFO level
|
|
assert!(
|
|
log_content.contains("Epoch 1/1"),
|
|
"Missing epoch summary in INFO logs"
|
|
);
|
|
assert!(
|
|
log_content.contains("train_loss=") || log_content.contains("Training Stats"),
|
|
"Missing training loss in INFO logs"
|
|
);
|
|
assert!(
|
|
log_content.contains("Trading Stats") || log_content.contains("P&L"),
|
|
"Missing trading stats in INFO logs"
|
|
);
|
|
assert!(
|
|
log_content.contains("Action diversity") || log_content.contains("diversity="),
|
|
"Missing action diversity in INFO logs"
|
|
);
|
|
|
|
println!("✅ Test passed: Log size {:.2}KB < 100KB target", size_kb);
|
|
println!("✅ Projected 10-epoch log size: {:.2}MB < 1MB target", size_mb * 10.0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_debug_logs_available() {
|
|
// Create temp log file
|
|
let log_file = "/tmp/test_log_debug.log";
|
|
|
|
// Run 1-epoch training with DEBUG-level logging
|
|
let output = Command::new("cargo")
|
|
.args(&[
|
|
"run",
|
|
"-p",
|
|
"ml",
|
|
"--example",
|
|
"train_dqn",
|
|
"--release",
|
|
"--features",
|
|
"cuda",
|
|
"--",
|
|
"--epochs",
|
|
"1",
|
|
])
|
|
.env("RUST_LOG", "debug")
|
|
.output()
|
|
.expect("Failed to run training");
|
|
|
|
// Write output to file
|
|
let mut file = File::create(log_file).expect("Failed to create log file");
|
|
file.write_all(&output.stdout).expect("Failed to write stdout");
|
|
file.write_all(&output.stderr).expect("Failed to write stderr");
|
|
|
|
// Verify DEBUG logs contain step-level details
|
|
let log_content = std::fs::read_to_string(log_file).expect("Failed to read log file");
|
|
|
|
// DEBUG-level details should be present
|
|
assert!(
|
|
log_content.contains("Q-values:") || log_content.contains("Diagnostics:"),
|
|
"Missing step-level diagnostics in DEBUG logs"
|
|
);
|
|
|
|
println!("✅ DEBUG logs contain step-level details");
|
|
}
|