diff --git a/live/validate_timing.py b/live/validate_timing.py index 42125a53..acb3bf3b 100644 --- a/live/validate_timing.py +++ b/live/validate_timing.py @@ -192,14 +192,31 @@ MIN_LEAD_H = 1.0 # light sniper guard: drop wallets whose median winning le def main(): conv = json.load(open(os.path.join(HERE, "conviction_wallets.json"))) print(f"copy-testing {len(conv)} conviction wallets…\n", flush=True) + # run the full copy replay on EVERY conviction wallet (cheap now: fresh-positions # resolution, clob only fills gaps), then select on copyability — not lead time. + # Per-wallet guard: one wallet's unexpected error must not kill the whole + # selection run (a single RemoteDisconnected once took out the nightly refresh); + # a failed wallet is retried once, then excluded from this run and logged. + def safe_stats(c): + for attempt in (1, 2): + try: + return display_stats(c["wallet"]) + except Exception as e: + if attempt == 2: + print(f" ⚠ {c['wallet'][:10]}… stats failed ({e}) — excluded this run", + flush=True) + return None + time.sleep(2) + with ThreadPoolExecutor(max_workers=8) as ex: - stats = list(ex.map(lambda c: display_stats(c["wallet"]), conv)) + stats = list(ex.map(safe_stats, conv)) cut30 = time.time() - 30 * 86400 sharps = [] for c, ds in zip(conv, stats): + if ds is None: + continue c.update(ds) if ds.get("name"): c["name"] = ds["name"] diff --git a/live/watch_sharps.json b/live/watch_sharps.json index 8b9e8fc1..d79c5c47 100644 --- a/live/watch_sharps.json +++ b/live/watch_sharps.json @@ -10,54 +10,24 @@ "fwd_win": 76.9, "fwd_conv_roi": 0.089, "fwd_n": 134, - "conv_win": 78.0, - "conv_won": 309, - "conv_lost": 87, - "conv_pnl": 82347, - "conv30_win": 76.9, - "conv30_won": 103, - "conv30_lost": 31, - "conv30_pnl": 27199, - "realized_pnl": 10649, - "avg_bet": 1888, - "copy_pnl": 1366, - "held_pnl": 1366, - "held_won": 48, + "conv_win": 78.2, + "conv_won": 323, + "conv_lost": 90, + "conv_pnl": 87481, + "conv30_win": 76.7, + "conv30_won": 115, + "conv30_lost": 35, + "conv30_pnl": 30326, + "realized_pnl": 13959, + "avg_bet": 1899, + "copy_pnl": 1555, + "held_pnl": 1555, + "held_won": 51, "held_lost": 31, "sold": 0, - "last_trade": 1782841976, - "last_conv_bet": 1782790799, - "med_lead_h": 4.6 - }, - { - "wallet": "0x6e4976c274384ada57ae03b75e463585ad01f1af", - "name": "lox-frogs", - "train_win": 81.2, - "train_conv_roi": 0.112, - "train_z": 2.79, - "avg_entry": 0.67, - "train_n": 64, - "fwd_win": 68.6, - "fwd_conv_roi": 0.013, - "fwd_n": 306, - "conv_win": 70.8, - "conv_won": 262, - "conv_lost": 108, - "conv_pnl": 18110, - "conv30_win": 68.6, - "conv30_won": 210, - "conv30_lost": 96, - "conv30_pnl": 13418, - "realized_pnl": -433, - "avg_bet": 861, - "copy_pnl": 1333, - "held_pnl": 659, - "held_won": 9, - "held_lost": 6, - "sold": 31, - "last_trade": 1782841732, - "last_conv_bet": 1782841696, - "med_lead_h": 372.9 + "last_trade": 1782958745, + "last_conv_bet": 1782944155, + "med_lead_h": 2.8 }, { "wallet": "0xe8ca3f758c93f44f3ec210542ab78afb7c0bcccb", @@ -70,24 +40,24 @@ "fwd_win": 76.9, "fwd_conv_roi": 0.498, "fwd_n": 52, - "conv_win": 73.0, - "conv_won": 211, - "conv_lost": 78, - "conv_pnl": 110325, - "conv30_win": 76.9, - "conv30_won": 40, - "conv30_lost": 12, - "conv30_pnl": 26912, - "realized_pnl": 42702, - "avg_bet": 766, - "copy_pnl": 1256, - "held_pnl": 325, - "held_won": 9, + "conv_win": null, + "conv_won": 0, + "conv_lost": 0, + "conv_pnl": 0, + "conv30_win": null, + "conv30_won": 0, + "conv30_lost": 0, + "conv30_pnl": 0, + "realized_pnl": 0, + "avg_bet": 0, + "copy_pnl": 1158, + "held_pnl": 267, + "held_won": 8, "held_lost": 1, "sold": 29, - "last_trade": 1782842006, + "last_trade": 1782959222, "last_conv_bet": 1782765110, - "med_lead_h": 78.2 + "med_lead_h": null }, { "wallet": "0xec1d07e5379072429caa16bf6efeae71a6e4db17", @@ -97,27 +67,57 @@ "train_z": 2.5, "avg_entry": 0.68, "train_n": 153, - "fwd_win": 71.4, - "fwd_conv_roi": 0.087, - "fwd_n": 182, - "conv_win": 73.4, - "conv_won": 246, - "conv_lost": 89, - "conv_pnl": 183, - "conv30_win": 71.4, - "conv30_won": 130, - "conv30_lost": 52, + "fwd_win": 71.3, + "fwd_conv_roi": 0.094, + "fwd_n": 178, + "conv_win": 73.6, + "conv_won": 245, + "conv_lost": 88, + "conv_pnl": 192, + "conv30_win": 69.7, + "conv30_won": 108, + "conv30_lost": 47, "conv30_pnl": 83, - "realized_pnl": -118, - "avg_bet": 12, - "copy_pnl": 779, - "held_pnl": 850, - "held_won": 84, - "held_lost": 56, + "realized_pnl": -130, + "avg_bet": 11, + "copy_pnl": 708, + "held_pnl": 811, + "held_won": 87, + "held_lost": 58, "sold": 20, - "last_trade": 1782829033, + "last_trade": 1782997358, "last_conv_bet": 1782791450, - "med_lead_h": 5.4 + "med_lead_h": 5.1 + }, + { + "wallet": "0x4df332e27f9ee3224f52ce30e3ce15c1075e788f", + "name": "SunlineTicker", + "train_win": 66.2, + "train_conv_roi": 0.244, + "train_z": 3.67, + "avg_entry": 0.54, + "train_n": 222, + "fwd_win": 78.3, + "fwd_conv_roi": 0.347, + "fwd_n": 60, + "conv_win": 69.1, + "conv_won": 199, + "conv_lost": 89, + "conv_pnl": 559926, + "conv30_win": 78.7, + "conv30_won": 48, + "conv30_lost": 13, + "conv30_pnl": 142803, + "realized_pnl": 265268, + "avg_bet": 6540, + "copy_pnl": 538, + "held_pnl": 552, + "held_won": 53, + "held_lost": 34, + "sold": 1, + "last_trade": 1782995591, + "last_conv_bet": 1782983375, + "med_lead_h": 15.9 }, { "wallet": "0x5b6e9bce6d8a533017e7f16987c9854c5da955b9", @@ -130,24 +130,24 @@ "fwd_win": 73.8, "fwd_conv_roi": 0.28, "fwd_n": 61, - "conv_win": 76.3, - "conv_won": 167, - "conv_lost": 52, - "conv_pnl": 171, - "conv30_win": 73.8, - "conv30_won": 45, - "conv30_lost": 16, - "conv30_pnl": 50, - "realized_pnl": -42, + "conv_win": 76.9, + "conv_won": 170, + "conv_lost": 51, + "conv_pnl": 176, + "conv30_win": 74.6, + "conv30_won": 44, + "conv30_lost": 15, + "conv30_pnl": 57, + "realized_pnl": -31, "avg_bet": 4, - "copy_pnl": 361, - "held_pnl": 102, - "held_won": 24, - "held_lost": 7, - "sold": 47, - "last_trade": 1782826003, - "last_conv_bet": 1782799258, - "med_lead_h": 5.7 + "copy_pnl": 374, + "held_pnl": 207, + "held_won": 29, + "held_lost": 6, + "sold": 49, + "last_trade": 1782995111, + "last_conv_bet": 1782995111, + "med_lead_h": 4.1 }, { "wallet": "0x86c878cde72660ec52f5e6f0f0438b76de8fc867", @@ -157,27 +157,27 @@ "train_z": 2.85, "avg_entry": 0.71, "train_n": 280, - "fwd_win": 73.0, - "fwd_conv_roi": 0.16, - "fwd_n": 115, - "conv_win": 76.2, - "conv_won": 301, - "conv_lost": 94, - "conv_pnl": 102509, - "conv30_win": 73.0, - "conv30_won": 84, - "conv30_lost": 31, - "conv30_pnl": 52957, - "realized_pnl": 71664, - "avg_bet": 2840, - "copy_pnl": 345, - "held_pnl": 332, - "held_won": 55, + "fwd_win": 73.8, + "fwd_conv_roi": 0.202, + "fwd_n": 103, + "conv_win": 76.7, + "conv_won": 297, + "conv_lost": 90, + "conv_pnl": 117695, + "conv30_win": 75.2, + "conv30_won": 79, + "conv30_lost": 26, + "conv30_pnl": 73652, + "realized_pnl": 87841, + "avg_bet": 2812, + "copy_pnl": 317, + "held_pnl": 305, + "held_won": 58, "held_lost": 18, - "sold": 2, - "last_trade": 1782840779, - "last_conv_bet": 1782824398, - "med_lead_h": 157.9 + "sold": 3, + "last_trade": 1782990980, + "last_conv_bet": 1782911405, + "med_lead_h": 155.9 }, { "wallet": "0x1fb7053bb490c6ec05a78fe2ed383af48526fb66", @@ -187,27 +187,27 @@ "train_z": 2.9, "avg_entry": 0.6, "train_n": 123, - "fwd_win": 65.5, - "fwd_conv_roi": 0.188, - "fwd_n": 29, - "conv_win": 70.4, + "fwd_win": 64.3, + "fwd_conv_roi": 0.131, + "fwd_n": 28, + "conv_win": 69.5, "conv_won": 107, - "conv_lost": 45, - "conv_pnl": 50032, - "conv30_win": 65.5, + "conv_lost": 47, + "conv_pnl": 48472, + "conv30_win": 61.3, "conv30_won": 19, - "conv30_lost": 10, - "conv30_pnl": 9851, - "realized_pnl": 42208, - "avg_bet": 1493, - "copy_pnl": 250, - "held_pnl": 250, + "conv30_lost": 12, + "conv30_pnl": 8291, + "realized_pnl": 40250, + "avg_bet": 1484, + "copy_pnl": 236, + "held_pnl": 244, "held_won": 7, "held_lost": 2, "sold": 7, - "last_trade": 1782785681, - "last_conv_bet": 1782735847, - "med_lead_h": 156.9 + "last_trade": 1782935641, + "last_conv_bet": 1782935641, + "med_lead_h": 155.0 }, { "wallet": "0x9e00f6a0e927146bac5f2cb6c29a32d8dcb9be98", @@ -220,25 +220,55 @@ "fwd_win": 50.0, "fwd_conv_roi": 0.062, "fwd_n": 10, - "conv_win": 65.0, - "conv_won": 141, - "conv_lost": 76, - "conv_pnl": 126, - "conv30_win": 50.0, - "conv30_won": 5, - "conv30_lost": 5, - "conv30_pnl": 3, - "realized_pnl": 25, + "conv_win": 70.0, + "conv_won": 166, + "conv_lost": 71, + "conv_pnl": 190, + "conv30_win": 67.4, + "conv30_won": 29, + "conv30_lost": 14, + "conv30_pnl": 36, + "realized_pnl": 40, "avg_bet": 2, - "copy_pnl": 237, - "held_pnl": 199, - "held_won": 10, - "held_lost": 5, - "sold": 20, - "last_trade": 1782829808, - "last_conv_bet": 1782829670, + "copy_pnl": 184, + "held_pnl": 224, + "held_won": 15, + "held_lost": 9, + "sold": 24, + "last_trade": 1782985621, + "last_conv_bet": 1782983395, "med_lead_h": null }, + { + "wallet": "0x0b9de6c1744db3888814eb09372e12edfd30e80c", + "name": "TLouis", + "train_win": 78.6, + "train_conv_roi": 0.798, + "train_z": 2.5, + "avg_entry": 0.5, + "train_n": 14, + "fwd_win": 71.4, + "fwd_conv_roi": 0.492, + "fwd_n": 14, + "conv_win": 75.0, + "conv_won": 21, + "conv_lost": 7, + "conv_pnl": 243, + "conv30_win": 71.4, + "conv30_won": 10, + "conv30_lost": 4, + "conv30_pnl": 71, + "realized_pnl": 225, + "avg_bet": 21, + "copy_pnl": 105, + "held_pnl": 105, + "held_won": 6, + "held_lost": 3, + "sold": 0, + "last_trade": 1782819106, + "last_conv_bet": 1782819106, + "med_lead_h": 127.6 + }, { "wallet": "0x7895b2409fb77887aa1f0ab0950dc2fdeeaee806", "name": null, @@ -260,43 +290,13 @@ "conv30_pnl": -80, "realized_pnl": -207, "avg_bet": 25, - "copy_pnl": 72, - "held_pnl": 138, + "copy_pnl": 54, + "held_pnl": 132, "held_won": 6, "held_lost": 3, "sold": 8, "last_trade": 1782650584, "last_conv_bet": 1782650584, - "med_lead_h": 5.7 - }, - { - "wallet": "0xb8adbd9b70907cd22cf1ab84f5091d7920d10e38", - "name": "ghgddaa", - "train_win": 78.8, - "train_conv_roi": 0.165, - "train_z": 2.64, - "avg_entry": 0.69, - "train_n": 132, - "fwd_win": 83.6, - "fwd_conv_roi": 0.031, - "fwd_n": 110, - "conv_win": 81.0, - "conv_won": 196, - "conv_lost": 46, - "conv_pnl": 147, - "conv30_win": 83.6, - "conv30_won": 92, - "conv30_lost": 18, - "conv30_pnl": -796, - "realized_pnl": -388, - "avg_bet": 77, - "copy_pnl": 50, - "held_pnl": 59, - "held_won": 14, - "held_lost": 2, - "sold": 60, - "last_trade": 1782401996, - "last_conv_bet": 1782360503, - "med_lead_h": 6.1 + "med_lead_h": 3.9 } ] \ No newline at end of file diff --git a/smart_money.py b/smart_money.py index 3b065b2d..ce633795 100644 --- a/smart_money.py +++ b/smart_money.py @@ -9,6 +9,7 @@ Run a terminal scan: python3 smart_money.py --scan """ import argparse +import http.client import json import ssl import sys @@ -70,7 +71,11 @@ def get_json(path, params=None, retries=2): req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(req, timeout=15, context=SSL_CTX) as r: return json.loads(r.read().decode()) - except (urllib.error.URLError, TimeoutError, json.JSONDecodeError): + except (OSError, http.client.HTTPException, json.JSONDecodeError): + # OSError covers URLError/timeouts/connection-resets; HTTPException + # covers RemoteDisconnected/IncompleteRead — the latter used to escape + # the retry loop and crash whole pipeline runs (validate_timing died + # mid-scan on one dropped keep-alive connection). if attempt == retries: return None time.sleep(1 + attempt)