Commit Graph

12 Commits

Author SHA1 Message Date
Administrator
3cca2494f3 Merge branch 'feature/action-diversity-fix' into 'main'
fix(ml): resolve DQN action diversity collapse in hyperopt

See merge request root/foxhunt!1
2026-03-06 00:29:30 +00:00
jgrusewski
98694a0ca2 fix(ml): resolve DQN action diversity collapse in hyperopt
4 root causes of 45-action DQN collapsing to 1-6 actions:

1. Batch epsilon ignoring noisy_epsilon_floor: select_actions_batch()
   and select_actions_batch_gpu() used get_epsilon() which returns 0.0
   with noisy nets — zero random exploration in the training path.
   Added get_effective_epsilon() that respects noisy_epsilon_floor.

2. Entropy coefficient too weak: default 0.05 with bounds (0.01, 0.2)
   produced max ~0.19 bonus vs TD loss of 4+. Bumped default to 0.1,
   widened bounds to (0.05, 0.5) for effective anti-collapse.

3. count_bonus_coefficient not in search space: was hardcoded at 0.1
   in from_continuous(). Promoted to 31st search dimension with bounds
   (0.05, 1.0) so PSO/TPE can optimize exploration strength.

4. Diversity penalty too coarse: objective had <10 unique actions
   short-circuit but nothing for 10-20. Added graduated penalty that
   linearly ramps from 3.0 (10 actions) to 0.0 (20 actions).

Also fixes pre-existing clippy impl_trait_in_params in optimizer.rs.

2720 tests pass, 0 clippy warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 01:27:54 +01:00
jgrusewski
371598ecb5 fix(metrics): emit per-trial hyperopt metrics for Grafana panels
Wire record_hyperopt_trial_duration, set_hyperopt_best_objective,
set_hyperopt_trial_best_loss, and set_hyperopt_elapsed into all three
optimizer paths (PSO sequential, PSO parallel, TPE). These metrics were
registered but never called during the optimization loop, causing
"Best Objective Over Time", "Trial Duration", and "Elapsed Time"
Grafana panels to show "No data".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 00:57:48 +01:00
jgrusewski
f2938b19e8 fix(ml): improve TPE exploitation with Scott bandwidth, best-trial injection
- Replace Silverman's bandwidth (h = 1.06σn^(-1/5)) with Scott's rule
  (h = 0.7σn^(-1/(d+4))) for tighter kernels in high-D parameter spaces
- Add best-trial injection: always evaluate EI at best known point plus
  5 small perturbations (±5%), preventing optimizer from forgetting peaks
- Scale n_candidates dynamically: max(256, 8*n_dims) instead of fixed 100
- Reduce gamma from 0.25 to 0.15 when trials < 50 for tighter exploitation
- Wire model_name through PSO/TPE paths for per-trial Prometheus metrics

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 23:54:30 +01:00
jgrusewski
1bf752d387 fix(dqn,ppo): production inference hardening, remove legacy aliases
DQN: disable all exploration for production (warmup=0, epsilon=0,
noisy_nets=false, count_bonus=false), read feature_count from
checkpoint metadata instead of hardcoding 54, add loaded guard
and NaN check on predict output.

PPO: fix confidence formula — use act_with_log_prob() instead of
act() which returns value_estimate not log_prob, add loaded guard
and NaN check, remove WorkingPPO alias.

Liquid: add loaded flag for is_ready()/predict() guards.

Remove EgoboxOptimizer/EgoboxOptimizerBuilder backward-compat
aliases — replaced with canonical ArgminOptimizer everywhere.

323 trading_service tests, 200 hyperopt tests, 0 clippy warnings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 01:19:02 +01:00
jgrusewski
903e690e9a feat(hyperopt): wire TPE optimizer into pipeline with --optimizer flag
Add optimize_with_tpe() function that uses Tree-Parzen Estimator for
Bayesian hyperparameter optimization. Add --optimizer=tpe CLI flag
to hyperopt_baseline_rl binary (default: pso for backward compat).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 18:40:03 +01:00
jgrusewski
a7b7796147 fix(ml): correct PSO auto-scaling with empirical VRAM estimates
Split model overhead into two constants: MODEL_OVERHEAD_MB (pure
model weights for batch-size capping) and TRIAL_VRAM_MB (total
per-trial VRAM for concurrent hyperopt planning). DQN trials
empirically consume ~7 GB each on L40S (model + GPU replay buffer +
experience collector + CUDA allocations + fragmentation), not the
200 MB previously estimated. This caused plan_hyperopt to compute
128 concurrent trials instead of the actual 5, inflating PSO
particles from 20→128 and total trials from 20→384 via .max()
instead of .min(), guaranteeing a 4h timeout kill.

Fix auto-scaling to: (1) match particles to GPU concurrency for
maximum hardware utilization on any node, (2) cap particles at
max_trials to never inflate the trial budget, (3) never auto-inflate
the total trial count.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:34:05 +01:00
jgrusewski
5d3efbd2cc feat(hyperopt): auto-scale PSO particles to GPU capacity
Remove artificial swarm_size cap from plan_hyperopt() that limited
concurrent trials to n_particles (default 20). Now concurrency is
purely VRAM-driven with a hardware cap of 128 threads.

optimize_parallel() auto-scales n_particles to match GPU budget:
- L4 24GB: ~65 concurrent DQN trials (was 20)
- H100 80GB: 128 concurrent DQN trials (was 20)
- CPU/small GPU: falls back to configured n_particles

max_trials scales proportionally to ensure 3+ PSO iterations
for convergence with larger swarms.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:12:11 +01:00
jgrusewski
4cc15d4496 feat(hyperopt): VRAM-aware parallel trial concurrency with OOM protection
optimize_parallel() now uses HardwareBudget::plan_hyperopt() to compute
max concurrent trials based on model VRAM footprint. Includes ramp-up
(start at half concurrency), VRAM watchdog (check free memory before
spawning), and graceful degradation to sequential.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:44:39 +01:00
jgrusewski
de2169fbe4 feat(hyperopt): add HardwareBudget + continuous_bounds_for() to ParameterSpace trait
Add VRAM-aware batch size bounds infrastructure:
- HardwareBudget struct with detect(), cpu_only(), with_memory_mb() constructors
- max_batch_size() helper for per-model memory profile scaling
- continuous_bounds_for(budget) default method on ParameterSpace trait
- Default impl delegates to static continuous_bounds() (non-breaking)
- Updated 2 optimizer call sites to detect hardware and use dynamic bounds
- 6 new unit tests for HardwareBudget behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:03:56 +01:00
jgrusewski
8225950f06 feat(ml): parallel PSO hyperopt with IBKR cost defaults
Enable concurrent trial evaluation for DQN/PPO hyperparameter
optimization via clone-per-particle pattern — each PSO particle
clones the trainer and trains independently, replacing the previous
Arc<Mutex> serialization bottleneck. On L4 (8 vCPU) this yields
~4-5x throughput improvement.

Changes:
- DQNTrainer/PPOTrainer: Clone with Arc<AtomicUsize> trial counter
- DQNTrainer: replace unsafe mutable aliasing with Arc<Mutex> for
  best_trial tracking
- ArgminOptimizer: add optimize_parallel() with ParallelObjectiveFunction
  and scoped-thread LHS evaluation
- CLI: --parallel 0 (auto-detect CPUs-2), --initial-capital 35000,
  --tx-cost-bps 0.1 (IBKR ES all-in)
- CI: both hyperopt jobs use --parallel 0 + IBKR ES cost defaults

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 19:42:22 +01:00
jgrusewski
9c3d741a08 refactor: restructure repo — crates/, bin/, testing/ layout
Move 17 library crates into crates/, CLI binary into bin/fxt,
consolidate 10 test crates into testing/, split config crate
from deployment config files.

Root directory reduced from 38+ to ~17 directories.
All Cargo.toml paths and build.rs proto refs updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 11:56:00 +01:00