Files
jaxperro 34d02956d8 Archive dead-end strategies; add FINDINGS.md write-up
Moved the 8 tested-and-failed strategy tools into archive/ (copytrade, backtest,
edge_research, lookback, table_77, lp_screener, lp_paper, xarb) with an
archive/README explaining each. Root now holds the keepers: insider.py (made
self-sufficient — dropped the copytrade load_json dependency) and smart_money.py
(data foundation). New FINDINGS.md is the honest scorecard: six systematic
public-data edges all efficient/illusory, the win-rate survivorship-bias
finding, and the one real signal (z-score improbability + funding clustering).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 13:09:56 -04:00

120 lines
3.9 KiB
Python

#!/usr/bin/env python3
"""240-day lookback on a short list of wallets, split into halves.
We selected these wallets on their last 120 days. The *older* half (240->120
days ago) is data that played no part in selection — so consistency there is
backward out-of-sample evidence the edge is real, not a lucky recent stretch.
"""
import statistics
import sys
import time
from collections import defaultdict
import smart_money as sm
WEEK = 7 * 86400
PAGES = 160 # generous for this focused 5-wallet run
def parse_end(end):
if not end:
return 0
end = end.replace("Z", "")
for fmt in ("%Y-%m-%dT%H:%M:%S", "%Y-%m-%d"):
try:
return time.mktime(time.strptime(end, fmt))
except ValueError:
continue
return 0
def resolved(wallet, cutoff):
now = time.time()
out = []
off = 0
while off < PAGES * 50:
page = sm.get_json("/closed-positions",
{"user": wallet, "limit": 50, "offset": off,
"sortBy": "TIMESTAMP", "sortDirection": "DESC"})
if not page:
break
for p in page:
if p.get("timestamp", 0) >= cutoff:
out.append({"ts": p["timestamp"], "pnl": p.get("realizedPnl", 0),
"stake": p.get("avgPrice", 0) * p.get("totalBought", 0)})
off += 50
if len(page) < 50 or page[-1].get("timestamp", 0) < cutoff:
break
off = 0
while off < PAGES * 50:
page = sm.get_json("/positions",
{"user": wallet, "limit": 50, "offset": off,
"sizeThreshold": 0.0})
if not page:
break
for p in page:
end = parse_end(p.get("endDate"))
if cutoff <= end < now:
out.append({"ts": end, "pnl": p.get("cashPnl", 0),
"stake": p.get("initialValue", 0)})
off += 50
if len(page) < 50:
break
return out
def stats(bets):
if not bets:
return None
by_week = defaultdict(lambda: [0.0, 0.0])
for b in bets:
wk = int(b["ts"] // WEEK)
by_week[wk][0] += b["pnl"]
by_week[wk][1] += b["stake"]
weeks = sorted(by_week)
wpnl = [by_week[w][0] for w in weeks]
wroi = [by_week[w][0] / by_week[w][1] if by_week[w][1] else 0 for w in weeks]
tot_pnl = sum(wpnl)
tot_stake = sum(by_week[w][1] for w in weeks)
gw = sum(p for p in wpnl if p > 0)
gl = abs(sum(p for p in wpnl if p < 0))
mean = statistics.mean(wroi)
std = statistics.pstdev(wroi) if len(wroi) > 1 else 0
return {
"weeks": len(weeks), "bets": len(bets),
"green": round(sum(1 for p in wpnl if p > 0) / len(weeks) * 100),
"pf": round(gw / gl, 2) if gl else 999,
"sharpe": round(mean / std, 2) if std else 0,
"roi": round(tot_pnl / tot_stake * 100, 1) if tot_stake else 0,
"pnl": round(tot_pnl),
}
def line(label, s):
if not s:
print(f" {label:<8} (no resolved bets in this period)")
return
print(f" {label:<8} {s['weeks']:>2}wk {s['bets']:>5}bets "
f"{s['green']:>3}%grn PF {s['pf']:>6} Sharpe {s['sharpe']:>5} "
f"ROI {s['roi']:>6}% ${s['pnl']:>12,}")
def main(wallets):
now = time.time()
mid = now - 120 * 86400
for name, w in wallets:
bets = resolved(w, now - 240 * 86400)
older = [b for b in bets if b["ts"] < mid] # 240->120d (not used to select)
recent = [b for b in bets if b["ts"] >= mid] # 120->0d (selection window)
print(f"\n{name} ({w[:16]}…)")
line("240d all", stats(bets))
line("older½", stats(older)) # out-of-sample
line("recent½", stats(recent)) # in-sample
if __name__ == "__main__":
# name, wallet — passed as alternating argv or hardcoded by caller
pairs = [(sys.argv[i], sys.argv[i + 1]) for i in range(1, len(sys.argv), 2)]
main(pairs)