chart: chain-link frozen predecessor-account history across brokerage re-provisioning
Browse files
app.py
CHANGED
|
@@ -62,17 +62,41 @@ def fetch_spy_intraday():
|
|
| 62 |
return None
|
| 63 |
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
def build_curve():
|
| 66 |
"""Returns (dataframe_or_None, note). Daily fund-vs-SPY once there's history; intraday today (both lines) for a young account."""
|
| 67 |
try:
|
| 68 |
daily = _curve_pts(ac.get_portfolio_history("1A", "1D")) # full history since inception, not a trailing window
|
| 69 |
except Exception:
|
| 70 |
daily = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
if len(daily) >= 4: # enough daily history → daily fund vs SPY
|
| 72 |
-
# Alpaca stamps each session's closing equity at 00:00 UTC of the NEXT day (= 8 PM ET),
|
| 73 |
-
# which renders every close ~80% of the way toward the following day's axis tick
|
| 74 |
-
# (Friday's close shows up under "Saturday"). Snap each point to its trading date.
|
| 75 |
-
daily = [(dt.datetime.combine(d.date(), dt.time.min), v) for d, v in daily]
|
| 76 |
base = daily[0][1]
|
| 77 |
rows = [{"date": d, "series": "DeepQuant (paper)", "value": round(v, 2)} for d, v in daily]
|
| 78 |
spy = fetch_spy_daily()
|
|
@@ -85,7 +109,7 @@ def build_curve():
|
|
| 85 |
px = spy[prior[-1]]
|
| 86 |
first = first or px
|
| 87 |
rows.append({"date": d, "series": "S&P 500 (SPY)", "value": round(base * px / first, 2)})
|
| 88 |
-
return _mk_df(rows),
|
| 89 |
try: # young account → today's intraday, fund AND SPY
|
| 90 |
intr = _curve_pts(ac.get_portfolio_history("1D", "15Min"))
|
| 91 |
except Exception:
|
|
|
|
| 62 |
return None
|
| 63 |
|
| 64 |
|
| 65 |
+
def _frozen_history():
|
| 66 |
+
"""Frozen daily-equity record of the predecessor brokerage account (closed Oct 2026).
|
| 67 |
+
The fund's history must not depend on any one brokerage account surviving — the live
|
| 68 |
+
curve is this frozen record plus the current account's history, chain-linked."""
|
| 69 |
+
try:
|
| 70 |
+
h = json.load(open(hf_hub_download("s-ttp/marketfm-panel", "deepquant_live_history.json",
|
| 71 |
+
repo_type="dataset", token=os.environ.get("HF_TOKEN"), force_download=True)))
|
| 72 |
+
return [(dt.datetime.fromisoformat(d), float(v)) for d, v in h["daily_equity"]]
|
| 73 |
+
except Exception:
|
| 74 |
+
return []
|
| 75 |
+
|
| 76 |
+
|
| 77 |
def build_curve():
|
| 78 |
"""Returns (dataframe_or_None, note). Daily fund-vs-SPY once there's history; intraday today (both lines) for a young account."""
|
| 79 |
try:
|
| 80 |
daily = _curve_pts(ac.get_portfolio_history("1A", "1D")) # full history since inception, not a trailing window
|
| 81 |
except Exception:
|
| 82 |
daily = []
|
| 83 |
+
# Alpaca stamps each session's closing equity at 00:00 UTC of the NEXT day (= 8 PM ET),
|
| 84 |
+
# which renders every close ~80% of the way toward the following day's axis tick
|
| 85 |
+
# (Friday's close shows up under "Saturday"). Snap each point to its trading date.
|
| 86 |
+
daily = [(dt.datetime.combine(d.date(), dt.time.min), v) for d, v in daily]
|
| 87 |
+
note = ""
|
| 88 |
+
frozen = _frozen_history()
|
| 89 |
+
if frozen:
|
| 90 |
+
splice = frozen[-1][0]
|
| 91 |
+
new = [(d, v) for d, v in daily if d > splice]
|
| 92 |
+
# chain-link: the successor account restarts at its own funding value, so scale its
|
| 93 |
+
# curve so that its first point continues the frozen record's last close exactly
|
| 94 |
+
daily = frozen + ([(d, v * frozen[-1][1] / new[0][1]) for d, v in new] if new else [])
|
| 95 |
+
note = ("Chain-linked series: the brokerage account was re-provisioned in Oct 2026; "
|
| 96 |
+
"history is the predecessor account's actual record, and the successor's curve is "
|
| 97 |
+
"linked at the splice so fund performance is continuous. Account value shown may "
|
| 98 |
+
"therefore differ from the raw successor-account balance.")
|
| 99 |
if len(daily) >= 4: # enough daily history → daily fund vs SPY
|
|
|
|
|
|
|
|
|
|
|
|
|
| 100 |
base = daily[0][1]
|
| 101 |
rows = [{"date": d, "series": "DeepQuant (paper)", "value": round(v, 2)} for d, v in daily]
|
| 102 |
spy = fetch_spy_daily()
|
|
|
|
| 109 |
px = spy[prior[-1]]
|
| 110 |
first = first or px
|
| 111 |
rows.append({"date": d, "series": "S&P 500 (SPY)", "value": round(base * px / first, 2)})
|
| 112 |
+
return _mk_df(rows), note
|
| 113 |
try: # young account → today's intraday, fund AND SPY
|
| 114 |
intr = _curve_pts(ac.get_portfolio_history("1D", "15Min"))
|
| 115 |
except Exception:
|