Major Changes: - Migrated from 3-action TradingAction to 45-action FactoredAction - 45 actions: 5 exposure × 3 order types × 3 urgency levels - Absolute exposure model (target positions -1.0 to +1.0) - Transaction cost differentiation (Market 0.15%, LimitMaker 0.05%, IoC 0.10%) - Fixed action diversity threshold (1.11% → 0.5% for 45-action space) Bug Fixes: - Bug #15: Incomplete FactoredAction integration (code existed but unused) - Bug #16: Runtime crash in action diversity checking (hardcoded 3-action match) Code Changes (13 files, ~464 lines): - ml/src/dqn/action_space.rs: Core FactoredAction + 4 helper methods - ml/src/trainers/dqn.rs: Action diversity refactored (3→45 dynamic) - ml/src/dqn/reward.rs: calculate_reward() signature updated - ml/src/dqn/portfolio_tracker.rs: execute_action() absolute exposure - ml/src/dqn/dqn.rs: WorkingDQN action selection migrated - ml/tests/*.rs: 9 test files updated with FactoredAction assertions Test Results: - 1-epoch smoke test: 100% action diversity (45/45 actions, 80.2s) - 10-epoch production: 87.8% readiness (79/90 scorecard, 14.0 min) - Loss convergence: 96.9% reduction (119K → 3.6K) - Action diversity: 100% → 44% (healthy specialization) - Checkpoint reliability: 12/12 files saved (100%) - DQN tests: 195/195 passing (100%) - ML baseline: 1,514/1,515 passing (99.93%) Production Status: ✅ CERTIFIED (87.8% readiness) Go/No-Go: ✅ GO FOR 100-EPOCH PRODUCTION TRAINING 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
66 lines
2.2 KiB
Bash
Executable File
66 lines
2.2 KiB
Bash
Executable File
#!/bin/bash
|
|
# Test script to verify DQN initialization is non-deterministic
|
|
# Runs 3 parallel training instances and extracts initial Q-values
|
|
|
|
set -e
|
|
|
|
echo "=== DQN Non-Deterministic Initialization Test ==="
|
|
echo "Starting 3 parallel training runs with 1 epoch each..."
|
|
echo ""
|
|
|
|
# Clean up old test outputs
|
|
rm -rf /tmp/init_test_* 2>/dev/null || true
|
|
|
|
# Run 3 training instances in parallel
|
|
cargo run --package ml --example train_dqn --release --features cuda -- \
|
|
--epochs 1 --output-dir /tmp/init_test_1 > /tmp/init_test_1.log 2>&1 &
|
|
PID1=$!
|
|
|
|
cargo run --package ml --example train_dqn --release --features cuda -- \
|
|
--epochs 1 --output-dir /tmp/init_test_2 > /tmp/init_test_2.log 2>&1 &
|
|
PID2=$!
|
|
|
|
cargo run --package ml --example train_dqn --release --features cuda -- \
|
|
--epochs 1 --output-dir /tmp/init_test_3 > /tmp/init_test_3.log 2>&1 &
|
|
PID3=$!
|
|
|
|
echo "Waiting for training runs to complete..."
|
|
echo " PID $PID1 (test 1)"
|
|
echo " PID $PID2 (test 2)"
|
|
echo " PID $PID3 (test 3)"
|
|
echo ""
|
|
|
|
wait $PID1 $PID2 $PID3
|
|
|
|
echo "All training runs completed. Extracting Q-values..."
|
|
echo ""
|
|
|
|
# Extract initial Q-values from logs
|
|
echo "=== Run 1 - Initial Q-Values ==="
|
|
grep -E "Step 0.*Q-values:" /tmp/init_test_1.log | head -1 || echo "No Q-values found in Run 1"
|
|
echo ""
|
|
|
|
echo "=== Run 2 - Initial Q-Values ==="
|
|
grep -E "Step 0.*Q-values:" /tmp/init_test_2.log | head -1 || echo "No Q-values found in Run 2"
|
|
echo ""
|
|
|
|
echo "=== Run 3 - Initial Q-Values ==="
|
|
grep -E "Step 0.*Q-values:" /tmp/init_test_3.log | head -1 || echo "No Q-values found in Run 3"
|
|
echo ""
|
|
|
|
# Extract entropy seeds
|
|
echo "=== Entropy Seeds Used ==="
|
|
echo "Run 1:"
|
|
grep "Device RNG seeded with entropy:" /tmp/init_test_1.log | head -1 || echo "No seed found"
|
|
echo "Run 2:"
|
|
grep "Device RNG seeded with entropy:" /tmp/init_test_2.log | head -1 || echo "No seed found"
|
|
echo "Run 3:"
|
|
grep "Device RNG seeded with entropy:" /tmp/init_test_3.log | head -1 || echo "No seed found"
|
|
echo ""
|
|
|
|
echo "=== Validation ==="
|
|
echo "SUCCESS: If the Q-values and seeds are DIFFERENT across runs, the fix is working!"
|
|
echo "FAILURE: If the Q-values are IDENTICAL across runs, the issue persists."
|
|
echo ""
|
|
echo "Logs saved to: /tmp/init_test_{1,2,3}.log"
|