import numpy as np, pandas as pd, os, sys import matplotlib; matplotlib.use("Agg") import matplotlib.pyplot as plt import discover as D z=np.load(os.path.join(D.CACHE,"mining.npz")); r=pd.read_pickle(os.path.join(D.CACHE,"mining_table.pkl")) lab,Y,U,Dn,S,T,P,R,V=(z[k] for k in ["lab","Y","U","Dn","S","T","P","R","V"]) x=np.r_[np.arange(-95,-23,6)+2.5, np.arange(-23,1)] # bar offsets: 12 bins of 6, then last 24 out=[] picks=[] for d in ("UP","DOWN"): g=r[(r["dir"]==d)].sort_values("both",ascending=False).head(3) picks+= [(d,int(c),row) for c,(_,row) in zip(g.cl,g.iterrows())] fig,ax=plt.subplots(len(picks),3,figsize=(13,2.6*len(picks))) for i,(d,c,row) in enumerate(picks): m=lab==c base=np.ones(len(lab),bool) for j,(arr,t,ref) in enumerate([(P,"price vs now (ATR)",None),(R,"bar range (ATR)",R.mean(0)),(np.clip(V,0,10),"volume / 100-bar mean",np.clip(V,0,10).mean(0))]): a=ax[i,j] a.plot(x,arr[m].mean(0),lw=2,label="cluster") a.plot(x,arr.mean(0),lw=1,ls="--",color="grey",label="all bars") if j==0: a.set_title(f"{d} cl{c}: P(big {d.lower()})={row.p_te:.0%} vs base {row.base_te:.0%} (x{row.lift_te:.2f} test, x{row.lift_tr:.2f} train)",fontsize=8,loc="left") else: a.set_title(t,fontsize=8,loc="left") a.axvline(0,color="k",lw=.5) hs=np.bincount(T[m,0],minlength=24)/m.sum()/ (np.bincount(T[:,0],minlength=24)/len(T)) mix=pd.Series(S[m]).value_counts(normalize=True).head(3) top_h=np.argsort(hs)[::-1][:3] dw=np.bincount(T[m,1],minlength=5)/m.sum()/(np.bincount(T[:,1],minlength=5)/len(T)) print(f"{d} cl{c}: n={m.sum()} mix={dict(mix.round(2))} enriched hours(x)={[(int(h),round(float(hs[h]),1)) for h in top_h]} dow(M..F) x={dw.round(2).tolist()}") plt.tight_layout(); p=os.path.join(os.path.dirname(D.CACHE),"patterns.png"); plt.savefig(p,dpi=70); print(p)