Files
Hanzo Dev a9804de11d world: rotation model research notebook (Hanzo Notebook)
A reproducible numpy/scipy reference implementation of the RRG rotation
model that powers the engine. Loads a 6-month daily snapshot of the
32-symbol universe (research/data), formalises RS-Ratio / RS-Momentum and
the quadrant classification, reproduces the current read and the Lux Book
top-10 allocation, and backtests the rotate-out-of-Weakening /
into-Improving thesis.

The numpy read cross-validates the Go engine exactly (Uranium 97.4/103.1,
Hyperscalers weakening 101.4/95.9, Great Rotation 0.55 WATCH). The backtest
is reported as indicative on a single window, not an alpha claim.

Executed notebook (rotation_model.ipynb) + percent-format source + the
data snapshot + the RRG plot.
2026-07-21 14:10:07 -07:00

40 lines
1.8 KiB
Python

"""Snapshot 6-month daily closes for the rotation universe from Yahoo.
Stdlib-only fetch → tidy CSV (date,symbol,close). Mirrors the Go engine's
universe so the notebook works on the exact same instruments.
"""
import json, time, urllib.request, urllib.parse, csv, sys, os
UNIVERSE = ["SPY","SMH","SOXX","NVDA","AMD","AVGO","SMCI","XLK","MSFT","GOOGL","META","AMZN",
"XLE","XOP","UNG","FCG","NG=F","URA","URNM","CCJ","VST","CEG","NRG","XLU",
"XLF","XLV","XLI","XLP","XLY","XLB","XLRE","XLC"]
UA = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"}
def fetch(sym):
url = "https://query1.finance.yahoo.com/v8/finance/chart/" + urllib.parse.quote(sym) + "?range=6mo&interval=1d"
req = urllib.request.Request(url, headers=UA)
with urllib.request.urlopen(req, timeout=15) as r:
d = json.load(r)
res = d["chart"]["result"][0]
ts = res["timestamp"]
close = res["indicators"]["quote"][0]["close"]
return [(t, c) for t, c in zip(ts, close) if c is not None]
def main():
rows = []
for sym in UNIVERSE:
for attempt in range(3):
try:
for t, c in fetch(sym):
rows.append((time.strftime("%Y-%m-%d", time.gmtime(t)), sym, round(c, 4)))
print(f" {sym}: ok", file=sys.stderr); break
except Exception as e:
print(f" {sym}: retry {attempt} ({e})", file=sys.stderr); time.sleep(1.5)
time.sleep(0.15)
out = os.path.join(os.path.dirname(__file__), "closes.csv")
with open(out, "w", newline="") as f:
w = csv.writer(f); w.writerow(["date","symbol","close"]); w.writerows(rows)
print(f"wrote {len(rows)} rows for {len(set(r[1] for r in rows))} symbols -> {out}", file=sys.stderr)
if __name__ == "__main__":
main()