harden pipeline against dropped connections; publish fee-aware sharps

- get_json: catch OSError + http.client.HTTPException (RemoteDisconnected/
  IncompleteRead escaped the retry loop and killed last night's validate_timing
  run on a single dropped keep-alive).
- validate_timing: per-wallet retry+exclude guard so one bad wallet can't take
  out the whole selection; regenerated watch_sharps.json — the first fee-aware,
  resolved-only sharp list (10 copy-positive holders of 254).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
jaxperro
2026-07-02 09:15:42 -04:00
parent 0f6d308eec
commit 29a4bcca9e
3 changed files with 205 additions and 183 deletions
+18 -1
View File
@@ -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"]
+181 -181
View File
@@ -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
}
]
+6 -1
View File
@@ -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)