| """DeepQuant — deterministic rebalance engine (Phase 1: compute only, no execution). |
| |
| Reproduces the MarketFM Tactical target portfolio and diffs it against the live account in |
| DOLLARS, trading only the change. No order is placed here — compute_orders returns the list |
| the agent *would* submit. Execution (Phase 2) consumes this same output, guardrailed. |
| """ |
| import json |
| import os |
| import ssl |
| import urllib.request |
|
|
| import numpy as np |
| import pandas as pd |
| from huggingface_hub import hf_hub_download |
|
|
| try: |
| import certifi |
| _CTX = ssl.create_default_context(cafile=certifi.where()) |
| except Exception: |
| _CTX = ssl.create_default_context() |
|
|
| PANEL_REPO = os.environ.get("MARKETFM_REPO", "s-ttp/marketfm-panel") |
| AV = os.environ.get("ALPHAVANTAGE_API_KEY", "") |
| SEG_K, SECTOR_CAP, SIZE, MAX_W = 1000, 5, 50, 0.10 |
| DEF_EQ, DEF_AGG, DEF_GLD = 0.60, 0.20, 0.20 |
| ETF = {"AGG": ("iShares Core US Aggregate Bond ETF", "Bonds (ETF)"), |
| "GLD": ("SPDR Gold Shares", "Gold (ETF)")} |
|
|
|
|
| def cap_weights(w, mw=MAX_W): |
| w = np.asarray(w, float) |
| for _ in range(30): |
| over = w > mw + 1e-9 |
| if not over.any(): |
| break |
| excess = (w[over] - mw).sum() |
| w[over] = mw |
| under = ~over |
| if w[under].sum() <= 0: |
| break |
| w[under] += excess * w[under] / w[under].sum() |
| return w |
|
|
|
|
| def detect_regime(): |
| try: |
| u = f"https://www.alphavantage.co/query?function=TIME_SERIES_WEEKLY_ADJUSTED&symbol=SPY&apikey={AV}" |
| ts = json.load(urllib.request.urlopen(u, timeout=25, context=_CTX))["Weekly Adjusted Time Series"] |
| s = pd.Series({k: float(v["5. adjusted close"]) for k, v in ts.items()}).sort_index() |
| sma10, sma40 = s.rolling(10).mean().iloc[-1], s.rolling(40).mean().iloc[-1] |
| return {"offense": bool(sma10 >= sma40), "sma10": float(sma10), "sma40": float(sma40), "spy": float(s.iloc[-1])} |
| except Exception as e: |
| return {"offense": True, "sma10": None, "sma40": None, "spy": None, |
| "warn": f"SPY fetch failed ({type(e).__name__}); defaulting to OFFENSE"} |
|
|
|
|
| def equity_sleeve(token): |
| p = hf_hub_download(PANEL_REPO, "marketfm_snapshot.parquet", repo_type="dataset", token=token) |
| df = pd.read_parquet(p) |
| df = df[df["marketcap"].notna() & (df["marketcap"] > 0)].copy() |
| df = df.sort_values("marketcap", ascending=False).head(SEG_K) |
| df["score"] = df["n_mom_12_1"].fillna(0) + df["n_roe"].fillna(0) |
| df = df.sort_values("score", ascending=False) |
| picked, sec = [], {} |
| for _, r in df.iterrows(): |
| if sec.get(r["sector"], 0) >= SECTOR_CAP: |
| continue |
| sec[r["sector"]] = sec.get(r["sector"], 0) + 1 |
| picked.append(r) |
| if len(picked) >= SIZE: |
| break |
| mc = np.array([r["marketcap"] for r in picked], float) |
| w = cap_weights(mc / mc.sum()) |
| return [{"ticker": r["ticker"], "name": r.get("name"), "sector": r["sector"], "weight": float(wi)} |
| for r, wi in zip(picked, w)] |
|
|
|
|
| def get_target(token): |
| reg = detect_regime() |
| sleeve = equity_sleeve(token) |
| if reg["offense"]: |
| rows = [dict(x) for x in sleeve] |
| else: |
| rows = [dict(x, weight=DEF_EQ * x["weight"]) for x in sleeve] |
| for sym, (nm, sct) in ETF.items(): |
| rows.append({"ticker": sym, "name": nm, "sector": sct, |
| "weight": DEF_AGG if sym == "AGG" else DEF_GLD}) |
| weights = {r["ticker"]: r["weight"] for r in rows} |
| return {"regime": reg, "weights": weights, "rows": rows} |
|
|
|
|
| def compute_orders(weights, positions, equity, band_pct=0.005): |
| """positions: {symbol: market_value $}. Returns order list (sells first), trading only the delta.""" |
| band = band_pct * equity |
| orders = [] |
| for sym in set(weights) | set(positions): |
| tw = weights.get(sym, 0.0) |
| tgt = tw * equity |
| cur = positions.get(sym, 0.0) |
| delta = tgt - cur |
| cw = (cur / equity) if equity else 0.0 |
| if tw == 0 and cur > 0: |
| orders.append({"symbol": sym, "side": "SELL", "delta": -cur, "cur_w": cw, "tgt_w": 0.0, "exit": True}) |
| elif cur == 0 and tgt > 1.0: |
| orders.append({"symbol": sym, "side": "BUY", "delta": tgt, "cur_w": 0.0, "tgt_w": tw, "exit": False}) |
| elif abs(delta) < band: |
| continue |
| else: |
| orders.append({"symbol": sym, "side": "BUY" if delta > 0 else "SELL", |
| "delta": delta, "cur_w": cw, "tgt_w": tw, "exit": False}) |
| orders.sort(key=lambda o: (0 if o["side"] == "SELL" else 1, -abs(o["delta"]))) |
| return orders |
|
|