import json, math, statistics as S, random
exec(open('it1.py').read().split("keys=[k for k in D")[0])
def donch(L,nin,nout):
    s=False;o=[]
    for i in range(len(L)):
        if i>=nin and L[i]>max(L[i-nin:i]): s=True
        elif i>=nout and L[i]<min(L[i-nout:i]): s=False
        o.append(s)
    return o
def ma_band(L,n,b):
    m=sma(L,n); return hyst([m[i] is not None and L[i]>m[i]*(1+b) for i in range(len(L))],[m[i] is None or L[i]<m[i]*(1-b) for i in range(len(L))])
def more(ds,L):
    o={}
    for n in (50,100,150,200):
        for b in (0,0.01,0.03,0.05):
            o[f'MA{n} band{int(b*100)}']=ma_band(L,n,b)
    for a,c in ((20,10),(30,15),(50,20),(90,30)):
        o[f'Donchian {a}/{c}']=donch(L,a,c)
    return o
keys=[k for k in D if k!='btc']
periods=[("all","2022-09-01","2026-12-31"),("H1","2022-09-01","2024-09-01"),("H2","2024-09-01","2026-12-31")]
res={}
for k in keys:
    ds=[d for d,_ in D[k]['line']]; L=[v for _,v in D[k]['line']]
    st=states(ds,L); st.update(more(ds,L))
    for nm,s in st.items():
        for pn,lo,hi in periods:
            eq,bh,tim,sw,n=run(ds,L,s,lo,hi)
            if n<60: continue
            # edge vs random exposure with same time in market and same switch cost
            edge=(eq-(tim*bh+sw*math.log(1-0.005)))/n*365
            # tail: share of the basket's worst 5% of 14d windows that started while ON
            fw=[(L[i+14]/L[i]-1,s[i]) for i in range(len(L)-14) if lo<=ds[i]<hi]
            fw.sort(); w=fw[:max(1,len(fw)//20)]; tail=sum(1 for _,x in w if x)/len(w)
            bst=fw[-max(1,len(fw)//20):]; up=sum(1 for _,x in bst if x)/len(bst)
            res.setdefault(nm,{}).setdefault(pn,[]).append((edge,tim,tail,up,sw/n*365,eq/n*365))
print(f"{'rule':30s} {'period':4s} edge/yr vs random exposure (median, baskets>0) | time on | worst-5% 14d starts while ON | best-5% while ON | switches/yr")
for nm,v in res.items():
    for pn in ("all","H1","H2"):
        rs=v.get(pn); 
        if not rs: continue
        e=[r[0] for r in rs]
        print(f"{nm:30s} {pn:4s} {S.median(e)*100:+6.1f}% ({sum(1 for x in e if x>0):2d}/{len(e)}) | {S.median([r[1] for r in rs])*100:3.0f}% | {S.median([r[2] for r in rs])*100:3.0f}% | {S.median([r[3] for r in rs])*100:3.0f}% | {S.median([r[4] for r in rs]):4.1f}")
