import sys; sys.path.insert(0,'/workspace/research/buyer-method-audit/scripts'); from lib import lot import pandas as pd,numpy as np; from scipy import stats T=pd.read_csv('results/trail50_trades.csv',parse_dates=['date']); T=T[T.status=='ok']; T['rs']=T.pnl*T.date.map(lot) RR=pd.read_csv('results/trail50_random.csv',parse_dates=['date','src_date']); rng=np.random.default_rng(7) def summ(x): x=x.sort_values('date'); p=x.pnl; w=p[p>0]; l=p[p<=0]; cum=x.rs.cumsum().values dd=(cum-np.maximum.accumulate(np.r_[0,cum])[1:]).min() if len(x) else np.nan mon=x.groupby(x.date.dt.to_period('M')).rs.sum() return dict(n=len(p),mean=p.mean(),median=p.median(),win=(p>0).mean()*100,avg_win=w.mean(),avg_loss=l.mean(),payoff=w.mean()/abs(l.mean()) if len(w) and len(l) else np.nan, rs_per_trade=x.rs.mean(),rs_total=x.rs.sum(),maxdd_rs=dd,worst_month=str(mon.idxmin()) if len(mon) else '',worst_month_rs=mon.min() if len(mon) else np.nan, t_p_one=stats.ttest_1samp(p,0,alternative='greater').pvalue if len(p)>2 else np.nan) def rnd(x,cand,mode): R=RR[(RR.cand==cand)&(RR['mode']==mode)]; G={k:g.pnl.values for k,g in R.groupby('src_date')}; arrs=[G[d] for d in x.date if d in G] if not arrs: return np.nan,np.nan ms=np.array([np.mean([a[rng.integers(len(a))] for a in arrs]) for _ in range(2000)]); return np.mean(np.concatenate(arrs)),(ms0).mean()*100),rs=('rs','sum')).round(1).reset_index(); Y.to_csv('results/trail50_by_year.csv',index=False); print(Y.to_string()) pr.groupby(['cand','ym']).agg(n=('pnl','size'),mean=('pnl','mean'),rs=('rs','sum')).round(1).reset_index().to_csv('results/trail50_by_month.csv',index=False) # sensitivity (spot, ATM) s=T[(T['mode']=='spot')&(T.inst=='ATM')].groupby(['cand','act','lock','split']).pnl.agg(['count','mean']).round(2).unstack().reset_index(); s.columns=['_'.join(map(str,c)).strip('_') for c in s.columns]; s.to_csv('results/trail50_sensitivity.csv',index=False); print(s.to_string()) # old exits (E0..E4) vs trail on same trades, REAL G=pd.read_csv('results/grid_all_exits_scen.csv'); G=G[G.scen=='REAL'].pivot_table(index='cand',columns=['split','ex'],values='mean') tr=P[(P['mode']=='spot')&(P.inst=='ATM')].pivot(index='cand',columns='split',values='mean') cmp=pd.DataFrame({'train_best_old':G['train'].max(axis=1),'train_E0':G['train']['E0'],'train_trail50':tr['train'],'test_E0':G['test']['E0'],'test_trail50':tr['test']}).round(2).reset_index(); cmp.to_csv('results/trail50_vs_old.csv',index=False); print(cmp.to_string()) # spot capture ORB SPX=pd.read_csv('results/trail50_spot_proxy.csv',parse_dates=['date']); SPX=SPX[(SPX.act==2.0)&(SPX.lock==0.5)] F=pd.read_csv('results/trail50_spot_proxy_full.csv',parse_dates=['date']); F['year']=F.date.dt.year fy=F.groupby(['cand','year']).spot_pts.mean().unstack().round(1); fy['all']=F.groupby('cand').spot_pts.mean().round(1); fy['p']=F.groupby('cand').spot_pts.apply(lambda v:stats.ttest_1samp(v.dropna(),0).pvalue).round(3); print(fy.to_string()); fy.reset_index().to_csv('results/trail50_spot_proxy_by_year.csv',index=False) cap=[] for c in ['B15','B30']: for inst in ['ATM']: x=T[(T.cand==c)&(T['mode']=='spot')&(T.inst==inst)&(T.act==2.0)&(T.lock==0.5)].merge(SPX[SPX.cand==c][['date','spot_pts']],on='date') for sp,g in x.groupby('split'): cap.append(dict(cand=c,inst=inst,split=sp,n=len(g),spot_pts=g.spot_pts.mean(),opt_gross_ex_slip=(g.gross+1.0).mean(),net=g.pnl.mean(),capture_pct=(g.gross+1.0).mean()/g.spot_pts.mean()*100)) for lab in ['ITM2','ITM4']: x=T[(T.cand=='L'+c[1:])&(T.inst==lab)].merge(SPX[SPX.cand==c][['date','spot_pts']],on='date') for sp,g in x.groupby('split'): cap.append(dict(cand='L'+c[1:]+' (puts)',inst=lab,split=sp,n=len(g),spot_pts=g.spot_pts.mean(),opt_gross_ex_slip=(g.gross+1.0).mean(),net=g.pnl.mean(),capture_pct=(g.gross+1.0).mean()/g.spot_pts.mean()*100)) CP=pd.DataFrame(cap).round(2); CP.to_csv('results/trail50_spot_capture.csv',index=False); print(CP.to_string()) print(T[(T['mode']=='spot')&(T.act==2)&(T.lock==.5)&(T.inst=='ATM')].why.value_counts())