"""day_split_mc (k trades a day, plain barriers) against exact references.  k=1 has an exact chain (no clips); k>1 is checked against an independent per-day DP."""
from pa_imp import *
import numpy as np
g=PA.cost_share(34.791728647093755); r=0.03; c=g*r
ex=PA.eval_chain(r,c,rr=1.0,clip_up=False,clip_dn=False)
mc=PA.day_split_mc(1,r,c,n=5000,seed=3)
print(f"k=1 3% plain barriers (cost share {g:.4%}): eval_chain {ex['p_pass']:.4f} (E trades {ex['e_trades']:.2f}); day_split_mc n=5000 {mc['p_pass']:.4f} ± {np.sqrt(mc['p_pass']*(1-mc['p_pass'])/5000):.4f} trades {mc['trades']:.2f}")
# independent DP for k trades a day, rule 'loss' (day ends at first loss) or 'win'; lattice unit = c/40
def dp(k,risk,rule,T=0.09,D=0.09,daily=0.05):
    U=40/c if False else 40/(g*risk)
    iC=40; iR=round(risk*U); iD=round(D*U); iT=round(T*U); iDaily=daily*U
    # day outcomes: sequence until stop-rule or k trades
    outs=[]   # (delta, prob)
    def rec(j,delta,prob):
        if j==k: outs.append((delta,prob)); return
        for win in (True,False):
            d=delta+(iR if win else -iR)-iC
            stop=(not win) if rule=='loss' else win
            if stop or j+1==k: outs.append((d,prob*0.5))
            else: rec(j+1,d,prob*0.5)
    # careful: rec above must branch properly
    outs=[]
    def go(j,delta,prob):
        for win in (True,False):
            d=delta+(iR if win else -iR)-iC
            stop=(not win) if rule=='loss' else win
            if stop or j+1==k: outs.append((d,prob*0.5))
            else: go(j+1,d,prob*0.5)
    go(0,0,1.0)
    v={0:1.0}; pp=0; days=0.0; n=0
    while v and n<3000:
        n+=1; nv={}
        for s,p in v.items():
            for d,q in outs:
                t=s+d
                dly=(-d)>iDaily*(1+s/U)+1e-9
                if dly or t<=-iD: continue
                if t>=iT: pp+=p*q; days+=n*p*q
                else: nv[t]=nv.get(t,0)+p*q
        v={a:b for a,b in nv.items() if b>1e-15}
    return pp,days/pp
for k,rule in ((2,'loss'),(2,'win'),(3,'loss')):
    risk={'loss':0.35*0.09,'win':0.05*(1-0.09)/(1+g)}[rule]/k
    c=g*risk
    mc=PA.day_split_mc(k,risk,c,rule,n=5000,seed=3)
    pp,dd=dp(k,risk,rule)
    print(f"k={k} {rule}: risk {risk:.4%}  day_split_mc(5000) pass {mc['p_pass']:.4f} days {mc['days_pass']:.1f} | independent DP pass {pp:.4f} days {dd:.1f}")
