0857d40acd3ae9e56c60d4786473666ed5fe28b3
Real production bug surfaced by the R9 G3 local smoke (not the
test-fixture bug the prior commit's message claimed). The
`rl_per_alpha_controller` kernel hardcoded its bootstrap value to
`PER_ALPHA_BOOTSTRAP = 0.6` (canonical PER default per Schaul 2016).
The per-step path's target formula `target = 0.4 + 0.2 × (kurt − 3) / 7`
maps kurt=10 (the canonical heavy-tailed market kurtosis) to **exactly
0.6** — the bootstrap. The Wiener-α blend `(1 − α) · prev + α · target`
then produces 0.6 from any α when prev = target = 0.6, freezing the
controller at the bootstrap value for any input near the canonical
market regime.
This is a real production behaviour bug, not a test fixture bug:
in any market session where TD-error kurtosis sits near canonical 10
(which is the *most common* regime — that's WHY 0.6 is the canonical
PER default), the controller never adapts off bootstrap. The
adaptation mechanism is effectively disabled for typical inputs and
only fires when kurtosis drifts away. The prior commit
(ee24f0a30) papered over this with a fixture change (kurt=20 instead
of 10), which avoided the symptom without fixing the underlying
dead-zone.
## Fix: derive bootstrap from input (pearl-compliant)
Per `pearl_first_observation_bootstrap` ("sentinel = 0; first
observation replaces directly"), the canonical bootstrap pattern is
to compute the target from the current input and write that, rather
than a hardcoded constant. The kernel now:
1. Computes `target = target_formula(input_slot's EMA value)` first.
2. At sentinel (prev == 0): writes the computed target directly
(= 0.4 when input is also sentinel-zero, = 0.886 when input is
already at warm-start kurt=20, etc.).
3. Per-step path unchanged: Wiener blend prev toward target.
The bootstrap value is now whatever the formula emits for the
current input. At cold start (no EMA observations yet), bootstrap =
target(0) = 0.4 (= PER_ALPHA_MIN + 0.1, the formula's floor). This
is distinct from EVERY target value the formula can emit for
non-sentinel input (target ≥ 0.4), so the per-step Wiener blend
always sees a real `prev` vs `target` delta and moves on subsequent
calls — no dead-zone possible.
Trade-off: cold-start α is now 0.4 (slightly more uniform PER
sampling) instead of 0.6 (canonical sharp). For the first ~1-2 steps
before the input EMA stabilises, the PER buffer treats transitions
more equally. After EMA stabilises, the controller drifts toward the
canonical 0.6 (when kurt ≈ 10) or higher (when tails are heavier).
The brief cold-start period with α=0.4 is a cost worth paying for
guaranteed responsiveness post-warm-up.
## Test impact
* `tests/isv_bootstrap.rs` + `tests/r5_controllers_and_soft_update.rs`:
the `PER_ALPHA_BOOTSTRAP` Rust mirror constant updated from 0.6 →
0.4 with an inline comment explaining the post-R9-audit derivation
pattern. The hardcoded-0.6 const was the host-side reflection of
the buggy CUDA `#define`.
* `tests/r5_controllers_and_soft_update.rs`: the prior commit's
`td_kurtosis = 20.0` fixture-workaround REVERTED back to `10.0`.
With the kernel fix, kurt=10 is no longer a dead-zone — the
controller bootstraps to 0.4 and per-step blends to ≈ 0.48 toward
the target 0.6. Test passes WITHOUT relying on a hand-picked
fixture input that happened to dodge the bug.
* Trainer docstring at `with_controllers_bootstrapped`: per_α slot
doc updated to reflect derive-from-input bootstrap pattern.
## Verified gates (post-fix, local sm_86)
G1 isv_bootstrap ✅ per_α=0.4 (was 0.6 pre-fix)
G3 controllers_emit ✅ per_α 0.4 → 0.48 with kurt=10
G4 target_soft_update ✅ unchanged
G6 r7d_per_wiring ✅ unchanged
end integrated_trainer_smoke ✅ unchanged
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…
…
…
…
…
…
…
Foxhunt
Production HFT trading system in Rust.
Architecture
The workspace contains 32 crates organized as follows:
Core Libraries (16)
| Crate | Purpose |
|---|---|
trading_engine |
Order processing, FIX 4.4, IB TWS, SIMD, RDTSC timing |
risk |
VaR, Kelly, circuit breakers, kill switches, compliance |
risk-data |
Risk data types and shared structures |
trading-data |
Trading data types |
ml |
DQN Rainbow, PPO, TFT, Mamba2, ensemble inference |
ml-data |
ML data types and feature definitions |
data |
Market data ingestion and storage |
backtesting |
Replay engine, strategy tester |
adaptive-strategy |
Ensemble execution, microstructure analysis |
common |
Shared types, resilience, error handling |
storage |
S3 and local model storage |
model_loader |
Model serialization and loading |
market-data |
Market data feed handlers |
database |
PostgreSQL access layer (SQLx) |
config |
Configuration management |
tli |
CLI commands and tooling |
Services (8)
| Service | Purpose |
|---|---|
backtesting_service |
gRPC backtesting service |
broker_gateway_service |
FIX routing, broker connectivity |
trading_service |
Core trading operations |
ml_training_service |
Model training orchestration |
data_acquisition_service |
Market data acquisition |
trading_agent_service |
Autonomous trading agents |
api_gateway |
gRPC API gateway with auth |
web-gateway |
Axum REST + WebSocket gateway |
Frontend
web-dashboard/ -- React 19 + TypeScript + Vite + TradingView charts.
Building
# Check compilation (no PostgreSQL required)
SQLX_OFFLINE=true cargo check --workspace
# Run tests for a specific crate
SQLX_OFFLINE=true cargo test -p <crate> --lib
# Clippy
SQLX_OFFLINE=true cargo clippy --workspace
ML Models
Four production model architectures on Candle v0.9.1 with CUDA:
- DQN Rainbow -- Deep Q-Network with prioritized replay, dueling heads, noisy nets
- PPO -- Proximal Policy Optimization with GAE and LSTM policies
- TFT -- Temporal Fusion Transformer for multi-horizon forecasting
- Mamba2 -- State space model for sequence prediction
Each model has a standalone trainer and a UnifiedTrainable adapter for the hyperopt pipeline.
Infrastructure
- Git: Gitea at
git.fxhnt.ai(Tailscale-only), Scaleway DEV1-S - Observability: OpenTelemetry OTLP (env
OTEL_EXPORTER_OTLP_ENDPOINT) - Database: PostgreSQL with SQLx offline mode for CI
License
Proprietary. All rights reserved.
Description
Languages
Rust
88.2%
Cuda
7.7%
Python
1.3%
Shell
1.1%
PLpgSQL
0.8%
Other
0.8%