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>
150 lines
4.9 KiB
TOML
150 lines
4.9 KiB
TOML
# 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
|