import pandas as pd,numpy as np from scipy.stats import mannwhitneyu,ttest_1samp R='/workspace/research/flow-forensics-2026-10/recov' C=pd.read_csv(f'{R}/results/candidates_scored.csv',parse_dates=['date']) T=pd.read_csv(f'{R}/results/trades_all.csv',parse_dates=['date']) cand=T[T.kind=='candidate'].merge(C[['rule_A_hypothesis','rule_B_train_top3_all','rule_B_train_top2','test','y200']],left_on='idx',right_index=True) rnd=T[T.kind=='random'] rng=np.random.default_rng(5); out=[] groups={'all_candidates':cand.index==cand.index,'rule_B_top3':cand.rule_B_train_top3_all,'rule_B_top2':cand.rule_B_train_top2,'rule_A_hypothesis':cand.rule_A_hypothesis} for gname,m in groups.items(): for sp,sm in [('train',~cand.test),('test',cand.test),('all',cand.test|~cand.test)]: for (er,st),g in cand[m&sm].groupby(['expiry_rule','style']): rp=rnd[(rnd.expiry_rule==er)&(rnd['style']==st)].pnl.values if len(rp)==0 or len(g)==0: print("EMPTY",gname,sp,er,st,len(g)); continue boots=np.array([rng.choice(rp,len(g)).mean() for _ in range(3000)]) out.append(dict(group=gname,split=sp,expiry_rule=er,style=st,n=len(g),mean_pts=g.pnl.mean(),median_pts=g.pnl.median(),win_pct=(g.pnl>0).mean()*100, total_rs_1lot=g.pnl_rs_lot.sum(),mean_rs_1lot=g.pnl_rs_lot.mean(),avg_cost_pts=g.cost.mean(),random_mean=rp.mean(),pctile_vs_random=(boots0).mean()*100),rs=('pnl_rs_lot','sum')).round(1); print(Y.to_string()); Y.to_csv(f'{R}/results/ruleB_trades_by_year.csv') M=b[b['style']=='spotstop'].groupby('ym').agg(n=('pnl','size'),mean_pts=('pnl','mean'),rs=('pnl_rs_lot','sum')).round(1); print(M.to_string()); M.to_csv(f'{R}/results/ruleB_trades_by_month_spotstop.csv') print(cand[(cand.date>='2026-10-26')][['date','hm','expiry_rule','style','fill','gross','cost','pnl','pnl_rs_lot']].round(2).to_string())