live: train/test wallet-selection study + capital-constrained copy sims

strategy.py (train pre-May-30 / test June1+ on copy-ROI + z + consistency +
diversification) and followability.py (entry-time/lead-time/cadence filter)
surface wallets with real, copyable, out-of-sample edge (49/77 profitable
forward, p=0.011, +23.4% pooled).

pnl_basket.py / pnl_focused.py add $1000 capital-constrained copy sims with
missed-trade accounting: the broad basket loses (can't follow 1,200 trades on
$1k), but 1-2 wallets + a conviction (bet-size) filter clears out-of-sample.
cache.py gains entry-time caching. Findings documented.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
jaxperro
2026-06-18 16:38:41 -06:00
parent 3d0bc7f001
commit 0c7d97c5d0
9 changed files with 2866 additions and 0 deletions
+23
View File
@@ -142,6 +142,29 @@ misleading signal on the platform; favorite-riders are uncopyable.* The
underdog/`value` archetype (beats longshot prices) is the only one left worth
testing.
## Train/test wallet selection, and the capital wall (June 2026)
Built `live/strategy.py` (train on bets resolved before May 30, validate June 1+)
and `live/followability.py` (entry-time + lead-time + cadence filter). Selecting
on **copy-ROI + z + monthly consistency + diversification** (not win rate) gave
150 wallets; **59/100 stayed profitable forward** (p=0.044), and filtering to
*followable* markets lifted it to **49/77 (p=0.011), +23.4% pooled** out-of-
sample. So a real, persistent, copyable edge **does** exist — unlike favorites.
Then the reality check (`live/pnl_basket.py`, `live/pnl_focused.py`): a $1,000
copier with **missed-trade accounting** (capital tied in open positions).
- **Broad 10-wallet basket:** the wallets fire **1,210 markets** in June; $1,000
can follow only ~213% of them. At realistic stakes it **loses** ($384 to
$800); the gains sit in the trades you couldn't afford ($14k$153k "missed").
**Capital, not edge, is the binding constraint.**
- **Focused + conviction:** copy only 12 top wallets and only their larger-stake
(≥$200) bets → trade count drops to ~3040, $1,000 affords them all, and it
**clears: +91% to +247% across stakes, stable, no blowup.**
*Lesson: a small-bankroll copier cannot follow a skilled wallet's whole feed —
the edge is only capturable by concentrating on few wallets' high-conviction
bets. The live tracker (jaxperro.com/trading) now runs exactly that config.*
## Repo layout
- `insider.py` — the detector: z-score/p-value, timing/freshness/sizing signals,
+12
View File
@@ -62,6 +62,18 @@ turn into losers out-of-sample. **Don't copy favorite-riders.** The `value`
archetype (beats underdog prices) is where real alpha may live — test it with
`backtest_june.py value`.
## Strategy backtests
- `strategy.py` — train (pre-May-30) / test (June1+) wallet selection on copy-ROI
+ z + monthly consistency + diversification. → `selection.json`.
- `followability.py` — pull entry timestamps (cached), drop wallets whose edge is
in un-followable fast/live markets, re-rank on followable forward bets. →
`watch_final.json` (the execution-realistic list).
- `pnl_basket.py` / `pnl_focused.py` — $1,000 capital-constrained copy sims with
**missed-trade accounting**. Key result: the broad basket loses on $1k (can't
follow 1,200 trades), but **12 wallets + a conviction (bet-size) filter clears**
out-of-sample. See `../FINDINGS.md`.
## Daily (`daily.sh`)
1. discover (enumerate last 14d) → 2. freshen cache (force-refresh watchlist +
+25
View File
@@ -33,6 +33,31 @@ _con.execute("""CREATE TABLE IF NOT EXISTS bets(
wallet TEXT, cond TEXT, won BOOLEAN, p DOUBLE, res_t BIGINT, size DOUBLE)""")
_con.execute("CREATE INDEX IF NOT EXISTS bets_w ON bets(wallet)")
_con.execute("CREATE TABLE IF NOT EXISTS pulled(wallet TEXT PRIMARY KEY, pulled_at BIGINT)")
_con.execute("CREATE TABLE IF NOT EXISTS entries(wallet TEXT, cond TEXT, first_buy BIGINT)")
_con.execute("CREATE INDEX IF NOT EXISTS entries_w ON entries(wallet)")
_con.execute("CREATE TABLE IF NOT EXISTS pulled_entries(wallet TEXT PRIMARY KEY, pulled_at BIGINT)")
def get_entries(wallet):
"""{conditionId: earliest BUY timestamp} for a wallet — cached. Lets us
compute entry->resolution lead time and trade cadence (followability)."""
now = time.time()
with _lock:
r = _con.execute("SELECT pulled_at FROM pulled_entries WHERE wallet=?", [wallet]).fetchone()
if r and now - r[0] < MAX_AGE_DAYS * 86400:
rows = _con.execute("SELECT cond,first_buy FROM entries WHERE wallet=?", [wallet]).fetchall()
return {c: t for c, t in rows}
try:
first_buy, _ = insider.entry_times(wallet)
except Exception:
first_buy = {}
with _lock:
_con.execute("DELETE FROM entries WHERE wallet=?", [wallet])
if first_buy:
_con.executemany("INSERT INTO entries(wallet,cond,first_buy) VALUES (?,?,?)",
[(wallet, c, t) for c, t in first_buy.items()])
_con.execute("INSERT OR REPLACE INTO pulled_entries VALUES (?,?)", [wallet, int(now)])
return first_buy
def get_bets(wallet):
+126
View File
@@ -0,0 +1,126 @@
#!/usr/bin/env python3
"""Execution-realistic re-ranking of the selected wallets.
Pulls entry timestamps (cached) for the strategy.py shortlist, then judges each
wallet on whether we could actually FOLLOW it with $1,000:
* lead time = resolution - entry. Bets that resolve within MIN_LEAD_H of the
wallet's entry (live/in-game/instant markets) are NOT copyable — you can't
see and mirror the trade in time. We drop them.
* cadence = distinct markets entered per active day. Extreme cadence = a bot
we can't hand-follow.
Then it recomputes forward (June1+, resolved) copy-ROI on ONLY the followable
bets — the realistic number — and re-ranks. Output: watch_final.json.
python3 followability.py
"""
import json
import os
import statistics as st
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
import cache
HERE = os.path.dirname(__file__)
TEST_START = time.mktime(time.strptime(os.environ.get("TEST_START", "2026-06-01"), "%Y-%m-%d"))
MIN_LEAD_H = 1.0 # a bet must resolve >= 1h after entry to be followable
MED_LEAD_MIN = 2.0 # wallet's median lead must clear this to qualify
MAX_CADENCE = 50.0 # entries/day above this = bot-like, hard to follow
MIN_FOLL_FRAC = 0.5 # >= half the wallet's bets must be followable
MIN_FWD_FOLL = 5 # need this many followable forward bets to rank
def ret(p, won):
return (1 - p) / p if won else -1.0
def assess(wallet):
ent = cache.get_entries(wallet) # {cond: first_buy_ts}
bets = cache.get_bets(wallet) # cached
leads = []
for b in bets:
e = ent.get(b["cond"])
if e and b.get("res_t"):
lh = (b["res_t"] - e) / 3600.0
if lh >= 0:
leads.append((b, lh))
if not leads:
return None
med_lead = st.median([lh for _, lh in leads])
foll_frac = sum(1 for _, lh in leads if lh >= MIN_LEAD_H) / len(leads)
ts = sorted(ent.values())
span = max(1.0, (ts[-1] - ts[0]) / 86400) if len(ts) > 1 else 1.0
cadence = len(ent) / span
# forward, followable only
fwd_foll = [b for b, lh in leads if b["res_t"] >= TEST_START and lh >= MIN_LEAD_H]
fwd_all = [b for b, lh in leads if b["res_t"] >= TEST_START]
foll_roi = (sum(ret(b["p"], b["won"]) for b in fwd_foll) / len(fwd_foll)
if fwd_foll else None)
raw_roi = (sum(ret(b["p"], b["won"]) for b in fwd_all) / len(fwd_all)
if fwd_all else None)
wins = sum(1 for b in fwd_foll if b["won"])
return dict(wallet=wallet, med_lead=med_lead, foll_frac=foll_frac, cadence=cadence,
fwd_foll_n=len(fwd_foll), foll_roi=foll_roi, raw_roi=raw_roi,
fwd_win=100 * wins / len(fwd_foll) if fwd_foll else 0)
def main():
sel = json.load(open(os.path.join(HERE, "selection.json")))
wallets = [c["wallet"] for c in sel]
meta = {c["wallet"]: c for c in sel}
print(f"assessing followability of {len(wallets)} selected wallets "
f"(entry-time pull, cached)…\n", flush=True)
rows, done = [], 0
with ThreadPoolExecutor(max_workers=10) as ex:
for r in ex.map(assess, wallets):
done += 1
if r:
rows.append(r)
if done % 30 == 0:
print(f" {done}/{len(wallets)}", flush=True)
# followability gates
foll = [r for r in rows if
r["med_lead"] >= MED_LEAD_MIN and
r["foll_frac"] >= MIN_FOLL_FRAC and
r["cadence"] <= MAX_CADENCE]
ranked = [r for r in foll if r["fwd_foll_n"] >= MIN_FWD_FOLL]
ranked.sort(key=lambda r: r["foll_roi"], reverse=True)
dropped = len(rows) - len(foll)
print(f"\n{len(rows)} assessed · {dropped} dropped as un-followable "
f"(fast/live markets or bot cadence) · {len(foll)} copyable\n")
if ranked:
pooled_num = sum(r["foll_roi"] * r["fwd_foll_n"] for r in ranked)
pooled_den = sum(r["fwd_foll_n"] for r in ranked)
pos = sum(1 for r in ranked if r["foll_roi"] > 0)
print(f"FOLLOWABLE forward verdict ({len(ranked)} wallets w/ >= {MIN_FWD_FOLL} "
f"followable June+ bets):")
print(f" {pos}/{len(ranked)} profitable · pooled followable copy-ROI "
f"{pooled_num/pooled_den:+.1%} · median {st.median([r['foll_roi'] for r in ranked]):+.1%}\n")
h = (f"{'foll_roi':>9}{'raw_roi':>8}{'medLeadH':>9}{'foll%':>6}{'cad/d':>7}"
f"{'fwd_n':>6}{'tr_z':>6} wallet")
print(h); print("-" * len(h))
for r in ranked[:40]:
m = meta[r["wallet"]]
raw = f"{r['raw_roi']:+.0%}" if r["raw_roi"] is not None else ""
print(f"{r['foll_roi']:>+8.0%}{raw:>8}{r['med_lead']:>8.1f}h{r['foll_frac']*100:>5.0f}%"
f"{r['cadence']:>7.1f}{r['fwd_foll_n']:>6}{m['train_z']:>6.1f} {r['wallet']}")
out = [{"wallet": r["wallet"], "name": r["wallet"][:10],
"foll_fwd_copy_roi": round(r["foll_roi"], 4),
"med_lead_h": round(r["med_lead"], 1), "cadence_per_day": round(r["cadence"], 1),
"followable_frac": round(r["foll_frac"], 2), "fwd_followable_n": r["fwd_foll_n"],
"train_z": meta[r["wallet"]]["train_z"],
"train_copy_roi": meta[r["wallet"]]["train_copy_roi"]} for r in ranked]
json.dump(out, open(os.path.join(HERE, "watch_final.json"), "w"), indent=2)
print(f"\n-> watch_final.json ({len(out)} execution-realistic wallets)")
if __name__ == "__main__":
main()
+101
View File
@@ -0,0 +1,101 @@
#!/usr/bin/env python3
"""Capital-constrained copy backtest of the 10-wallet basket, June 1 -> now.
$1,000 bankroll. Replay the wallets' June-1+ entries in time order (using cached
entry timestamps). At each entry: first settle any held bets that have resolved
(free the cash + realize P&L), then enter IF we can afford the stake — otherwise
it's a MISSED trade (counted, with its hypothetical outcome). Capital stays tied
in still-open positions, which is what forces the misses. Realized P&L only.
One position per market (earliest of the 10 wallets to enter it). Shown across a
few flat stake sizes since that's the knob that trades off coverage vs misses.
"""
import time
import cache
JUN1 = time.mktime(time.strptime("2026-06-01", "%Y-%m-%d"))
NOW = time.time()
BANK = 1000.0
WALLETS = [
"0xe8ca3f758c93f44f3ec210542ab78afb7c0bcccb", "0x0a7aaf83341b52df34e8ffef52aa295538d6df1b",
"0xfd4263b3ad08226034fe1b1ea678a46d80b58895", "0x13464aabec792c36b062316f474713e681330448",
"0x36bfcd8ab96dce2ddea30145ab749b59c6362864", "0x2d4bf8f846bf68f43b9157bf30810d334ac6ca7a",
"0x1cff72c8dddc30a64486fda6eab71ab5f9243984", "0xfc81760d44a21acc9fd4b749a5bf9a9b2eeae072",
"0x86c878cde72660ec52f5e6f0f0438b76de8fc867", "0x6fdddf25b92251ed1515703cda43bf8ff5f5d385",
]
def gather():
"""One copy signal per market: (entry_ts, p, won, res_t|None). res_t None =
still open (ties up capital, no realized P&L)."""
pos = {}
for w in WALLETS:
ent = cache.get_entries(w) # {cond: first_buy_ts}
resolved = {b["cond"]: b for b in cache.get_bets(w)}
for cond, ets in ent.items():
if ets < JUN1:
continue
b = resolved.get(cond)
p = max(0.001, min(0.999, b["p"])) if b else None
rec = dict(ets=ets, p=p, won=b["won"] if b else None,
res_t=(b["res_t"] if b else None))
if cond not in pos or ets < pos[cond]["ets"]:
pos[cond] = rec
return sorted(pos.values(), key=lambda r: r["ets"])
def sim(events, stake):
cash, realized = BANK, 0.0
held = [] # (res_t, p, won, stake)
entered = missed = openn = 0
missed_pnl = 0.0
def settle2(upto):
nonlocal cash, realized
keep = []
for res_t, p, won, s in held:
if res_t is not None and res_t <= upto:
payout = (s / p) if won else 0.0
cash += payout
realized += payout - s
else:
keep.append((res_t, p, won, s))
held[:] = keep
for e in events:
settle2(e["ets"])
if cash >= stake:
cash -= stake
held.append((e["res_t"], e["p"], e["won"], stake))
entered += 1
if e["res_t"] is None:
openn += 1
else:
missed += 1
if e["res_t"] is not None: # hypothetical realized miss
missed_pnl += (stake / e["p"] - stake) if e["won"] else -stake
settle2(NOW)
open_left = sum(1 for h in held if h[0] is None or h[0] > NOW)
equity = BANK + realized # open held at cost
return dict(stake=stake, entered=entered, missed=missed, open_left=open_left,
realized=realized, equity=equity, missed_pnl=missed_pnl)
def main():
ev = gather()
res = sum(1 for e in ev if e["res_t"] is not None)
print(f"10-wallet basket · {len(ev)} unique June1+ markets entered "
f"({res} resolved, {len(ev)-res} still open) · $1000 bankroll, miss when broke\n")
h = f"{'stake':>6}{'entered':>8}{'missed':>7}{'open':>5}{'realized P&L':>14}{'equity':>10}{'missed P&L':>12}"
print(h); print("-" * len(h))
for s in (20, 50, 100, 200):
r = sim(ev, s)
print(f"${r['stake']:>4}{r['entered']:>8}{r['missed']:>7}{r['open_left']:>5}"
f"{r['realized']:>+13,.0f}{r['equity']:>10,.0f}{r['missed_pnl']:>+12,.0f}")
print("\nrealized P&L = settled bets only · equity = $1000 + realized (open held at cost)")
print("missed P&L = hypothetical resolved P&L of trades skipped for lack of cash")
if __name__ == "__main__":
main()
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""Does a FOCUSED copy strategy clear where the broad 10-wallet basket didn't?
Same $1000 capital-constrained engine + missed-trade accounting (pnl_basket.sim),
but on narrower signal sets: fewer wallets, and/or only the wallet's higher-
conviction (larger-stake) bets — so $1000 isn't spread across 1,210 markets.
"""
import time
import cache
import pnl_basket as pb
JUN1 = time.mktime(time.strptime("2026-06-01", "%Y-%m-%d"))
E8 = "0xe8ca3f758c93f44f3ec210542ab78afb7c0bcccb"
A0 = "0x0a7aaf83341b52df34e8ffef52aa295538d6df1b"
def gather(wallets, size_min=None):
"""One signal per market. size_min filters to the wallet's larger-stake
(higher-conviction) bets; in that mode we only use resolved bets (open ones
have no known stake to filter on)."""
pos = {}
for w in wallets:
ent = cache.get_entries(w)
resolved = {b["cond"]: b for b in cache.get_bets(w)}
for cond, ets in ent.items():
if ets < JUN1:
continue
b = resolved.get(cond)
if b:
if size_min and (b["size"] or 0) < size_min:
continue
rec = dict(ets=ets, p=max(0.001, min(0.999, b["p"])),
won=b["won"], res_t=b["res_t"])
else:
if size_min:
continue
rec = dict(ets=ets, p=None, won=None, res_t=None)
if cond not in pos or ets < pos[cond]["ets"]:
pos[cond] = rec
return sorted(pos.values(), key=lambda r: r["ets"])
def run(label, wallets, size_min=None):
ev = gather(wallets, size_min)
res = sum(1 for e in ev if e["res_t"] is not None)
print(f"\n### {label}{len(ev)} markets ({res} resolved)")
h = f"{'stake':>6}{'entered':>8}{'missed':>7}{'open':>5}{'realized':>11}{'equity':>9}"
print(h)
for s in (50, 100, 200):
r = pb.sim(ev, s)
print(f"${s:>4}{r['entered']:>8}{r['missed']:>7}{r['open_left']:>5}"
f"{r['realized']:>+10,.0f}{r['equity']:>9,.0f}")
def main():
run("0xe8 only — all June+ entries", [E8])
run("0xe8 only — conviction (their bets >= $200)", [E8], size_min=200)
run("0xe8 only — conviction (their bets >= $1000)", [E8], size_min=1000)
run("0xe8 + 0x0a — all June+ entries", [E8, A0])
run("0xe8 + 0x0a — conviction (>= $200)", [E8, A0], size_min=200)
print("\nrealized = settled-bet P&L · equity = $1000 + realized (open at cost)")
if __name__ == "__main__":
main()
+1502
View File
File diff suppressed because it is too large Load Diff
+162
View File
@@ -0,0 +1,162 @@
#!/usr/bin/env python3
"""Train/test wallet-selection study, entirely from the local cache.
TRAIN = bets resolved before --train-end (default 2026-05-30): pick wallets.
TEST = bets resolved on/after --test-start (default 2026-06-01), resolved only:
validate which picks were actually profitable to follow forward.
Lens: we have $1,000 and copy flat-size, so the key metric is COPY-ROI — the
mean per-bet return if we mirror each entry with the same stake:
win -> (1-p)/p per $1 (entry at price p pays out at 1)
loss -> -1
A wallet with positive copy-ROI would have made us money (before lag/fees).
We also compute z (beats entry prices) and the wallet's own $ ROI.
Selection gates (all on TRAIN):
* n >= MIN_N resolved bets
* z significant (Benjamini-Hochberg FDR)
* copy-ROI > 0 (copying them actually paid)
* consistent: positive copy-ROI in >= CONSISTENCY of monthly buckets
* copyable proxies: median bet size in [$5,$5000] (not dust, not whale),
not at the ~2000-bet HFT cap, not one-market-dependent
python3 strategy.py
"""
import math
import os
import sys
import time
from collections import defaultdict
import duckdb
HERE = os.path.dirname(__file__)
DB = os.path.join(HERE, "cache.duckdb")
TRAIN_END = time.mktime(time.strptime(os.environ.get("TRAIN_END", "2026-05-30"), "%Y-%m-%d"))
TEST_START = time.mktime(time.strptime(os.environ.get("TEST_START", "2026-06-01"), "%Y-%m-%d"))
MIN_N = 30 # train bets needed to judge a wallet
MIN_N_TEST = 5 # forward bets needed to report a forward number
CAP = 1990 # >= this looks API-capped (HFT/truncated) -> deprioritize
SIZE_LO, SIZE_HI = 5.0, 5000.0 # copyable median bet size ($)
CONSISTENCY = 0.6 # fraction of monthly buckets that must be profitable
FDR_Q = 0.05
def ret(p, won):
return (1 - p) / p if won else -1.0 # copy return per $1 staked
def metrics(bets):
n = len(bets)
wins = sum(1 for b in bets if b["won"])
exp = sum(b["p"] for b in bets)
var = sum(b["p"] * (1 - b["p"]) for b in bets) or 1e-9
z = (wins - exp) / math.sqrt(var)
copy_roi = sum(ret(b["p"], b["won"]) for b in bets) / n
staked = sum(b["size"] for b in bets) or 1e-9
dollars = sum((b["size"] * (1 - b["p"]) / b["p"] if b["won"] else -b["size"]) for b in bets)
return dict(n=n, wins=wins, win_rate=100 * wins / n, z=z, copy_roi=copy_roi,
own_roi=dollars / staked, exp=exp)
def consistency(bets):
"""fraction of calendar-month buckets (by res_t) with positive copy-ROI."""
buck = defaultdict(list)
for b in bets:
buck[time.strftime("%Y-%m", time.localtime(b["res_t"] or 0))].append(b)
months = [m for m in buck.values() if len(m) >= 5]
if not months:
return 0.0, 0
good = sum(1 for m in months if sum(ret(b["p"], b["won"]) for b in m) > 0)
return good / len(months), len(months)
def concentration(bets):
"""share of total copy-return coming from the single best market."""
by = defaultdict(float)
for b in bets:
by[b["cond"]] += ret(b["p"], b["won"])
tot = sum(v for v in by.values() if v > 0) or 1e-9
return max(by.values()) / tot if by else 1.0
def norm_sf(z):
return 0.5 * math.erfc(z / math.sqrt(2))
def main():
con = duckdb.connect(DB, read_only=True)
wallets = [r[0] for r in con.execute("SELECT DISTINCT wallet FROM bets").fetchall()]
print(f"loaded {len(wallets):,} wallets; train<{time.strftime('%F', time.localtime(TRAIN_END))}"
f" test>={time.strftime('%F', time.localtime(TEST_START))}\n", flush=True)
cand = []
for w in wallets:
rows = con.execute(
"SELECT won,p,res_t,size,cond FROM bets WHERE wallet=?", [w]).fetchall()
bets = [dict(won=x[0], p=max(0.001, min(0.999, x[1] or 0)),
res_t=x[2], size=x[3] or 0, cond=x[4]) for x in rows]
train = [b for b in bets if (b["res_t"] or 0) < TRAIN_END]
if len(train) < MIN_N:
continue
m = metrics(train)
med = sorted(b["size"] for b in train)[len(train) // 2]
cons, nmonths = consistency(train)
conc = concentration(train)
test = [b for b in bets if (b["res_t"] or 0) >= TEST_START]
tm = metrics(test) if len(test) >= MIN_N_TEST else None
cand.append(dict(w=w, m=m, med=med, cons=cons, nmonths=nmonths, conc=conc,
capped=len(train) >= CAP, tm=tm, ntest=len(test)))
# FDR over the candidate edge p-values
pvals = sorted(norm_sf(c["m"]["z"]) for c in cand)
k = 0
for i, p in enumerate(pvals, 1):
if p <= FDR_Q * i / len(pvals):
k = i
thr = pvals[k - 1] if k else 0.0
# selection gates (all on TRAIN)
sel = [c for c in cand if
norm_sf(c["m"]["z"]) <= thr and thr > 0 and
c["m"]["copy_roi"] > 0 and
c["cons"] >= CONSISTENCY and
SIZE_LO <= c["med"] <= SIZE_HI and
not c["capped"] and
c["conc"] < 0.5]
sel.sort(key=lambda c: c["m"]["copy_roi"], reverse=True)
print(f"{len(cand):,} wallets with >= {MIN_N} train bets · BH thr p<= {thr:.1e}")
print(f"SELECTED (skilled + consistent + copyable on TRAIN): {len(sel)}\n")
# how did the SELECTED set do FORWARD?
fwd = [c for c in sel if c["tm"]]
if fwd:
avg_fwd = sum(c["tm"]["copy_roi"] for c in fwd) / len(fwd)
win_fwd = sum(1 for c in fwd if c["tm"]["copy_roi"] > 0)
print(f"FORWARD (June1+, resolved): {len(fwd)} selected wallets had test bets · "
f"{win_fwd}/{len(fwd)} stayed profitable · mean fwd copy-ROI {avg_fwd:+.1%}\n")
h = (f"{'train_roi':>10}{'fwd_roi':>9}{'tr_z':>6}{'tr_wr':>6}{'cons':>6}"
f"{'medSz':>7}{'tr_n':>6}{'fwd_n':>6} wallet")
print(h); print("-" * len(h))
for c in sel[:40]:
t = c["tm"]
fr = f"{t['copy_roi']:+.0%}" if t else ""
fn = c["ntest"] if t else 0
print(f"{c['m']['copy_roi']:>+9.0%}{fr:>9}{c['m']['z']:>6.1f}{c['m']['win_rate']:>5.0f}%"
f"{c['cons']:>6.0%}{c['med']:>7.0f}{c['m']['n']:>6}{fn:>6} {c['w']}")
# persist the selection for the followability pull + watchlist
import json
json.dump([{"wallet": c["w"], "train_copy_roi": round(c["m"]["copy_roi"], 4),
"train_z": round(c["m"]["z"], 2), "train_n": c["m"]["n"],
"fwd_copy_roi": round(c["tm"]["copy_roi"], 4) if c["tm"] else None,
"fwd_n": c["ntest"], "med_size": round(c["med"], 1),
"consistency": round(c["cons"], 2)} for c in sel],
open(os.path.join(HERE, "selection.json"), "w"), indent=2)
print(f"\n-> selection.json ({len(sel)} wallets)")
if __name__ == "__main__":
main()
+849
View File
@@ -0,0 +1,849 @@
[
{
"wallet": "0xe8ca3f758c93f44f3ec210542ab78afb7c0bcccb",
"name": "0xe8ca3f75",
"foll_fwd_copy_roi": 2.7036,
"med_lead_h": 95.6,
"cadence_per_day": 8.7,
"followable_frac": 0.99,
"fwd_followable_n": 93,
"train_z": 18.86,
"train_copy_roi": 2.8782
},
{
"wallet": "0x0a7aaf83341b52df34e8ffef52aa295538d6df1b",
"name": "0x0a7aaf83",
"foll_fwd_copy_roi": 2.134,
"med_lead_h": 248.8,
"cadence_per_day": 9.8,
"followable_frac": 0.99,
"fwd_followable_n": 138,
"train_z": 7.21,
"train_copy_roi": 0.5841
},
{
"wallet": "0xfd4263b3ad08226034fe1b1ea678a46d80b58895",
"name": "0xfd4263b3",
"foll_fwd_copy_roi": 0.9877,
"med_lead_h": 256.3,
"cadence_per_day": 5.8,
"followable_frac": 0.98,
"fwd_followable_n": 39,
"train_z": 15.53,
"train_copy_roi": 2.1616
},
{
"wallet": "0x13464aabec792c36b062316f474713e681330448",
"name": "0x13464aab",
"foll_fwd_copy_roi": 0.9692,
"med_lead_h": 158.6,
"cadence_per_day": 5.8,
"followable_frac": 0.96,
"fwd_followable_n": 89,
"train_z": 7.33,
"train_copy_roi": 0.512
},
{
"wallet": "0xad703ba9fa7af1447bfcfe22522d052df64f4ccf",
"name": "0xad703ba9",
"foll_fwd_copy_roi": 0.9587,
"med_lead_h": 39.6,
"cadence_per_day": 11.0,
"followable_frac": 0.99,
"fwd_followable_n": 163,
"train_z": 3.98,
"train_copy_roi": 0.3063
},
{
"wallet": "0x36bfcd8ab96dce2ddea30145ab749b59c6362864",
"name": "0x36bfcd8a",
"foll_fwd_copy_roi": 0.8856,
"med_lead_h": 157.7,
"cadence_per_day": 16.9,
"followable_frac": 1.0,
"fwd_followable_n": 96,
"train_z": 7.03,
"train_copy_roi": 0.2044
},
{
"wallet": "0x2d4bf8f846bf68f43b9157bf30810d334ac6ca7a",
"name": "0x2d4bf8f8",
"foll_fwd_copy_roi": 0.6857,
"med_lead_h": 364.3,
"cadence_per_day": 6.8,
"followable_frac": 0.99,
"fwd_followable_n": 110,
"train_z": 19.72,
"train_copy_roi": 0.8859
},
{
"wallet": "0xade74a23c444d0eebee00034459fbc269fab58af",
"name": "0xade74a23",
"foll_fwd_copy_roi": 0.6597,
"med_lead_h": 161.4,
"cadence_per_day": 1.5,
"followable_frac": 1.0,
"fwd_followable_n": 18,
"train_z": 6.43,
"train_copy_roi": 0.3886
},
{
"wallet": "0xab2067f2bfe4a5bce93cda6f418cde1515d2d9e2",
"name": "0xab2067f2",
"foll_fwd_copy_roi": 0.5481,
"med_lead_h": 161.4,
"cadence_per_day": 3.8,
"followable_frac": 1.0,
"fwd_followable_n": 19,
"train_z": 5.6,
"train_copy_roi": 0.2669
},
{
"wallet": "0x1cff72c8dddc30a64486fda6eab71ab5f9243984",
"name": "0x1cff72c8",
"foll_fwd_copy_roi": 0.4498,
"med_lead_h": 14.8,
"cadence_per_day": 3.5,
"followable_frac": 1.0,
"fwd_followable_n": 31,
"train_z": 5.5,
"train_copy_roi": 0.1861
},
{
"wallet": "0x68c24bf4a8ad4d79a6fe4b8eec6f93a02dfd1711",
"name": "0x68c24bf4",
"foll_fwd_copy_roi": 0.4469,
"med_lead_h": 401.2,
"cadence_per_day": 4.2,
"followable_frac": 1.0,
"fwd_followable_n": 30,
"train_z": 4.23,
"train_copy_roi": 0.3288
},
{
"wallet": "0xfc81760d44a21acc9fd4b749a5bf9a9b2eeae072",
"name": "0xfc81760d",
"foll_fwd_copy_roi": 0.409,
"med_lead_h": 161.5,
"cadence_per_day": 5.7,
"followable_frac": 0.99,
"fwd_followable_n": 142,
"train_z": 7.92,
"train_copy_roi": 0.2013
},
{
"wallet": "0x2f385bfefacbf73173f9cb81f46fe7a53b2c8adc",
"name": "0x2f385bfe",
"foll_fwd_copy_roi": 0.3809,
"med_lead_h": 173.0,
"cadence_per_day": 0.3,
"followable_frac": 0.99,
"fwd_followable_n": 25,
"train_z": 3.75,
"train_copy_roi": 0.2828
},
{
"wallet": "0x7ed0a33693a19378318f160064e4f9c1c27a9c4f",
"name": "0x7ed0a336",
"foll_fwd_copy_roi": 0.361,
"med_lead_h": 154.6,
"cadence_per_day": 10.5,
"followable_frac": 1.0,
"fwd_followable_n": 250,
"train_z": 3.9,
"train_copy_roi": 0.1949
},
{
"wallet": "0x64795fe43b184571d5eb25ca44fc9ba9e1295e64",
"name": "0x64795fe4",
"foll_fwd_copy_roi": 0.3407,
"med_lead_h": 17.9,
"cadence_per_day": 2.8,
"followable_frac": 0.96,
"fwd_followable_n": 7,
"train_z": 7.29,
"train_copy_roi": 0.2879
},
{
"wallet": "0x312d268ab4d1823684d6838f24a3c96da7d66814",
"name": "0x312d268a",
"foll_fwd_copy_roi": 0.327,
"med_lead_h": 5.5,
"cadence_per_day": 16.5,
"followable_frac": 0.87,
"fwd_followable_n": 30,
"train_z": 3.48,
"train_copy_roi": 0.0428
},
{
"wallet": "0x86c878cde72660ec52f5e6f0f0438b76de8fc867",
"name": "0x86c878cd",
"foll_fwd_copy_roi": 0.3054,
"med_lead_h": 156.9,
"cadence_per_day": 11.0,
"followable_frac": 1.0,
"fwd_followable_n": 97,
"train_z": 7.81,
"train_copy_roi": 1.2334
},
{
"wallet": "0x48270d81cfe598ae0379ca535a26dc41e3e9080d",
"name": "0x48270d81",
"foll_fwd_copy_roi": 0.2759,
"med_lead_h": 150.9,
"cadence_per_day": 16.8,
"followable_frac": 0.92,
"fwd_followable_n": 170,
"train_z": 3.12,
"train_copy_roi": 0.1267
},
{
"wallet": "0x12f93b2a5cd5d370e2e2772246c3c7ceed7774ba",
"name": "0x12f93b2a",
"foll_fwd_copy_roi": 0.2733,
"med_lead_h": 2.5,
"cadence_per_day": 9.6,
"followable_frac": 0.87,
"fwd_followable_n": 8,
"train_z": 11.58,
"train_copy_roi": 0.3433
},
{
"wallet": "0xc904211fd4412d5caa0b51f923304bf5e1821e9a",
"name": "0xc904211f",
"foll_fwd_copy_roi": 0.2391,
"med_lead_h": 10.5,
"cadence_per_day": 5.2,
"followable_frac": 1.0,
"fwd_followable_n": 21,
"train_z": 4.14,
"train_copy_roi": 0.2324
},
{
"wallet": "0xb8f6c79e452d7247d0cf47d16eaf7911953c4f7f",
"name": "0xb8f6c79e",
"foll_fwd_copy_roi": 0.2062,
"med_lead_h": 136.4,
"cadence_per_day": 16.8,
"followable_frac": 0.99,
"fwd_followable_n": 154,
"train_z": 3.31,
"train_copy_roi": 0.082
},
{
"wallet": "0x6fdddf25b92251ed1515703cda43bf8ff5f5d385",
"name": "0x6fdddf25",
"foll_fwd_copy_roi": 0.2044,
"med_lead_h": 10.1,
"cadence_per_day": 25.7,
"followable_frac": 0.98,
"fwd_followable_n": 103,
"train_z": 7.59,
"train_copy_roi": 0.4085
},
{
"wallet": "0xe1a607ef9d2bf9db6a8ebc99c612743827c8391d",
"name": "0xe1a607ef",
"foll_fwd_copy_roi": 0.1693,
"med_lead_h": 171.3,
"cadence_per_day": 0.4,
"followable_frac": 0.99,
"fwd_followable_n": 31,
"train_z": 5.35,
"train_copy_roi": 0.36
},
{
"wallet": "0x13a12ebadc50f6fa42c8f2595997d8adf329d9bc",
"name": "0x13a12eba",
"foll_fwd_copy_roi": 0.1595,
"med_lead_h": 2.1,
"cadence_per_day": 10.8,
"followable_frac": 0.87,
"fwd_followable_n": 28,
"train_z": 4.43,
"train_copy_roi": 0.082
},
{
"wallet": "0x5912794596cd3cc2f36605710fc1fcd6e5886f45",
"name": "0x59127945",
"foll_fwd_copy_roi": 0.1589,
"med_lead_h": 157.6,
"cadence_per_day": 6.8,
"followable_frac": 0.99,
"fwd_followable_n": 150,
"train_z": 6.6,
"train_copy_roi": 0.0691
},
{
"wallet": "0x4269450ac9f1927fc1fd462678606d3c7656e056",
"name": "0x4269450a",
"foll_fwd_copy_roi": 0.1512,
"med_lead_h": 3.2,
"cadence_per_day": 6.2,
"followable_frac": 0.85,
"fwd_followable_n": 12,
"train_z": 5.47,
"train_copy_roi": 0.1799
},
{
"wallet": "0x96be2d4496f4c547e6c0e7765f15d7c83c5069a9",
"name": "0x96be2d44",
"foll_fwd_copy_roi": 0.1354,
"med_lead_h": 3.2,
"cadence_per_day": 39.8,
"followable_frac": 0.8,
"fwd_followable_n": 172,
"train_z": 5.4,
"train_copy_roi": 0.0536
},
{
"wallet": "0x75acf1aa88a3f5c613f2214486b91fa9fc1f33d7",
"name": "0x75acf1aa",
"foll_fwd_copy_roi": 0.1346,
"med_lead_h": 67.7,
"cadence_per_day": 7.1,
"followable_frac": 1.0,
"fwd_followable_n": 132,
"train_z": 7.61,
"train_copy_roi": 0.1037
},
{
"wallet": "0x2f633efb75256a2f2445110c8978684ab8936643",
"name": "0x2f633efb",
"foll_fwd_copy_roi": 0.1322,
"med_lead_h": 253.6,
"cadence_per_day": 1.7,
"followable_frac": 0.97,
"fwd_followable_n": 36,
"train_z": 7.54,
"train_copy_roi": 0.1757
},
{
"wallet": "0x8428101d6979dcc97de6c7474b0535ceb558b41f",
"name": "0x8428101d",
"foll_fwd_copy_roi": 0.1305,
"med_lead_h": 2.4,
"cadence_per_day": 33.2,
"followable_frac": 0.82,
"fwd_followable_n": 112,
"train_z": 3.69,
"train_copy_roi": 0.0588
},
{
"wallet": "0xc308447bc9ef6e72018a3f3914005bd24c207b09",
"name": "0xc308447b",
"foll_fwd_copy_roi": 0.1274,
"med_lead_h": 2.1,
"cadence_per_day": 15.9,
"followable_frac": 0.82,
"fwd_followable_n": 194,
"train_z": 5.54,
"train_copy_roi": 0.5171
},
{
"wallet": "0x2b7b2173a5f89300e93625805871565ed82e8539",
"name": "0x2b7b2173",
"foll_fwd_copy_roi": 0.1127,
"med_lead_h": 2.4,
"cadence_per_day": 45.6,
"followable_frac": 0.81,
"fwd_followable_n": 63,
"train_z": 13.85,
"train_copy_roi": 0.3276
},
{
"wallet": "0x143844ade2eb7d1aa86c2dee71dc65eb28396d40",
"name": "0x143844ad",
"foll_fwd_copy_roi": 0.1065,
"med_lead_h": 2.7,
"cadence_per_day": 40.8,
"followable_frac": 0.8,
"fwd_followable_n": 105,
"train_z": 4.1,
"train_copy_roi": 0.1253
},
{
"wallet": "0x5f5945ea1a0be6c3ca7c841769ef892be48ae61d",
"name": "0x5f5945ea",
"foll_fwd_copy_roi": 0.1056,
"med_lead_h": 2.3,
"cadence_per_day": 11.4,
"followable_frac": 0.77,
"fwd_followable_n": 27,
"train_z": 4.14,
"train_copy_roi": 0.0393
},
{
"wallet": "0x5e23595f0d698f29832a5cf19e94c24fb1c5a3d7",
"name": "0x5e23595f",
"foll_fwd_copy_roi": 0.0972,
"med_lead_h": 2.2,
"cadence_per_day": 20.8,
"followable_frac": 0.79,
"fwd_followable_n": 63,
"train_z": 7.59,
"train_copy_roi": 0.0746
},
{
"wallet": "0x1e55408f217f58facdf1d663c74cfa7f55e9e3e2",
"name": "0x1e55408f",
"foll_fwd_copy_roi": 0.0959,
"med_lead_h": 322.6,
"cadence_per_day": 1.4,
"followable_frac": 1.0,
"fwd_followable_n": 77,
"train_z": 4.12,
"train_copy_roi": 0.4696
},
{
"wallet": "0xb03b826a4fc9893b35d3ddf4f11be824525b6ca1",
"name": "0xb03b826a",
"foll_fwd_copy_roi": 0.0878,
"med_lead_h": 322.5,
"cadence_per_day": 2.6,
"followable_frac": 0.98,
"fwd_followable_n": 39,
"train_z": 4.1,
"train_copy_roi": 0.081
},
{
"wallet": "0xf2bbd4a5a02780c14b7ec16a52a3e21a744cae21",
"name": "0xf2bbd4a5",
"foll_fwd_copy_roi": 0.0854,
"med_lead_h": 27.8,
"cadence_per_day": 16.3,
"followable_frac": 0.94,
"fwd_followable_n": 87,
"train_z": 3.01,
"train_copy_roi": 0.1332
},
{
"wallet": "0xffb0b9b292e406fd250854a35a0c9bd5612afa37",
"name": "0xffb0b9b2",
"foll_fwd_copy_roi": 0.0786,
"med_lead_h": 495.6,
"cadence_per_day": 2.4,
"followable_frac": 1.0,
"fwd_followable_n": 42,
"train_z": 4.63,
"train_copy_roi": 0.1617
},
{
"wallet": "0xff4288c9d0cf320e494174554a752fe9f9ca1548",
"name": "0xff4288c9",
"foll_fwd_copy_roi": 0.0696,
"med_lead_h": 2.9,
"cadence_per_day": 35.6,
"followable_frac": 0.85,
"fwd_followable_n": 48,
"train_z": 3.17,
"train_copy_roi": 0.04
},
{
"wallet": "0xb2b4ec88c02de44d6ab61eb6c4141fe8170e512d",
"name": "0xb2b4ec88",
"foll_fwd_copy_roi": 0.0671,
"med_lead_h": 2.6,
"cadence_per_day": 46.3,
"followable_frac": 0.83,
"fwd_followable_n": 49,
"train_z": 3.9,
"train_copy_roi": 0.0674
},
{
"wallet": "0xed61f86bb5298d2f27c21c433ce58d80b88a9aa3",
"name": "0xed61f86b",
"foll_fwd_copy_roi": 0.0439,
"med_lead_h": 3.2,
"cadence_per_day": 3.6,
"followable_frac": 0.91,
"fwd_followable_n": 13,
"train_z": 10.52,
"train_copy_roi": 0.35
},
{
"wallet": "0xc39319fc46cb229eeacf3763cce5977766b3b18f",
"name": "0xc39319fc",
"foll_fwd_copy_roi": 0.0436,
"med_lead_h": 2.1,
"cadence_per_day": 14.8,
"followable_frac": 0.74,
"fwd_followable_n": 66,
"train_z": 5.06,
"train_copy_roi": 0.3394
},
{
"wallet": "0x7ca56b03105371839e4a3d98f4c1059d10d784bc",
"name": "0x7ca56b03",
"foll_fwd_copy_roi": 0.0222,
"med_lead_h": 156.3,
"cadence_per_day": 38.0,
"followable_frac": 0.98,
"fwd_followable_n": 194,
"train_z": 4.57,
"train_copy_roi": 0.0063
},
{
"wallet": "0x8c1026f774fe33016fb36d5f18f5e791d3e0d7b3",
"name": "0x8c1026f7",
"foll_fwd_copy_roi": 0.0205,
"med_lead_h": 404.8,
"cadence_per_day": 9.8,
"followable_frac": 1.0,
"fwd_followable_n": 242,
"train_z": 3.16,
"train_copy_roi": 0.0215
},
{
"wallet": "0x70831c34434486ffb8e33270642604d9c5731937",
"name": "0x70831c34",
"foll_fwd_copy_roi": 0.0166,
"med_lead_h": 131.0,
"cadence_per_day": 4.0,
"followable_frac": 0.83,
"fwd_followable_n": 10,
"train_z": 5.38,
"train_copy_roi": 0.7969
},
{
"wallet": "0x85d57ae07c1c0cae93f1ed6d05166eff4233bbf0",
"name": "0x85d57ae0",
"foll_fwd_copy_roi": 0.0155,
"med_lead_h": 159.4,
"cadence_per_day": 5.8,
"followable_frac": 1.0,
"fwd_followable_n": 97,
"train_z": 5.67,
"train_copy_roi": 0.1268
},
{
"wallet": "0x5a05e30ef2ae848927c7a724b93292bf8cd14c5a",
"name": "0x5a05e30e",
"foll_fwd_copy_roi": 0.0136,
"med_lead_h": 6.5,
"cadence_per_day": 25.6,
"followable_frac": 0.99,
"fwd_followable_n": 48,
"train_z": 7.26,
"train_copy_roi": 0.1578
},
{
"wallet": "0x875e974594985283c999765461bf2e15b4dee6b5",
"name": "0x875e9745",
"foll_fwd_copy_roi": 0.0047,
"med_lead_h": 5.7,
"cadence_per_day": 16.3,
"followable_frac": 0.94,
"fwd_followable_n": 14,
"train_z": 4.25,
"train_copy_roi": 0.0102
},
{
"wallet": "0x587bcff09b7e887186a4e2b3086653f10dcd2622",
"name": "0x587bcff0",
"foll_fwd_copy_roi": -0.002,
"med_lead_h": 35.9,
"cadence_per_day": 17.2,
"followable_frac": 0.99,
"fwd_followable_n": 52,
"train_z": 3.48,
"train_copy_roi": 0.1476
},
{
"wallet": "0xa75f077c6e2510b020967c6230bac2bf342300f0",
"name": "0xa75f077c",
"foll_fwd_copy_roi": -0.007,
"med_lead_h": 2.8,
"cadence_per_day": 21.7,
"followable_frac": 0.8,
"fwd_followable_n": 21,
"train_z": 5.54,
"train_copy_roi": 0.135
},
{
"wallet": "0xb5e987c2027879646587f060f7d25793d011c62a",
"name": "0xb5e987c2",
"foll_fwd_copy_roi": -0.0136,
"med_lead_h": 2.0,
"cadence_per_day": 39.0,
"followable_frac": 0.78,
"fwd_followable_n": 48,
"train_z": 9.81,
"train_copy_roi": 0.074
},
{
"wallet": "0x8548f0fae7636fc17ca6bb2cbae39cbd4fbce4c1",
"name": "0x8548f0fa",
"foll_fwd_copy_roi": -0.026,
"med_lead_h": 3.2,
"cadence_per_day": 21.5,
"followable_frac": 0.94,
"fwd_followable_n": 35,
"train_z": 4.34,
"train_copy_roi": 1.2923
},
{
"wallet": "0xd84d970b0d4ec9bfc28d011306eba298b339cc32",
"name": "0xd84d970b",
"foll_fwd_copy_roi": -0.0384,
"med_lead_h": 6.9,
"cadence_per_day": 8.4,
"followable_frac": 0.97,
"fwd_followable_n": 44,
"train_z": 8.73,
"train_copy_roi": 1.7671
},
{
"wallet": "0xf3d54ccedcd08c9a203d28e332275e50770fdde9",
"name": "0xf3d54cce",
"foll_fwd_copy_roi": -0.0386,
"med_lead_h": 2.8,
"cadence_per_day": 22.9,
"followable_frac": 0.79,
"fwd_followable_n": 21,
"train_z": 4.66,
"train_copy_roi": 0.095
},
{
"wallet": "0xc52fead8edac49825f5c52aff6e63cd331980981",
"name": "0xc52fead8",
"foll_fwd_copy_roi": -0.0394,
"med_lead_h": 57.1,
"cadence_per_day": 11.2,
"followable_frac": 0.99,
"fwd_followable_n": 73,
"train_z": 4.15,
"train_copy_roi": 0.0657
},
{
"wallet": "0x4b284723fa3c53a46d5217394840ec3b70c615df",
"name": "0x4b284723",
"foll_fwd_copy_roi": -0.0434,
"med_lead_h": 535.7,
"cadence_per_day": 3.6,
"followable_frac": 1.0,
"fwd_followable_n": 82,
"train_z": 3.58,
"train_copy_roi": 0.3997
},
{
"wallet": "0xc0f1388fdb14503c3bdf7c244346c98b57208680",
"name": "0xc0f1388f",
"foll_fwd_copy_roi": -0.0588,
"med_lead_h": 9.3,
"cadence_per_day": 20.4,
"followable_frac": 0.99,
"fwd_followable_n": 82,
"train_z": 4.52,
"train_copy_roi": 0.4433
},
{
"wallet": "0xc5d521074e88279556836998fb2a5d2e2c1c6caa",
"name": "0xc5d52107",
"foll_fwd_copy_roi": -0.0598,
"med_lead_h": 3.2,
"cadence_per_day": 37.2,
"followable_frac": 1.0,
"fwd_followable_n": 21,
"train_z": 5.39,
"train_copy_roi": 0.051
},
{
"wallet": "0x9e8ecc4cb3c4e48f544cba2fbbb252a6a65e8db8",
"name": "0x9e8ecc4c",
"foll_fwd_copy_roi": -0.0798,
"med_lead_h": 46.1,
"cadence_per_day": 47.0,
"followable_frac": 0.99,
"fwd_followable_n": 512,
"train_z": 10.17,
"train_copy_roi": 0.0761
},
{
"wallet": "0xbbeacf98b7affb6ac2abf44b6577f5a54f931bb3",
"name": "0xbbeacf98",
"foll_fwd_copy_roi": -0.1034,
"med_lead_h": 3.1,
"cadence_per_day": 8.7,
"followable_frac": 0.88,
"fwd_followable_n": 25,
"train_z": 3.42,
"train_copy_roi": 0.1141
},
{
"wallet": "0xd9001f915cf59cbd013f57ed380372329496d9d6",
"name": "0xd9001f91",
"foll_fwd_copy_roi": -0.1374,
"med_lead_h": 3.3,
"cadence_per_day": 9.8,
"followable_frac": 0.85,
"fwd_followable_n": 23,
"train_z": 5.87,
"train_copy_roi": 0.0809
},
{
"wallet": "0x3298488d0f4af79aa44634e95f03f4ba8669b714",
"name": "0x3298488d",
"foll_fwd_copy_roi": -0.1394,
"med_lead_h": 155.9,
"cadence_per_day": 12.6,
"followable_frac": 1.0,
"fwd_followable_n": 7,
"train_z": 7.8,
"train_copy_roi": 0.5191
},
{
"wallet": "0xbafa197f7eecfc2fd2fe348cb995bba6812402e0",
"name": "0xbafa197f",
"foll_fwd_copy_roi": -0.152,
"med_lead_h": 6.3,
"cadence_per_day": 4.2,
"followable_frac": 1.0,
"fwd_followable_n": 24,
"train_z": 3.99,
"train_copy_roi": 0.1195
},
{
"wallet": "0x215adbb63b47d0ca92f849fe2c2dc1adb0f6254c",
"name": "0x215adbb6",
"foll_fwd_copy_roi": -0.1533,
"med_lead_h": 364.9,
"cadence_per_day": 27.6,
"followable_frac": 1.0,
"fwd_followable_n": 98,
"train_z": 4.71,
"train_copy_roi": 0.3785
},
{
"wallet": "0x51f7c3d9fa8cc71818aede2db6e4496968ecae1f",
"name": "0x51f7c3d9",
"foll_fwd_copy_roi": -0.1669,
"med_lead_h": 105.2,
"cadence_per_day": 15.5,
"followable_frac": 0.99,
"fwd_followable_n": 231,
"train_z": 3.31,
"train_copy_roi": 0.6247
},
{
"wallet": "0xa6214292fba769fc1c0a11c3191cefe197bf6e29",
"name": "0xa6214292",
"foll_fwd_copy_roi": -0.2162,
"med_lead_h": 3.4,
"cadence_per_day": 15.9,
"followable_frac": 0.89,
"fwd_followable_n": 10,
"train_z": 5.0,
"train_copy_roi": 0.0241
},
{
"wallet": "0x128485a5431d5cc091e0aac21299a819fc370323",
"name": "0x128485a5",
"foll_fwd_copy_roi": -0.2585,
"med_lead_h": 2.5,
"cadence_per_day": 7.3,
"followable_frac": 0.91,
"fwd_followable_n": 5,
"train_z": 7.05,
"train_copy_roi": 0.1592
},
{
"wallet": "0x31de246d1502779e316a991fb85d3627a34303ff",
"name": "0x31de246d",
"foll_fwd_copy_roi": -0.3087,
"med_lead_h": 47.2,
"cadence_per_day": 6.2,
"followable_frac": 0.96,
"fwd_followable_n": 46,
"train_z": 2.98,
"train_copy_roi": 0.1141
},
{
"wallet": "0xba0229758a95f7e1f906a7b9101bf2c195cb6b23",
"name": "0xba022975",
"foll_fwd_copy_roi": -0.3561,
"med_lead_h": 95.4,
"cadence_per_day": 2.3,
"followable_frac": 0.99,
"fwd_followable_n": 37,
"train_z": 3.25,
"train_copy_roi": 0.0936
},
{
"wallet": "0x1a6df901e63422055a1658b0ef2b2a871507cf4a",
"name": "0x1a6df901",
"foll_fwd_copy_roi": -0.3636,
"med_lead_h": 8.6,
"cadence_per_day": 7.6,
"followable_frac": 0.8,
"fwd_followable_n": 13,
"train_z": 11.16,
"train_copy_roi": 2.1573
},
{
"wallet": "0x34f4c3118569f32ef02441326305bca0ff5816bd",
"name": "0x34f4c311",
"foll_fwd_copy_roi": -0.3772,
"med_lead_h": 2.3,
"cadence_per_day": 32.3,
"followable_frac": 0.81,
"fwd_followable_n": 34,
"train_z": 3.96,
"train_copy_roi": 0.0336
},
{
"wallet": "0xc850cf70d9da621ff0c219f625c9623f88b78c51",
"name": "0xc850cf70",
"foll_fwd_copy_roi": -0.3856,
"med_lead_h": 3.8,
"cadence_per_day": 13.7,
"followable_frac": 1.0,
"fwd_followable_n": 6,
"train_z": 6.06,
"train_copy_roi": 0.1196
},
{
"wallet": "0xbd934e2889bef964f6b2e396f769eda6b2ef13fc",
"name": "0xbd934e28",
"foll_fwd_copy_roi": -0.3913,
"med_lead_h": 2.5,
"cadence_per_day": 9.1,
"followable_frac": 0.8,
"fwd_followable_n": 33,
"train_z": 6.04,
"train_copy_roi": 0.1456
},
{
"wallet": "0xddcd8e90d139f6d60042b4a14cb2cd00a3a8725f",
"name": "0xddcd8e90",
"foll_fwd_copy_roi": -0.8613,
"med_lead_h": 4.0,
"cadence_per_day": 9.8,
"followable_frac": 0.8,
"fwd_followable_n": 29,
"train_z": 4.94,
"train_copy_roi": 0.5462
},
{
"wallet": "0x93d9f537708ccb6e701a4ebd495e29b95798639f",
"name": "0x93d9f537",
"foll_fwd_copy_roi": -1.0,
"med_lead_h": 3.6,
"cadence_per_day": 10.1,
"followable_frac": 0.97,
"fwd_followable_n": 9,
"train_z": 3.3,
"train_copy_roi": 0.3581
},
{
"wallet": "0x02730eb22c927008de1dd5b5df1c493ee67661e4",
"name": "0x02730eb2",
"foll_fwd_copy_roi": -1.0,
"med_lead_h": 2.7,
"cadence_per_day": 23.8,
"followable_frac": 0.77,
"fwd_followable_n": 5,
"train_z": 3.4,
"train_copy_roi": 0.1823
}
]