forked from mnbvc188199/Warrior_EA
55 lines
2.5 KiB
Python
55 lines
2.5 KiB
Python
"""
| |
Gold-set generator for Wyckoff structure labelling (2026-10-05).
| |
| |
Each sample = the last W H1 bars ending at a decision bar t. CAUSAL: nothing after t is drawn, so a
| |
labeller (a vision model or a human) sees exactly what a trader sees at t. ANONYMOUS: no dates, no
| |
symbol, price rescaled to ATR units from the window's first close, volume to the window's median, so
| |
the labeller cannot recall the history. The key (symbol, timestamp) goes to a separate CSV.
| |
Sealed: nothing dated >= 2025-01-01 is ever sampled.
| |
python wyckoff_gold.py SP500,NAS100 40 pilot # symbols, n per symbol, set name
| |
"""
| |
import os, sys, numpy as np, pandas as pd
| |
import matplotlib; matplotlib.use("Agg")
| |
import matplotlib.pyplot as plt
| |
sys.path.insert(0, os.path.dirname(__file__))
| |
import discover as D
| |
| |
W = 120
| |
OUT = os.path.join(os.path.dirname(__file__), "wyckoff_gold")
| |
| |
| |
def render(b: pd.DataFrame, path: str):
| |
c0 = b.c.iloc[0]
| |
atr = (b.h - b.l).rolling(14, min_periods=1).mean().iloc[-1]
| |
sc = lambda x: (x - c0) / atr
| |
v = b.tv / b.tv.median()
| |
fig, (a, v_ax) = plt.subplots(2, 1, figsize=(11, 6.5), sharex=True, gridspec_kw={"height_ratios": [3, 1]})
| |
x = np.arange(len(b))
| |
up = b.c >= b.o
| |
a.vlines(x, sc(b.l), sc(b.h), color="k", lw=0.8)
| |
a.bar(x, (sc(b.c) - sc(b.o)).abs().clip(lower=0.02), bottom=np.minimum(sc(b.o), sc(b.c)), width=0.7,
| |
color=np.where(up, "#2a9d4a", "#d62f2f"))
| |
a.set_ylabel("price (ATR units)"); a.grid(alpha=.25)
| |
v_ax.bar(x, v, color=np.where(up, "#2a9d4a", "#d62f2f"), width=0.8); v_ax.set_ylabel("rel. volume")
| |
v_ax.set_xlabel("bar (last bar = now; nothing to the right exists)"); v_ax.grid(alpha=.25)
| |
fig.tight_layout(); fig.savefig(path, dpi=80); plt.close(fig)
| |
| |
| |
def main():
| |
syms = sys.argv[1].split(","); n = int(sys.argv[2]); name = sys.argv[3]
| |
d = os.path.join(OUT, name); os.makedirs(d, exist_ok=True)
| |
rng = np.random.default_rng(int(os.environ.get("SEED","7"))); key = []
| |
for s in syms:
| |
h = D.load_h1(s); h = h[h.index < D.SEAL]
| |
# event-driven sampling: decision bars where price moved >=2 ATR from the 20-bar mean or at random
| |
idx = rng.choice(np.arange(W, len(h)), n, replace=False)
| |
for i in sorted(idx):
| |
sid = f"{len(key):04d}"
| |
render(h.iloc[i - W + 1:i + 1], os.path.join(d, sid + ".png"))
| |
key.append((sid, s, h.index[i], h.c.iloc[i]))
| |
pd.DataFrame(key, columns=["id", "sym", "t", "close"]).to_csv(os.path.join(d, "_key.csv"), index=False)
| |
print(len(key), "charts ->", d)
| |
| |
| |
if __name__ == "__main__":
| |
main()
|