diff --git a/live/node.py b/live/node.py index df2953d..cfb82bb 100644 --- a/live/node.py +++ b/live/node.py @@ -31,15 +31,15 @@ RESERVE = 398.0 MAKER_FEE = 0.0002 STRATEGIES = { - "Order Book Imbalance": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000800,"fee_paid":0.0,"signals":[],"type":"reversal","description":"L2 bid/ask volume skew — buys when bids dominate, sells when asks dominate."}, - "Iceberg Detection": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000850,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Detects whale TWAP accumulation — follows smart money flow."}, - "Funding Rate Arb": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000900,"fee_paid":0.0,"signals":[],"type":"carry","description":"Delta-neutral carry — holds spot, shorts perp, collects funding."}, - "Pairs Trading": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.027500,"fee_paid":0.0,"signals":[],"type":"stat_arb","description":"BTC/ETH ratio Z-score — trades when spread exceeds 1.5σ."}, - "Avellaneda-Stoikov": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000950,"fee_paid":0.0,"signals":[],"type":"market_making","description":"Dual-sided quoting at best bid/ask — captures spread via stochastic control. Places both sides simultaneously."}, - "Momentum Breakout": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.020000,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Bollinger Band (1.2σ) breakout on ETH — enters when price breaks bands."}, - "Mean Reversion": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.022500,"fee_paid":0.0,"signals":[],"type":"reversal","description":"VWAP deviation on ETH — buys below VWAP, sells above. Higher vol = more reversion."}, - "Kalman Pairs": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.025000,"fee_paid":0.0,"signals":[],"type":"stat_arb","description":"Kalman-filter adaptive hedge ratio — tracks evolving BTC/ETH beta with every tick."}, - "Hurst VPIN": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.001000,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Hurst exponent regime filter + VPIN informed flow — enters when both align trending + high flow imbalance."} + "Order Book Imbalance": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000200,"fee_paid":0.0,"signals":[],"type":"reversal","description":"L2 bid/ask volume skew — buys when bids dominate, sells when asks dominate."}, + "Iceberg Detection": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000210,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Detects whale TWAP accumulation — follows smart money flow."}, + "Funding Rate Arb": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000220,"fee_paid":0.0,"signals":[],"type":"carry","description":"Delta-neutral carry — holds spot, shorts perp, collects funding."}, + "Pairs Trading": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.006,"fee_paid":0.0,"signals":[],"type":"stat_arb","description":"BTC/ETH ratio Z-score — trades when spread exceeds 1.5σ."}, + "Avellaneda-Stoikov": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000230,"fee_paid":0.0,"signals":[],"type":"market_making","description":"Dual-sided quoting at best bid/ask — captures spread via stochastic control. Places both sides simultaneously."}, + "Momentum Breakout": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.0005,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Bollinger Band (1.2σ) breakout on ETH — enters when price breaks bands."}, + "Mean Reversion": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.0005,"fee_paid":0.0,"signals":[],"type":"reversal","description":"VWAP deviation on ETH — buys below VWAP, sells above. Higher vol = more reversion."}, + "Kalman Pairs": {"allocation":100.0,"instrument":"ETH-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.005,"fee_paid":0.0,"signals":[],"type":"stat_arb","description":"Kalman-filter adaptive hedge ratio — tracks evolving BTC/ETH beta with every tick."}, + "Hurst VPIN": {"allocation":100.0,"instrument":"BTC-USD-PERP","pnl":0.0,"pnl_pct":0.0,"position":0.0,"trades_today":0,"wins":0,"win_rate":0.0,"status":"idle","size":0.000240,"fee_paid":0.0,"signals":[],"type":"momentum","description":"Hurst exponent regime filter + VPIN informed flow — enters when both align trending + high flow imbalance."} } trades_log: list[dict] = [] @@ -92,11 +92,39 @@ def get_orderbook(coin): return best_bid, best_ask, (best_bid+best_ask)/2 if best_bid and best_ask else 0 except: return 0,0,0 +# Module-level cache for open orders/positions (avoid 429 rate limit) +_cached_orders = [] +_cached_positions = [] +_last_metrics_fetch = 0.0 + def write_metrics(addr): + global _cached_orders, _cached_positions, _last_metrics_fetch total_pnl = sum(s["pnl"] for s in STRATEGIES.values()) total_pnl_pct = (total_pnl/TOTAL_EQUITY)*100 if TOTAL_EQUITY>0 else 0 for s in STRATEGIES.values(): if s["trades_today"]>0: s["win_rate"] = s["wins"]/s["trades_today"] + # Get real open orders and positions from Hyperliquid (cached 5s to avoid 429) + if time.time() - _last_metrics_fetch > 5: + try: + _cached_orders = requests.post(TESTNET_API, json={"type":"openOrders","user":addr}, timeout=5).json() or [] + _cached_positions = [] + ch = requests.post(TESTNET_API, json={"type":"clearinghouseState","user":addr}, timeout=5).json() + if ch and "assetPositions" in ch: + for a in ch["assetPositions"]: + pos = a.get("position", {}) + if pos and float(pos.get("szi", 0)) != 0: + _cached_positions.append({ + "coin": pos.get("coin", "?"), + "size": float(pos.get("szi", 0)), + "entry_px": float(pos.get("entryPx", 0)), + "pnl": float(pos.get("unrealizedPnl", 0)), + }) + _last_metrics_fetch = time.time() + except Exception: + pass + live_orders = _cached_orders + live_positions = _cached_positions + data = { "timestamp":time.time(),"wallet":addr, "total_equity":TOTAL_EQUITY+total_pnl,"base_equity":TOTAL_EQUITY, @@ -104,7 +132,7 @@ def write_metrics(addr): "reserve":RESERVE,"equity_history":equity_history[-600:], "strategies":STRATEGIES,"trades":trades_log[-200:],"status":"running","testnet_up":True, "strategy_equity":{k: v[-600:] for k,v in strategy_equity.items()}, - "open_positions":[],"open_orders":[] + "open_positions":live_positions,"open_orders":live_orders } try: with open(METRICS_FILE,"w") as f: json.dump(data,f,default=str) @@ -184,15 +212,15 @@ def compute_signals(): elif eth_cur < sma-1.2*std: STRATEGIES["Momentum Breakout"]["signals"].append({"time":time.time(),"signal":"SELL","strength":(sma-1.2*std-eth_cur)/std}) # Mean Reversion: VWAP on ETH (exclude current price from VWAP) - if len(eth_prices)>=60: - w = list(eth_prices)[-60:]; eth_mr = eth_prices[-1] - # SMA deviation on prior 59 prices (60s window captures real mean reversion) + if len(eth_prices)>=20: + w = list(eth_prices)[-20:]; eth_mr = eth_prices[-1] + # VWAP on prior 19 prices, equal volume weights prior = w[:-1] sma = sum(prior)/len(prior) vstd = math.sqrt(sum((p-sma)**2 for p in prior)/len(prior)) dev = (eth_mr-sma)/vstd if vstd>0 else 0 - if dev>0.5: STRATEGIES["Mean Reversion"]["signals"].append({"time":time.time(),"signal":"SELL","strength":dev}) - elif dev<-0.5: STRATEGIES["Mean Reversion"]["signals"].append({"time":time.time(),"signal":"BUY","strength":abs(dev)}) + if dev>1.0: STRATEGIES["Mean Reversion"]["signals"].append({"time":time.time(),"signal":"SELL","strength":dev}) + elif dev<-1.0: STRATEGIES["Mean Reversion"]["signals"].append({"time":time.time(),"signal":"BUY","strength":abs(dev)}) # Hurst/VPIN: feed BTC price into dollar bars if len(btc_prices)>=3: @@ -284,7 +312,7 @@ async def main(): log.info("="*60) # Cancel stale - open_ords = requests.post(TESTNET_API, json={"type":"openOrders","user":addr}, timeout=10).json() + open_ords = requests.post(TESTNET_API, json={"type":"openOrders","user":addr}, timeout=10).json() or [] for o in open_ords: try: iid = InstrumentId.from_str(f"{o['coin']}-USD-PERP.HYPERLIQUID") @@ -537,7 +565,7 @@ async def main(): log.info("Stopping...") # Cancel all - open_ords = requests.post(TESTNET_API, json={"type":"openOrders","user":addr}, timeout=10).json() + open_ords = requests.post(TESTNET_API, json={"type":"openOrders","user":addr}, timeout=10).json() or [] for o in open_ords: try: iid=InstrumentId.from_str(f"{o['coin']}-USD-PERP.HYPERLIQUID")