jgrusewski
01e5277e1c
fix(dqn): Fix 4 critical bugs + align hyperopt with production + implement HFT constraints
This commit addresses critical bugs discovered during Wave 11 DQN hyperopt campaign
and implements HFT-specific constraint logic to guide optimization toward active trading.
## Bug Fixes
### Bug 1: epsilon_greedy_action placeholder (ml/src/trainers/dqn.rs:1646)
**Symptom**: Greedy action selection always returned BUY (action 0)
**Cause**: Placeholder `Ok(0)` never replaced with argmax(Q-values)
**Fix**: Implemented proper Q-network forward pass + argmax selection
**Impact**: Greedy action selection now correctly selects action with highest Q-value
### Bug 2: Epsilon-greedy during evaluation (ml/src/trainers/dqn.rs:492-540)
**Symptom**: Validation metrics contaminated with 5-30% random exploration
**Cause**: compute_validation_loss used epsilon-greedy instead of pure greedy
**Fix**: Added set_epsilon(0.0) before validation, restore original epsilon after
**Impact**: Evaluation now uses deterministic policy (Q-value argmax only)
### Bug 3: Epsilon decay per-step (ml/src/dqn/dqn.rs:618)
**Symptom**: Epsilon collapsed to floor (0.05) after only 2.1% of training
**Cause**: update_epsilon() called every training step (21,750×) instead of per epoch (5×)
**Math**: ε = 0.3 × 0.995^21750 ≈ 0.000001 → clamped to 0.05 floor at step 460
**Expected**: ε = 0.3 × 0.995^5 = 0.292 after 5 epochs
**Fix**: Removed epsilon decay from train_step, moved to epoch loop in trainer
**Impact**: Restored proper exploration schedule, action diversity now healthy
### Bug 4: Hyperopt-production parameter misalignment
**Symptom**: Hyperopt results not transferable to production (7 parameters diverged)
**Cause**: Parameters drifted over multiple development waves
**Critical**: hold_penalty_weight 0.01 vs 2.0 (200× difference)
**Fix**: Aligned all parameters with production values:
- hold_penalty: -0.01 → -0.001 (production standard)
- hold_penalty_weight: 0.01 → 2.0 (user-discovered optimal)
- q_value_floor: 0.01 → 0.5 (early stopping threshold)
- gradient_clip_norm: dynamic → fixed 10.0 (Wave 11 Bug #1 fix)
- movement_threshold: optimized → fixed 0.02 (2% standard)
- epsilon_start: 1.0 → 0.3 (production standard)
- epsilon_decay: optimized → fixed 0.995 (production standard)
## HFT Constraint Logic (ml/src/hyperopt/adapters/dqn.rs)
**Motivation**: HFT trend-following requires active BUY/SELL decisions, not passive HOLD
### Parameter Space Changes
- **Before**: 4D (learning_rate, batch_size, gamma, buffer_size)
- **After**: 5D (added hold_penalty_weight: 0.5-5.0)
- **Removed**: movement_threshold (fixed 0.02), epsilon_decay (fixed 0.995)
### HFT Constraints (3 rules)
1. **Minimum penalty**: hold_penalty_weight ≥ 0.5 (force active trading)
2. **Training stability**: Low LR + very high penalty rejected (prevents instability)
3. **Buffer capacity**: Small buffer + high penalty rejected (prevents forgetting)
### Multi-Objective Enhancement
- **P&L**: 40% weight (primary objective)
- **HFT activity**: 30% weight (NEW - rewards BUY/SELL ratio, penalizes passive HOLD)
- **Stability**: 20% weight (low Q-value variance)
- **Completion**: 10% weight (early stopping penalty)
## Validation Results
**5-Epoch Test** (cargo run --release -p ml --example train_dqn --features cuda):
- Final epsilon: 0.2926 (matches expected 0.292)
- Action distribution: BUY 40%, SELL 10%, HOLD 50% (healthy diversity)
- Previous: 96.4% HOLD due to epsilon decay bug
- Q-values show continuous variation (argmax working correctly)
**Unit Tests**: 7/7 HFT constraint tests pass
## Files Modified
- ml/src/hyperopt/adapters/dqn.rs (268 lines changed)
- Added hold_penalty_weight to search space
- Implemented HFT constraints + enhanced multi-objective
- Aligned all production parameters
- Added 3 constraint unit tests
- ml/src/dqn/dqn.rs (12 lines changed)
- Removed epsilon decay from train_step
- Made update_epsilon public for trainer access
- Added set_epsilon method
- ml/src/trainers/dqn.rs (54 lines changed)
- Fixed epsilon_greedy_action argmax implementation
- Added epsilon=0 during evaluation
- Moved epsilon decay to epoch loop
- ml/examples/hyperopt_dqn_demo.rs (3 lines removed)
- Removed epsilon_decay from parameter display
- ml/src/benchmark/dqn_benchmark.rs (1 line changed)
- Aligned gradient_clip_norm with production (10.0)
## Breaking Changes
None - all changes internal to DQN hyperopt pipeline
## Next Steps
1. ✅ Validation complete (5-epoch test passed)
2. ⏳ Run hyperopt with HFT constraints (3-trial dry-run or 100-trial production)
3. ⏳ Deploy best parameters to production
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-06 22:31:00 +01:00
..
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-11-02 21:49:07 +01:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-25 15:36:57 +02:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-28 14:11:18 +01:00
2025-10-19 09:10:55 +02:00
2025-10-21 08:54:26 +02:00
2025-10-21 08:54:26 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-03 07:34:26 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-11-02 21:49:07 +01:00
2025-11-02 21:49:07 +01:00
2025-11-02 21:49:07 +01:00
2025-11-06 00:38:23 +01:00
2025-11-02 21:49:07 +01:00
2025-11-02 21:49:07 +01:00
2025-10-19 09:10:55 +02:00
2025-11-04 23:54:18 +01:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-11-06 22:31:00 +01:00
2025-10-31 00:20:00 +01:00
2025-11-02 21:49:07 +01:00
2025-11-02 11:12:14 +01:00
2025-11-02 11:12:14 +01:00
2025-10-19 09:10:55 +02:00
2025-11-02 21:49:07 +01:00
2025-11-02 21:49:07 +01:00
2025-10-14 10:42:56 +02:00
2025-11-06 00:38:23 +01:00
2025-10-19 09:10:55 +02:00
2025-10-28 14:11:18 +01:00
2025-10-28 14:11:18 +01:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-28 14:11:18 +01:00
2025-10-28 14:11:18 +01:00
2025-11-02 21:49:07 +01:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-22 20:50:43 +02:00
2025-10-22 20:50:43 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-11-06 00:38:23 +01:00
2025-10-19 09:10:55 +02:00
2025-11-04 23:54:18 +01:00
2025-10-19 09:10:55 +02:00
2025-10-28 14:11:18 +01:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-23 10:43:52 +02:00
2025-10-19 09:10:55 +02:00
2025-10-21 08:54:26 +02:00
2025-11-04 23:54:18 +01:00
2025-10-22 20:50:43 +02:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-11-02 21:49:07 +01:00
2025-11-04 23:54:18 +01:00
2025-11-06 01:17:53 +01:00
2025-10-19 09:10:55 +02:00
2025-10-29 19:52:21 +01:00
2025-10-29 19:52:21 +01:00
2025-10-28 14:11:18 +01:00
2025-11-02 21:49:07 +01:00
2025-10-19 09:10:55 +02:00
2025-11-02 11:12:14 +01:00
2025-10-26 11:14:33 +01:00
2025-10-21 21:13:11 +02:00
2025-10-26 20:58:49 +01:00
2025-10-21 21:13:11 +02:00
2025-10-21 21:13:11 +02:00
2025-10-19 09:10:55 +02:00
2025-11-04 23:54:18 +01:00
2025-10-21 08:54:26 +02:00
2025-10-20 21:54:39 +02:00
2025-10-19 09:10:55 +02:00
2025-10-21 08:54:26 +02:00
2025-10-19 09:10:55 +02:00
2025-11-06 00:38:23 +01:00
2025-10-28 16:11:01 +01:00
2025-11-02 21:49:07 +01:00
2025-11-02 21:49:07 +01:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-22 20:50:43 +02:00
2025-10-31 00:20:00 +01:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-29 19:52:21 +01:00
2025-10-22 20:50:43 +02:00
2025-10-19 09:10:55 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00
2025-10-19 09:10:55 +02:00
2025-10-19 09:10:55 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00
2025-10-20 21:54:39 +02:00