Files
foxhunt/DQN_TEST_VALIDATION_REPORT.md
jgrusewski 8ce7c52586 fix(dqn): Update evaluation script feature dimension from 125 to 128
- Fixed feature dimension mismatch in evaluate_dqn_main_orchestrator.rs
- Updated all 5 occurrences: state_dim, input comments, feature vector type
- Aligned with Wave 16D training (128 features: 125 market + 3 portfolio)

Issue: Validation backtest reveals 100% HOLD action collapse - requires reward
system investigation and redesign per latest RL research.
2025-11-08 18:28:56 +01:00

308 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# DQN Test Suite Validation Report
**Date**: 2025-11-08
**Status**: ⚠️ FAILURES DETECTED - Production deployment BLOCKED
## Executive Summary
**Test Results**: 142/160 passed (88.8% pass rate) - **BELOW 100% REQUIREMENT**
- **17 failures** across 3 categories
- **1 ignored** (requires real DBN files + GPU)
- **Integration tests**: COMPILATION FAILED (13 errors, 4 warnings)
**Production Readiness**: ❌ **NOT READY** - Critical bugs in portfolio tracking, hyperopt constraints, and feature dimensions
---
## Detailed Failure Analysis
### Category A: Feature Dimension Mismatch (7 failures)
**Root Cause**: State dimension is **131** but code/tests expect **128**
**Failed Tests**:
1. `test_feature_vector_to_state` - Assertion: 131 vs expected 128
2. `test_batched_action_selection` - Shape mismatch [10,131] vs [128,256]
3. `test_batched_vs_sequential_action_selection_consistency` - Shape mismatch [5,131] vs [128,256]
4. `test_batch_size_mismatch_larger_than_configured` - Shape mismatch [64,131] vs [128,256]
5. `test_batch_size_mismatch_smaller_than_configured` - Shape mismatch [16,131] vs [128,256]
6. `test_single_sample_batch` - Shape mismatch [1,131] vs [128,256]
**Impact**: CRITICAL - All batched inference operations failing
**Required Fix**: Determine correct dimension (131 or 128) and update network architecture + tests
**Dimension Breakdown** (current implementation):
- `feature_vector_to_state()` creates state from 225-dim FeatureVector
- Extracts: 4 price features + 221 technical indicators (indices 4-224)
- Adds: 3 portfolio features
- **Total: 4 + 221 + 3 = 228** (NOT 131!)
- **Actual observed: 131** - suggests truncation somewhere
**Action Required**:
- Trace exact feature extraction path
- Verify Wave 16D changes (125 market + 3 portfolio = 128 claim)
- Update network input_dim to match actual state dimension
---
### Category B: Portfolio Reward Calculation (6 failures)
**Root Cause**: Reward function always returns -1 (HOLD penalty) regardless of P&L
**Failed Tests**:
1. `test_pnl_reward_nonzero` - Expected positive reward for profitable BUY, got -1
2. `test_pnl_calculation_accuracy` - Both 1% and 5% profit returned -1
3. `test_reward_function_receives_portfolio` - Expected positive reward when portfolio value increases, got -1
4. `test_integration_full_trade_cycle` - Portfolio value mismatch: 11100 vs expected 11200
5. `test_portfolio_features_populated` - Short position value: 10900 vs expected 11100 (200 point error)
6. `test_portfolio_tracking_sell_action` - Short position value: 10900 vs expected 11100
**Impact**: CRITICAL - P&L-based rewards completely broken, agent cannot learn profitable strategies
**Observable Symptoms**:
- All profitable trades returning HOLD penalty (-1) instead of positive reward
- Short position P&L calculation off by exactly 200 points (10% error)
- Portfolio value not updating correctly after trades
**Action Required**:
- Fix `calculate_reward()` to use actual portfolio P&L from PortfolioTracker
- Verify short position value calculation (entry_price vs current_price logic)
- Add integration test for reward → P&L correlation
---
### Category C: Hyperopt Constraint Logic (4 failures)
**Root Cause**: HFT validation logic inverted + parameter bounds mismatch
**Failed Tests**:
1. `test_dqn_params_bounds` - Batch size range (32, 230) vs expected (80, 220)
2. `test_hft_constraint_minimum_penalty` - Valid params rejected by HFT constraint
3. `test_hft_constraint_training_instability` - Invalid params accepted by HFT constraint
4. `test_hft_constraint_buffer_size` - Invalid params accepted by HFT constraint
5. `test_dqn_params_roundtrip` - Gamma precision loss during encode/decode
**Impact**: MODERATE - Hyperopt may accept invalid configurations or reject valid ones
**Batch Size Mismatch**:
- Wave 16I expanded range to 32-230 (GPU limit fix)
- Tests still expect old range 80-220
- **Resolution**: Update test expectations or revert to 80-220
**HFT Constraint Bugs**:
- `validate_for_hft_trendfollowing()` returns Ok when should return Err (and vice versa)
- Suggests boolean logic inversion or incorrect threshold comparisons
- 3 constraint rules failing: minimum penalty, training instability, buffer size
**Action Required**:
- Review `validate_for_hft_trendfollowing()` implementation line-by-line
- Update test expectations to match Wave 16I parameter ranges
- Fix gamma roundtrip precision (use epsilon comparison instead of exact equality)
---
### Category D: Integration Tests (COMPILATION FAILED)
**File**: `ml/tests/dqn_realistic_constraints_integration.rs`
**Errors** (13 compilation errors):
1. Missing field `warmup_steps` in `DQNHyperparameters` initializer (line 60)
2-13. Type mismatches: f32 vs f64 in slippage calculations (lines 331-361)
- `apply_slippage()` expects f64, `execute_action()` expects f32
- Multiple arithmetic operations between f32 and f64
**Warnings** (4):
- Unused imports: `TrainingMetrics`, `Decimal`, `TempDir`
- Unused mut: `trainer` variable
**Impact**: MODERATE - Integration tests cannot run, realistic constraint validation blocked
**Action Required**:
- Add `warmup_steps: 0` to DQNHyperparameters initialization
- Cast all prices to consistent type (either f32 or f64 throughout)
- Remove unused imports and mut annotation
---
## Test Coverage Analysis
**Unit Tests**: 160 total
- **Passed**: 142 (88.8%)
- **Failed**: 17 (10.6%)
- **Ignored**: 1 (0.6%)
**By Module**:
| Module | Passed | Failed | Rate |
|--------|--------|--------|------|
| dqn::agent | 10/10 | 0 | 100% |
| dqn::dqn | 8/8 | 0 | 100% |
| dqn::network | 5/5 | 0 | 100% |
| dqn::portfolio_tracker | 9/9 | 0 | 100% |
| dqn::reward | 4/4 | 0 | 100% |
| dqn::tests::portfolio_integration | 3/9 | 6 | 33% ❌ |
| trainers::dqn | 5/11 | 6 | 45% ❌ |
| hyperopt::adapters::dqn | 2/7 | 5 | 29% ❌ |
| benchmark::dqn_benchmark | 3/3 | 0 | 100% |
| integration::strategy_dqn_bridge | 5/5 | 0 | 100% |
**Critical Failures**:
- Portfolio integration tests: 67% failure rate (6/9 tests)
- Hyperopt adapter tests: 71% failure rate (5/7 tests)
- Trainer batch tests: 55% failure rate (6/11 tests)
---
## Risk Assessment
### CRITICAL Risks (Production Blockers)
1. **Portfolio Reward Broken**: Agent cannot learn - all profitable trades return -1
2. **Feature Dimension Mismatch**: Batched inference crashes - hyperopt will fail
3. **Short Position P&L**: 200 point calculation error - risk management failure
### HIGH Risks (Operational Issues)
4. **HFT Constraint Logic**: May accept unstable configurations or reject valid ones
5. **Integration Tests Broken**: Cannot validate realistic trading scenarios
### MODERATE Risks (Data Quality)
6. **Batch Size Range**: Tests expect 80-220, code uses 32-230 (documentation drift)
7. **Gamma Roundtrip**: Precision loss may cause hyperopt parameter drift
---
## Smoke Test Recommendation
**Status**: ⚠️ **SKIP SMOKE TESTS** - Critical unit test failures must be resolved first
**Rationale**:
- Feature dimension mismatch will cause immediate crashes in `train_dqn` example
- Portfolio reward bug means training will produce meaningless models
- 88.8% pass rate is below production threshold (95%+ required)
**Next Steps** (before smoke tests):
1. Fix feature dimension issue (expected ~1 hour)
2. Fix portfolio reward calculation (expected ~2 hours)
3. Fix HFT constraint validation (expected ~1 hour)
4. Re-run unit tests until 100% pass rate achieved
5. Fix integration test compilation errors (expected ~30 min)
6. THEN proceed to smoke tests
---
## Production Certification Status
**Current**: ❌ **FAILED** - 88.8% pass rate (below 95% threshold)
**Blockers**:
1. 17 unit test failures across 3 critical categories
2. Integration tests failing to compile
3. Portfolio reward calculation completely broken
4. Feature dimension mismatch (131 vs 128)
**Required for Certification**:
- [ ] 100% unit test pass rate (currently 88.8%)
- [ ] Integration tests compiling and passing
- [ ] Smoke test: 5-epoch training completes successfully
- [ ] Smoke test: 5-trial hyperopt completes without crashes
- [ ] Code review of all fixes
**Estimated Time to Fix**: 4-5 hours (3 categories + integration tests + re-validation)
---
## Comparison to CLAUDE.md Claims
**CLAUDE.md States**:
> DQN Production Certified (2025-11-05)
> - Test Results: DQN Tests: 147/147 passing (100%) ✅
> - Production Readiness: ✅ CERTIFIED
**Reality** (2025-11-08):
- **160 tests exist** (not 147)
- **142/160 passing** (88.8%, not 100%)
- **17 failures** in critical paths
- **Integration tests broken**
**Conclusion**: CLAUDE.md status is **OUT OF DATE** or reflects a previous state before recent code changes. Recommend updating CLAUDE.md to reflect actual status: ⚠️ **PRODUCTION CERTIFICATION REVOKED**
---
## Recommendations
### Immediate Actions (Priority 1)
1. **Fix Feature Dimension Bug** (1 hour)
- Trace actual state vector creation
- Determine if 128 or 131 is correct
- Update network architecture or feature extraction
2. **Fix Portfolio Reward Bug** (2 hours)
- Review `calculate_reward()` implementation
- Fix short position P&L calculation (200 point error)
- Ensure rewards correlate with portfolio value changes
3. **Fix HFT Constraint Logic** (1 hour)
- Review `validate_for_hft_trendfollowing()`
- Fix inverted validation logic
- Update batch size range expectations
### Medium Priority
4. **Fix Integration Tests** (30 min)
- Add `warmup_steps` field
- Standardize f32/f64 types
- Remove unused imports
5. **Update Test Suite** (1 hour)
- Add 13 missing tests to reach 160 total documented
- Update batch size range expectations
- Add epsilon comparison for gamma roundtrip
### Post-Fix Validation
6. **Re-run Full Test Suite** (10 min)
- Target: 160/160 passing (100%)
- Document any remaining issues
7. **Smoke Tests** (30 min)
- 5-epoch training
- 5-trial hyperopt
- Verify no crashes, reasonable metrics
8. **Update CLAUDE.md** (15 min)
- Reflect actual test count (160)
- Update production status
- Document fix wave (Wave 16J?)
**Total Estimated Effort**: 6-7 hours to production-ready state
---
## Appendix: Test Failure Details
### Feature Dimension Errors
```
Shape mismatch in matmul, lhs: [batch_size, 131], rhs: [128, 256]
Expected: state_dim=128 (125 market + 3 portfolio)
Actual: state_dim=131
Difference: +3 features (source unknown)
```
### Portfolio Reward Errors
```
Reward should be positive for profitable BUY trade, got -1
5% profit reward (-1) should be greater than 1% profit reward (-1)
Portfolio value: 11100.0 expected: 11200.0 (100 point shortfall)
Short position: 10900.0 expected: 11100.0 (200 point error)
```
### HFT Constraint Errors
```
Batch size range: (32.0, 230.0) expected: (80.0, 220.0)
assertion failed: params.validate_for_hft_trendfollowing().is_err() (was Ok)
assertion failed: params_valid.validate_for_hft_trendfollowing().is_ok() (was Err)
```
### Integration Test Errors
```
error[E0063]: missing field `warmup_steps` in initializer of `DQNHyperparameters`
error[E0308]: mismatched types - expected `f64`, found `f32` (×12 occurrences)
```
---
**Report Generated**: 2025-11-08
**Validator**: Claude Code Agent
**Next Review**: After fixes applied (target: 100% pass rate)