- live/paper_trader.py: replaced random 5% fill probability in simulate_avellaneda()
with QueueAwareFillModel — fills only when aggressor volume exceeds depth ahead,
regime-adaptive quote placement (tight in LOW_VOL, wide in HIGH_VOL). Integrated
WQI Predictor and Funding Rate Arb as new strategies with signal generation.
Dashboard metrics now include WQI summaries, funding arb status, and fill model
throughput stats (fill rate, fills vs skips). 14 strategies total.
- scripts/kill_switch.py: emergency kill switch — flattens all positions, cancels
all open orders, verifies account is flat. Supports --dry-run, --mainnet, retry
logic, L1 action signing. Reads private key from HL_PRIVATE_KEY env or ~/.hl/key.
- infrastructure/systemd/: three service unit files for production deployment:
ftdt-collector (data collection), ftdt-paper (trading node v2), ftdt-dashboard
(FastAPI backend). Includes memory/cpu limits, auto-restart, log rotation.
321 tests passing.
Root cause: VWAP weighted the current price highest so dev≈0 always.
- Use prior 19 prices (exclude current) for mean/std calculation
- Compare current price vs prior mean, normalized by prior std
- Paper trader: was using BTC prices instead of ETH (wrong coin)
- Threshold unified: 1.0σ (was 1.5σ in paper, 1.0σ in live)
Backtests show BTC Mean Reversion: +76.42% PnL, 91% win, 22 trades.
Live node:
- Added Hurst VPIN to STRATEGIES (BTC, 0.00024 size, 00)
- Feed BTC price into dollar-bar Hurst/VPIN every 5 ticks
- Signal: BUY/SELL when H>0.55 + VPIN>0.25 + direction bias
Paper trader:
- Added Kalman Pairs, Avellaneda-Stoikov, Hurst VPIN strategies
- All 00 allocation, matching live node asset distribution
- Hurst/VPIN signal from BTC mid-price dollar bars
Strategy file: hurst_vpin_live.py (lightweight price-tick mode)
Live node:
- Registered in STRATEGIES dict (8th strategy)
- Signal: KalmanPairsTrader.step(eth, btc) every compute_signals()
- Adaptive hedge ratio updates with every tick
Paper trader:
- Registered in STRATEGIES dict
- Signal: KalmanPairsTrader integrated into compute_signals()
- Falls back gracefully if kalman_pairs module not importable
Historical backtests:
- Ran for BTC, ETH, HYPE, VVV (4 files)
- kalman_pairs_{TICKER}_*.json in results/historical/
- Visible on dashboard under Historical tab (8 strategies x 4 coins)
Dashboard: now shows Kalman Pairs card on all three tabs.
Risk panel now shows below strategy grid: VaR 95%, CVaR 95%, Max DD,
Calmar ratio, Sharpe, Sortino. Strategy correlation summary with
color-coded ρ values (red=high >0.7, amber=medium). Auto-refreshes
when paper data updates (throttled 30s). Collapsible with ▶ toggle.
backtests/historical_runner.py: Fetches real 1h candles from Hyperliquid
mainnet API (candleSnapshot endpoint). Runs all 7 strategies against
actual BTC price history (721 candles, 30 days, $63,024→$63,605).
Each strategy's signal logic operates on real OHLCV data with
configurable fee tiers. Saves to backtests/results/historical/.
Results on 30d BTC data at VIP0:
Mean Reversion: +93.87% net (Sharpe 0.94)
Order Book Imbalance: +54.31% net (Sharpe 1.03)
Avellaneda-Stoikov: -1.02% net (Sharpe -0.13)
Iceberg Detection: -33.20% net
Momentum Breakout: -54.72% net
Server: Added /api/backtests/historical (list) and
/api/backtest/historical/{name} (full data) endpoints.
Dashboard: Added "Historical" tab with "Real Data" badge. Cards show
coin + mainnet source. Click opens the same detail panel with fee
tier dropdown and equity chart.
Backtest detail: openDetail() now fetches full backtest JSON from the API
instead of showing "Full trade data not in summary". Renders equity curve
chart + full trade history table with 100 rows.
Backtest reproducibility: replaced hash(key) with fixed per-strategy seeds.
Python's hash() is randomized per process (PYTHONHASHSEED), causing wildly
different results for same strategy across runs. Now deterministic.
Server: added total_trades and sortino to /api/backtests summary response.
Paper trader: fixed Avellaneda-Stoikov simulate using TAKER_FEE instead of
MAKER_FEE. Lowered OBI signal threshold from 5bps to 1.5bps for flat markets.
Live node: added None-guard in get_mark_prices — Hyperliquid testnet API
sometimes returns null, crashing the node. Wrapped in try/except.
Paper trader now tracks individual equity history per strategy
(strategy_equity dict with deque per strategy). Metrics file
exports per-strategy data for dashboard rendering.
Dashboard paper chart upgraded to 7 overlaid area series:
- Each strategy gets its own colored curve (green, blue, purple, etc.)
- 300px height for better visibility of multiple lines
- Color palette distinguishes strategies at a glance
$100K total capital: $10K per strategy × 7 + $30K reserve.
Exeria Charts evaluated: excellent library (Benzinga award winner,
Canvas/WebGL, exchange connectors) but requires npm+bundler —
not suitable for single-file dashboard. Lightweight-charts
remains the right choice for our architecture.
Tab IDs now match JavaScript: tab-backtest instead of tab-bt.
Paper trading increased to $100,000 ($10K per strategy, $30K reserve).
Server default paper metrics updated to $100K.
New paper trading engine (live/paper_trader.py):
- Pulls real mainnet prices, orderbooks, funding rates every 2s
- Runs all 7 strategies in simulation without placing orders
- Simulates fills at market with realistic taker fees (0.05%) and slip (1bp)
- Avellaneda-Stoikov: simulates spread capture with 15%/tick fill probability
- Tracks virtual positions and PnL per strategy
- $5,000 capital ($1,000 per strategy, $1,000 reserve)
- Writes to /tmp/ftdt-paper-metrics.json
Dashboard updated with 3 tabs:
- Live Trading (Testnet) — real orders on testnet
- Paper Trading (Mainnet) — simulated fills on real mainnet data
- Backtesting — 30-day simulated results
Server.py: added /ws/paper WebSocket endpoint, paper_clients set,
paper metrics reader and broadcast loop.