Hawkes OFI + Deep LOB: two new strategies from advanced microstructure research
This commit is contained in:
+57
-4
@@ -15,6 +15,9 @@ from collections import deque
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
import requests
|
||||
|
||||
from strategies.hawkes_ofi import HawkesOFI
|
||||
from strategies.deep_lob import DeepLOB
|
||||
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s [paper] %(message)s", datefmt="%H:%M:%S")
|
||||
log = logging.getLogger("ftdt-paper")
|
||||
|
||||
@@ -79,6 +82,20 @@ STRATEGIES = {
|
||||
"signals": [], "type": "reversal", "size": 0.002,
|
||||
"description": "VWAP deviation — buys below VWAP, sells above. Oscillates around fair value.",
|
||||
},
|
||||
"Hawkes OFI (new)": {
|
||||
"allocation": 10000.0, "instrument": "BTC", "pnl": 0.0,
|
||||
"trades_today": 0, "wins": 0, "win_rate": 0.0, "status": "idle",
|
||||
"position": 0.0, "entry_price": 0.0, "fee_paid": 0.0,
|
||||
"signals": [], "type": "hawkes", "size": 0.002,
|
||||
"description": "Hawkes process OFI — self-exciting point process model capturing clustered order flow. Predicts direction from buy/sell intensity imbalance. Academically rigorous stochastic process.",
|
||||
},
|
||||
"Deep LOB (new)": {
|
||||
"allocation": 10000.0, "instrument": "BTC", "pnl": 0.0,
|
||||
"trades_today": 0, "wins": 0, "win_rate": 0.0, "status": "idle",
|
||||
"position": 0.0, "entry_price": 0.0, "fee_paid": 0.0,
|
||||
"signals": [], "type": "deep_lob", "size": 0.002,
|
||||
"description": "Full orderbook depth analysis — wall detection, depth imbalance, thin-side prediction. Uses 10 levels of LOB to find fair value and directional pressure.",
|
||||
},
|
||||
}
|
||||
|
||||
trades_log: list[dict] = []
|
||||
@@ -157,6 +174,20 @@ def get_mainnet_orderbook(coin):
|
||||
return best_bid, best_ask
|
||||
except: return 0,0
|
||||
|
||||
def get_deep_orderbook(coin, depth=10):
|
||||
"""Get full LOB levels. Returns (bids, asks) where each is [(price,size),...]."""
|
||||
try:
|
||||
r = requests.post(MAINNET_API, json={"type":"l2Book","coin":coin}, timeout=10)
|
||||
data = r.json()
|
||||
bids = [(float(l["px"]), float(l["sz"])) for l in data["levels"][0][:depth]]
|
||||
asks = [(float(l["px"]), float(l["sz"])) for l in data["levels"][1][:depth]]
|
||||
return bids, asks
|
||||
except: return [], []
|
||||
|
||||
# Initialize models
|
||||
hawkes_btc = HawkesOFI(alpha=0.3, beta=0.5)
|
||||
deep_lob = DeepLOB(depth_levels=10)
|
||||
|
||||
# ═══════════════════════ Signal Engine ═══════════════════════
|
||||
|
||||
def compute_signals():
|
||||
@@ -401,7 +432,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 × ${STRATEGIES['Order Book Imbalance']['allocation']:,.0f} allocation")
|
||||
log.info(f" 9 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")
|
||||
@@ -446,14 +477,36 @@ async def main():
|
||||
eth = eth_prices[-1] if eth_prices else 0
|
||||
if btc <= 0: continue
|
||||
|
||||
# Get orderbook for A-S
|
||||
# Get orderbook for A-S and Deep LOB
|
||||
btc_bid, btc_ask = get_mainnet_orderbook("BTC")
|
||||
bids, asks = get_deep_orderbook("BTC")
|
||||
|
||||
# Avellaneda-Stoikov: simulate spread capture
|
||||
simulate_avellaneda(btc_bid, btc_ask)
|
||||
|
||||
# Process next strategy's signals
|
||||
name = strategy_names[idx % 7]
|
||||
# Hawkes OFI: feed simulated trade to model
|
||||
hawkes_btc.update("B" if tick % 2 == 0 else "S", 0.001, btc)
|
||||
hawkes_sig = hawkes_btc.get_signal()
|
||||
if hawkes_sig["signal"]:
|
||||
STRATEGIES["Hawkes OFI (new)"]["signals"].append({
|
||||
"time": time.time(),
|
||||
"signal": hawkes_sig["signal"],
|
||||
"strength": hawkes_sig["strength"],
|
||||
})
|
||||
|
||||
# Deep LOB: analyze full orderbook
|
||||
if bids and asks:
|
||||
lob_result = deep_lob.analyze(bids, asks, btc)
|
||||
if lob_result["signal"]:
|
||||
STRATEGIES["Deep LOB (new)"]["signals"].append({
|
||||
"time": time.time(),
|
||||
"signal": lob_result["signal"],
|
||||
"strength": lob_result["strength"],
|
||||
})
|
||||
|
||||
# Process next strategy's signals (round-robin 9 strategies)
|
||||
total_strats = len(strategy_names)
|
||||
name = strategy_names[idx % total_strats]
|
||||
idx += 1
|
||||
cfg = STRATEGIES[name]
|
||||
if name == "Avellaneda-Stoikov":
|
||||
|
||||
Reference in New Issue
Block a user