import json, statistics as st
rows=json.load(open('winner_features.json'))
c25={c['symbol']:c for c in json.load(open('/var/www/screener/trade1/sim/candidates/2026-09-25.json'))}
for r in rows:
    if r['date']=='2026-09-25' and r['symbol'] in c25:
        m=c25[r['symbol']]['metrics']; r['rvol']=m.get('rvol'); r['pm_volume']=m.get('premarket_volume')
        r['pm_strength_pct']=m.get('price_strength_pct'); r['dist_to_resistance_pct']=m.get('distance_to_resistance_pct'); r['score']=c25[r['symbol']].get('candidate_score')
N=len(rows); B=sum(r['big'] for r in rows)
print(f"{N} stock-days, {B} big winners, base rate {B/N*100:.1f}%\n")
def med(k,sel):
    v=[r[k] for r in rows if sel(r) and isinstance(r.get(k),(int,float)) and not isinstance(r.get(k),bool)]
    return st.median(v) if v else None
num=["price","score","rvol","pm_volume","gap_pct","pm_strength_pct","dist_to_resistance_pct","daily_atr_pct","open_vs_20d_high_pct","open_vs_prev_high_pct","pos_in_5d_range","prev_day_chg_pct","chg_5d_pct","days_on_list_before","spy_0930_1000","iwm_0930_1000","chg_1000","vs_vwap_1000","off_high_1000","range_1000","vol_1000_x_base","chg_1030","vs_vwap_1030","off_high_1030","range_1030","vol_1030_x_base"]
print(f"{'feature':24}{'big winners':>12}{'others':>10}   (medians)")
for k in num:
    a=med(k,lambda r:r['big']); b=med(k,lambda r:not r['big'])
    if a is not None: print(f"{k:24}{a:12.2f}{b:10.2f}")
def rate(label, sel):
    s=[r for r in rows if sel(r)]
    if s: print(f"  {label:44} n={len(s):4}  big {sum(r['big'] for r in s)/len(s)*100:5.1f}%  winners {sum(r['winner'] for r in s)/len(s)*100:5.1f}%  avg open-close {st.mean(r['open_close_pct'] for r in s):+.2f}%")
def bands(k, edges):
    print(f"\n{k}:")
    for a,b in zip(edges,edges[1:]):
        rate(f"{a} .. {b}", lambda r,a=a,b=b: isinstance(r.get(k),(int,float)) and a<=r[k]<b)
for k,e in [("price",[0,3,5,8,12,20,100]),("gap_pct",[-50,-2,0,2,5,10,20,500]),("rvol",[0,0.1,0.3,1,3,1000]),
            ("daily_atr_pct",[0,3,5,8,12,100]),("pos_in_5d_range",[-500,0,25,50,75,100,500]),("open_vs_20d_high_pct",[-100,-20,-10,-3,0,5,500]),
            ("prev_day_chg_pct",[-100,-5,0,5,15,1000]),("chg_5d_pct",[-100,-10,0,10,30,1000]),
            ("chg_1000",[-100,-3,-1,0,1,3,100]),("vs_vwap_1000",[-100,-1,0,1,2,100]),("off_high_1000",[-100,-5,-3,-1,-0.0001,1]),
            ("vol_1000_x_base",[0,0.05,0.1,0.25,0.5,100]),("chg_1030",[-100,-3,-1,0,1,3,100]),("vs_vwap_1030",[-100,-1,0,1,2,100]),
            ("spy_0930_1000",[-5,-0.3,0,0.3,5]),("iwm_0930_1000",[-5,-0.3,0,0.3,5])]:
    bands(k,e)
print()
for k in ["on_list_prev_day","big_winner_before","low_before_high_1000","higher_low_1030","higher_high_1030"]:
    print(k); rate("yes",lambda r,k=k:r.get(k) is True); rate("no",lambda r,k=k:r.get(k) is False)
