| """Option 2 sample (pre-registered 2026-10-05): 90 trigger candidates + 90 controls, shuffled, anonymised, key kept apart.
|
| Triggers: spring&prior-1 / utad&prior+1 / sos / sow, badvol=0, thinned >=48h per symbol, 2010-2024.
|
| Controls: box bars with no trigger, thinned. Equal draw per class. Judge sees chart only; outcome columns never shown."""
|
| import os, sys, numpy as np, pandas as pd
|
| sys.path.insert(0, os.path.dirname(__file__))
|
| import discover as D, wyckoff_gold as G, wyckoff_scan as S
|
| L = pd.read_csv("wyckoff_ledger.csv", parse_dates=["t"]); L = L[(L.badvol == 0) & (L.t.dt.year >= 2010)]
|
| trig = ((L.spring == 1) & (L.prior == -1)) | ((L.utad == 1) & (L.prior == 1)) | (L.sos == 1) | (L.sow == 1)
|
| T = pd.concat([S.thin(g) for _, g in L[trig].groupby("sym")])
|
| C = pd.concat([S.thin(g) for _, g in L[~trig].groupby("sym")])
|
| print("trigger pool", len(T), "control pool", len(C))
|
| rng = np.random.default_rng(2026)
|
| T = T.iloc[rng.choice(len(T), 90, replace=False)].assign(kind="trig")
|
| C = C.iloc[rng.choice(len(C), 90, replace=False)].assign(kind="ctl")
|
| A = pd.concat([T, C]).sample(frac=1, random_state=5).reset_index(drop=True)
|
| d = os.path.join(G.OUT, "judge"); os.makedirs(d, exist_ok=True)
|
| cache = {}
|
| for i, r in A.iterrows():
|
| h = cache.setdefault(r.sym, D.load_h1(r.sym))
|
| k = h.index.get_loc(r.t)
|
| G.render(h.iloc[k - G.W + 1:k + 1], os.path.join(d, f"{i:03d}.png"))
|
| A.insert(0, "id", [f"{i:03d}" for i in range(len(A))]); A.to_csv(os.path.join(d, "_key.csv"), index=False)
|
| print(len(A), "charts", d)
|