Regime-switching Avellaneda-Stoikov + Advanced Strategies research doc

Implemented regime detection in paper trader:
- Rolling 30-tick volatility classifies market as LOW_VOL/NORMAL/HIGH_VOL
- A-S fill probability adapts: 25% (low vol), 15% (normal), 8% (high vol)
- HIGH_VOL with spreads >$30: skip trading (adverse selection protection)
- Regime shown on dashboard header with color-coded badge

Added docs/ADVANCED_STRATEGIES.md — comprehensive research covering:
  1. Deep Learning LOB Prediction (Transformers/TLOB)
  2. Latency Arbitrage in Fragmented Markets
  3. Hawkes Process OFI Modeling
  4. Cross-Chain MEV Arbitrage
  5. Institutional Capital Flow Arbitrage (ETF flows)
  6. Hybrid Transformer + Hawkes Fusion
  7. Implementation Roadmap (Phase 1-4)

All strategies referenced with papers from arXiv, SSRN, and empirical studies.
This commit is contained in:
ramseshk
2026-08-04 04:54:26 +00:00
parent ba29e12f60
commit acf3a556ec
3 changed files with 267 additions and 10 deletions
+58 -9
View File
@@ -88,6 +88,36 @@ btc_prices: deque = deque(maxlen=120)
eth_prices: deque = deque(maxlen=120)
funding_rates: deque = deque(maxlen=100)
# ═══════════════════════ Regime Detection ═══════════════════════
# Uses rolling volatility to classify market regime:
# LOW_VOL: quiet markets → tight spreads, aggressive size
# NORMAL: standard conditions → baseline parameters
# HIGH_VOL: turbulence → wide spreads, reduced size, cautious signals
current_regime = "NORMAL"
regime_confidence = 0.5
def detect_regime():
"""Classify market regime from rolling BTC price volatility."""
global current_regime, regime_confidence
if len(btc_prices) < 30:
return "NORMAL"
window = list(btc_prices)[-30:]
# Compute 30-tick log returns
returns = [math.log(window[i] / window[i-1]) for i in range(1, len(window))]
realized_vol = math.sqrt(sum(r**2 for r in returns) / len(returns))
# Annualize (30 ticks at ~1s each → 30s window, annualize to 1yr)
annual_vol = realized_vol * math.sqrt(365 * 24 * 60 * 60 / 30)
regime_confidence = min(0.95, max(0.2, annual_vol / 2.0))
if annual_vol < 0.15: # <15% annualized
return "LOW_VOL"
elif annual_vol > 0.60: # >60% annualized
return "HIGH_VOL"
return "NORMAL"
# ═══════════════════════ Mainnet Data ═══════════════════════
def get_mainnet_prices():
@@ -266,20 +296,35 @@ def simulate_fill(name: str, side: str, coin: str, price: float):
# ═══════════════════════ A-S Spread Capture ═══════════════════════
def simulate_avellaneda(btc_bid, btc_ask):
"""Avellaneda-Stoikov: simulate spread capture when orders are at best bid/ask."""
"""Avellaneda-Stoikov: regime-adaptive spread capture.
Regime-dependent behavior:
LOW_VOL → fill_prob=25%, tight margins (capture small spreads frequently)
NORMAL → fill_prob=15%, baseline
HIGH_VOL → fill_prob=8%, skip if spread too wide (adverse selection risk)
"""
cfg = STRATEGIES["Avellaneda-Stoikov"]
if btc_bid <= 0 or btc_ask <= 0:
return
# Each tick, there's a chance our quotes get hit
# On mainnet, this happens frequently. Simulate with probability.
if random.random() < 0.15: # 15% per tick = fill every ~7 seconds on average
# Our bid gets hit (we buy at bid, sell at ask later for profit)
regime = current_regime
spread = btc_ask - btc_bid
# Regime-dependent fill probability
if regime == "LOW_VOL":
fill_prob = 0.25
elif regime == "HIGH_VOL":
fill_prob = 0.08
# During high vol with wide spreads, avoid getting picked off
if spread > 30: # >$30 spread = dangerous
return
else:
fill_prob = 0.15
if random.random() < fill_prob:
if cfg["position"] <= 0:
# Buy at bid
bid_fill_price = btc_bid
else:
# Sell at ask (close position)
bid_fill_price = btc_ask
side = "BUY" if cfg["position"] <= 0 else "SELL"
@@ -342,6 +387,8 @@ def write_metrics():
"status": "running",
"btc_price": btc_prices[-1] if btc_prices else 0,
"eth_price": eth_prices[-1] if eth_prices else 0,
"regime": current_regime,
"regime_confidence": regime_confidence,
}
try:
with open(METRICS_FILE, "w") as f:
@@ -354,7 +401,7 @@ async def main():
log.info("="*60)
log.info(" FTDT Quant Lab — PAPER TRADING (Mainnet Data)")
log.info(f" Capital: ${STARTING_CAPITAL:,} | Reserve: ${RESERVE:,}")
log.info(f" 7 strategies × $1,000 allocation")
log.info(f" 7 strategies × ${STRATEGIES['Order Book Imbalance']['allocation']:,.0f} allocation")
log.info(f" Fees: {TAKER_FEE*100:.2f}% taker | Slippage: {SLIPPAGE_BPS} bps")
log.info(f" Data: Hyperliquid MAINNET")
log.info(f" Dashboard: https://ftdt.io/cv")
@@ -390,6 +437,7 @@ async def main():
# Compute signals every 5 ticks
if tick % 5 == 0:
current_regime = detect_regime()
compute_signals()
# Execute signals every 3-5 ticks
@@ -443,7 +491,8 @@ async def main():
btc_now = btc_prices[-1] if btc_prices else 0
log.info(
f"Tick {tick:4d} | BTC: ${btc_now:,.0f} | "
f"PnL: ${tp:+.2f} | Trades: {tr:3d} | Fees: ${tf:.2f}"
f"PnL: ${tp:+.2f} | Trades: {tr:3d} | Fees: ${tf:.2f} | "
f"Regime: {current_regime}"
)
await asyncio.sleep(1)