Files
foxhunt/config/training/dqn-smoketest.toml
jgrusewski 366832be44 refactor(data_source): default to mbp10 across smoke + localdev profiles
Smoke and localdev profiles previously used data_source = "ohlcv", divergent
from production (mbp10). Mismatch silently produced cache-key collisions in
the SHA256 hash path: smoke fxcache could not be loaded by production-shape
training without an explicit override. Local-dev fxcache regen also required
remembering to pass --data-source ohlcv to match.

Globalize mbp10 as the default everywhere it isn't deliberately overridden:
- config/training/dqn-smoketest.toml: data_source = "mbp10"
- config/training/dqn-localdev.toml: data_source = "mbp10"
- training_profile.rs: doc Default → "mbp10"
- trainers/dqn/config.rs: Default impl → "mbp10"
- hyperopt/adapters/dqn.rs: default → "mbp10"
- examples/precompute_features.rs: doc updated
- fxcache.rs / feature_cache.rs: discover_and_load + cache-key tests
  use "mbp10" arguments
- docs/dqn-wire-up-audit.md: new entry per Invariant 7

Documentation strings retained "ohlcv" only where they document the two
available choices (config.rs:946, training_profile.rs:83).

Local fxcache regenerated to v6 mbp10:
test_data/feature-cache/13c0b086a975cc7e2384377a2cd0e97738c9410292fcfecb5807c29bf885cb48.fxcache
(175874 bars, 55 MB, OFI_DIM=32). Stale v5 ohlcv fxcache untracked
from git index (already gitignored post-79578bbaf).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 22:35:47 +02:00

150 lines
4.9 KiB
TOML
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 Smoke Test Profile — f32 master weights + bf16 tensor core shadows
# gpu_n_episodes=auto × gpu_timesteps=100 (auto-scaled from VRAM)
# batch_size=64 fits in 4GB RTX 3050
#
# Mixed-precision (NVIDIA AMP pattern):
# - f32 master weights, Adam moments, gradients, loss accumulators
# - bf16 shadow copies for cuBLAS GemmEx tensor core GEMM
# - gradient_clip_norm=10000.0 (safety-only clip, raw gradient norms ~4000)
# - huber_delta=1.0 (keeps TD errors bounded for stable C51 transition)
# - q_clip ±50 (prevents logit explosion through bf16 forward)
[training]
epochs = 10
batch_size = 64
learning_rate = 1e-4
gamma = 0.95
weight_decay = 0.0001
adam_epsilon = 1e-8
warmup_steps = 0
hidden_dim_base = 64
reward_scale = 1.0
huber_delta = 1.0
symbol = "ES.FUT"
max_bars = 5000
data_source = "mbp10"
mbp10_data_dir = "test_data/futures-baseline-mbp10"
trades_data_dir = "test_data/futures-baseline-trades"
imbalance_bar_threshold = 1.0
imbalance_bar_ewma_alpha = 0.1
[distributional]
num_atoms = 52
# gamma=0.95 → Q_max = R/(1-gamma) = 20 for PopArt-normalized rewards.
# ±15 covers 75% of theoretical Q range — adequate for smoke test.
v_min = -15.0
v_max = 15.0
[exploration]
epsilon_start = 0.3
epsilon_end = 0.02
epsilon_decay = 0.85
noisy_sigma_init = 0.3
entropy_coefficient = 0.001
count_bonus_coefficient = 0.1
q_gap_threshold = 0.05
noise_sigma = 0.1
[replay_buffer]
buffer_size = 256
min_replay_size = 64
regime_replay_decay = 0.3
# Plan 3 Task 8 B.3: smoke override. Production default 100_000; smoke runs
# only ~200 samples per `collect_experiences_gpu` (4 episodes × 50 timesteps)
# × 5 epochs × 3 folds ≈ 3000 total. Setting to 1_000 lets the seed phase
# complete mid-fold so the seed→network transition is observable in the smoke
# (HEALTH_DIAG cql_alpha.eff visibly ramps from 0 toward config.cql_alpha).
replay_seed_steps = 1000
[early_stopping]
enabled = true
patience = 5
min_epochs_before_stopping = 10
[experience]
gpu_timesteps_per_episode = 50
gpu_n_episodes = 4
tx_cost_multiplier = 0.18 # IBKR ES: 0.18 bps = $4.50/contract RT
[experience.fill_simulation]
ioc_fill_prob = 0.85
limit_fill_min = 0.30
limit_fill_max = 0.80
spread_cost_frac = 0.50
spread_capture_frac = 0.50
[risk]
max_leverage = 5.0
max_position = 2.0 # legacy fallback; ignored when max_leverage is set and reference price is available
loss_aversion = 1.0
q_clip_min = -50.0
q_clip_max = 50.0
[advanced]
n_steps = 5
tau = 0.005
c51_warmup_epochs = 0
c51_alpha_max = 1.0
her_ratio = 0.2
cql_alpha = 0.1
curiosity_weight = 0.1
iqn_lambda = 0.25
spectral_norm_sigma_max = 1.5
spectral_decoupling_lambda = 0.01
gradient_clip_norm = 10000.0
[generalization]
# Toned-down generalization for tiny smoketest network [64,64]
# Full production uses aggressive defaults; smoketest needs gentler settings
# to avoid gradient collapse on small capacity networks.
anti_lr_good_mult = 1.1 # 1.1x — minimal destabilization for tiny network
anti_lr_bad_mult = 0.9 # 0.9x — minimal stabilization for tiny network
anti_lr_sharpe_threshold = 5.0 # Very high threshold — rarely triggers on smoketest
stochastic_depth_prob = 0.1 # 10% vs production 20% (less capacity loss)
feature_mask_fraction = 0.15 # 15% vs production 30% (more features visible)
feature_noise_scale = 0.05 # 0.05 vs production 0.1 (less noise)
asymmetric_dd_weight = 0.2 # 0.2 vs production 0.5 (less aggressive DD penalty)
trade_clustering_penalty = 0.02 # 0.02 vs production 0.05
ensemble_disagreement_penalty = 0.1 # 0.1 vs production 0.3
regret_blend = 0.15 # 0.15 vs production 0.3
time_reversal_mod = 10 # 10% reversed vs production 20%
causal_weight = 0.05 # Half of production
causal_intervention_interval = 50 # Less frequent than production (10)
bottleneck_dim = 16 # 16D bottleneck — 8× more market feature info for all branches
adversarial_warmup_epochs = 100 # Beyond smoketest duration (don't activate saboteur)
adversarial_checkpoint_interval = 100
pruning_epoch = 100 # Beyond 50-epoch test (don't prune tiny network)
pruning_fraction = 0.5 # Less aggressive (50% vs production 70%)
mixup_alpha = 0.2
# Core family intensity scalars for hyperopt (1.0 = neutral, range [0.0, 2.0])
learning_intensity = 1.0
exploration_intensity = 1.0
replay_intensity = 1.0
architecture_intensity = 1.0
risk_intensity = 1.0
# Generalization family intensity scalars for hyperopt (1.0 = neutral, range [0.0, 2.0])
adversarial_intensity = 1.0
regularization_intensity = 1.0
augmentation_intensity = 1.0
loss_shaping_intensity = 1.0
ensemble_intensity = 1.0
causal_intensity = 1.0
[reward]
# v8 comprehensive training overhaul
popart_enabled = true
micro_reward_scale = 0.0
td_lambda = 0.9
max_trace_length = 7
hindsight_fraction = 0.1
hindsight_lookahead = 10
loss_aversion = 1.0
q_gap_threshold = 0.1
w_dd = 1.0
dd_threshold = 0.02
cea_weight = 0.3
b3_size = 3
[walk_forward]
step_fraction = 0.25