36 lines
2.1 KiB
Python
36 lines
2.1 KiB
Python
|
|
import kit,numpy as np,sys,datetime as dt
|
||
|
|
sys.stdout.reconfigure(encoding='utf-8',errors='replace')
|
||
|
|
from sklearn.ensemble import HistGradientBoostingClassifier
|
||
|
|
sym,tf,sl,tp,H,mn=("EURUSD","16385",2,3,48,1999)
|
||
|
|
t,o,h,l,c,v,sp=kit.load_rates(sym,tf)
|
||
|
|
k=np.array([dt.datetime.fromtimestamp(x,dt.UTC).year for x in t])>=mn
|
||
|
|
t,o,h,l,c,v,sp=[a[k] for a in (t,o,h,l,c,v,sp)]
|
||
|
|
X,names,a=kit.features(t,o,h,l,c,v)
|
||
|
|
diffs=np.abs(np.diff(np.unique(np.round(c,6)))); tick=np.median(diffs[diffs>0])
|
||
|
|
y,valid=kit.barrier_vec(h,l,c,a,sl,tp,H,np.median(sp)*tick)
|
||
|
|
n=len(y); idx=np.arange(n); be=100*sl/(sl+tp)
|
||
|
|
prob=np.full((n,3),np.nan); fold=np.full(n,-1)
|
||
|
|
bounds=np.linspace(int(n*0.35),n,6).astype(int)
|
||
|
|
for f in range(5):
|
||
|
|
te0,te1=bounds[f],bounds[f+1]
|
||
|
|
te=(idx>=te0)&(idx<te1)&valid; tr=(idx<te0-H)&valid
|
||
|
|
m=HistGradientBoostingClassifier(max_iter=200,learning_rate=0.06,max_depth=6,
|
||
|
|
l2_regularization=1.0,random_state=0).fit(X[tr],y[tr])
|
||
|
|
prob[te]=m.predict_proba(X[te]); fold[te]=f
|
||
|
|
print(f"EURUSD H1 {sl}:{tp} h{H} break-even {be:.1f}% bars={n} ({dt.datetime.fromtimestamp(t[0],dt.UTC).year}-{dt.datetime.fromtimestamp(t[-1],dt.UTC).year})")
|
||
|
|
print("ALL thresholds, no selection:\n")
|
||
|
|
print(f" {'thr':>5}{'trades':>8}{'win%':>8}{'edge':>8}{'sigma':>8} per-fold win%")
|
||
|
|
for thr in (0.35,0.40,0.45,0.50,0.55,0.60):
|
||
|
|
tr_i=[];j=0
|
||
|
|
while j<n:
|
||
|
|
if fold[j]<0 or not np.isfinite(prob[j,0]): j+=1; continue
|
||
|
|
p=prob[j];pr=int(np.argmax(p))
|
||
|
|
if pr==2 or float(np.max(p))<thr: j+=1; continue
|
||
|
|
tr_i.append((pr==y[j],fold[j]));j+=H
|
||
|
|
if len(tr_i)<50: print(f" {thr:>5.2f}{len(tr_i):>8} too few"); continue
|
||
|
|
w=np.array([x[0] for x in tr_i]);fo=np.array([x[1] for x in tr_i])
|
||
|
|
wr=100*w.mean();nT=len(w);se=100*np.sqrt((be/100)*(1-be/100)/nT)
|
||
|
|
pf=" ".join(f"{100*w[fo==f].mean():5.1f}" for f in range(5) if (fo==f).sum()>=15)
|
||
|
|
print(f" {thr:>5.2f}{nT:>8}{wr:>8.2f}{wr-be:>+8.2f}{(wr-be)/se:>+8.2f} {pf}")
|
||
|
|
print("\nsigma is vs break-even on INDEPENDENT trades. 6 thresholds tested here, 48 across the")
|
||
|
|
print("whole sweep - so a single +1.5s reading is what selection alone produces.")
|