Upload folder using huggingface_hub
Browse files- __pycache__/app.cpython-312.pyc +0 -0
- app.py +42 -24
__pycache__/app.cpython-312.pyc
CHANGED
|
Binary files a/__pycache__/app.cpython-312.pyc and b/__pycache__/app.cpython-312.pyc differ
|
|
|
app.py
CHANGED
|
@@ -37,28 +37,46 @@ def fetch_spy_daily():
|
|
| 37 |
return None
|
| 38 |
|
| 39 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
def build_curve():
|
|
|
|
| 41 |
try:
|
| 42 |
-
|
| 43 |
except Exception:
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
if len(pts) < 2:
|
| 48 |
-
return None
|
| 49 |
rows = [{"date": d, "series": "DeepQuant (paper)", "value": round(v, 2)} for d, v in pts]
|
| 50 |
-
|
| 51 |
-
spy = fetch_spy_daily()
|
| 52 |
-
if spy:
|
| 53 |
-
in_range = {d: px for d, px in spy.items() if d >= d0}
|
| 54 |
-
if in_range:
|
| 55 |
-
first = spy[min(in_range)]
|
| 56 |
-
for d, px in sorted(in_range.items()):
|
| 57 |
-
rows.append({"date": dt.datetime.combine(d, dt.time()), "series": "S&P 500 (SPY)",
|
| 58 |
-
"value": round(base_eq * px / first, 2)})
|
| 59 |
-
df = pd.DataFrame(rows)
|
| 60 |
-
df["date"] = pd.to_datetime(df["date"]).astype("datetime64[ns]")
|
| 61 |
-
return df
|
| 62 |
|
| 63 |
|
| 64 |
def refresh():
|
|
@@ -99,13 +117,12 @@ def refresh():
|
|
| 99 |
"Unrealized P&L": f'${float(p["unrealized_pl"]):,.2f} ({float(p["unrealized_plpc"]) * 100:+.1f}%)',
|
| 100 |
})
|
| 101 |
df = pd.DataFrame(rows) if rows else pd.DataFrame([{"Symbol": "— no open positions —"}])
|
| 102 |
-
curve = build_curve()
|
|
|
|
| 103 |
if curve is None:
|
| 104 |
-
return (summary, df, gr.update(visible=False),
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
return (summary, df, gr.update(value=curve, visible=True), gr.update(visible=False),
|
| 108 |
-
f"_Last updated {now} · auto-refreshes every 30 min_")
|
| 109 |
|
| 110 |
|
| 111 |
def load_rebalance():
|
|
@@ -113,7 +130,8 @@ def load_rebalance():
|
|
| 113 |
if not tok:
|
| 114 |
return ""
|
| 115 |
try:
|
| 116 |
-
log = json.load(open(hf_hub_download("s-ttp/marketfm-panel", "deepquant_log.json", repo_type="dataset",
|
|
|
|
| 117 |
if not log:
|
| 118 |
return ""
|
| 119 |
e = log[-1]
|
|
|
|
| 37 |
return None
|
| 38 |
|
| 39 |
|
| 40 |
+
def _curve_pts(h):
|
| 41 |
+
ts, eqv = h.get("timestamp", []), h.get("equity", [])
|
| 42 |
+
return [(dt.datetime.fromtimestamp(t, dt.timezone.utc).replace(tzinfo=None), v) for t, v in zip(ts, eqv) if v]
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
def _mk_df(rows):
|
| 46 |
+
df = pd.DataFrame(rows)
|
| 47 |
+
df["date"] = pd.to_datetime(df["date"]).astype("datetime64[ns]")
|
| 48 |
+
return df
|
| 49 |
+
|
| 50 |
+
|
| 51 |
def build_curve():
|
| 52 |
+
"""Returns (dataframe_or_None, note). Daily DeepQuant-vs-SPY once there's history; intraday today for a young account."""
|
| 53 |
try:
|
| 54 |
+
pts = _curve_pts(ac.get_portfolio_history("1M", "1D"))
|
| 55 |
except Exception:
|
| 56 |
+
pts = []
|
| 57 |
+
if len(pts) >= 4: # enough daily history → DeepQuant vs SPY
|
| 58 |
+
base = pts[0][1]
|
| 59 |
+
rows = [{"date": d, "series": "DeepQuant (paper)", "value": round(v, 2)} for d, v in pts]
|
| 60 |
+
spy = fetch_spy_daily()
|
| 61 |
+
if spy:
|
| 62 |
+
sd = sorted(spy)
|
| 63 |
+
first = None
|
| 64 |
+
for d, _v in pts:
|
| 65 |
+
prior = [x for x in sd if x <= d.date()]
|
| 66 |
+
if not prior:
|
| 67 |
+
continue
|
| 68 |
+
px = spy[prior[-1]]
|
| 69 |
+
first = first or px
|
| 70 |
+
rows.append({"date": d, "series": "S&P 500 (SPY)", "value": round(base * px / first, 2)})
|
| 71 |
+
return _mk_df(rows), ""
|
| 72 |
+
try: # young account → today's intraday equity
|
| 73 |
+
pts = _curve_pts(ac.get_portfolio_history("1D", "15Min"))
|
| 74 |
+
except Exception:
|
| 75 |
+
pts = []
|
| 76 |
if len(pts) < 2:
|
| 77 |
+
return None, "Equity curve builds once the account has trading history."
|
| 78 |
rows = [{"date": d, "series": "DeepQuant (paper)", "value": round(v, 2)} for d, v in pts]
|
| 79 |
+
return _mk_df(rows), "Today's intraday equity — the daily curve vs the S&P 500 fills in over the coming sessions."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
|
| 82 |
def refresh():
|
|
|
|
| 117 |
"Unrealized P&L": f'${float(p["unrealized_pl"]):,.2f} ({float(p["unrealized_plpc"]) * 100:+.1f}%)',
|
| 118 |
})
|
| 119 |
df = pd.DataFrame(rows) if rows else pd.DataFrame([{"Symbol": "— no open positions —"}])
|
| 120 |
+
curve, cnote = build_curve()
|
| 121 |
+
stamp = f"_Last updated {now} · auto-refreshes every 30 min_"
|
| 122 |
if curve is None:
|
| 123 |
+
return (summary, df, gr.update(visible=False), gr.update(value=f"_{cnote}_", visible=True), stamp)
|
| 124 |
+
note_upd = gr.update(value=f"_{cnote}_", visible=True) if cnote else gr.update(visible=False)
|
| 125 |
+
return (summary, df, gr.update(value=curve, visible=True), note_upd, stamp)
|
|
|
|
|
|
|
| 126 |
|
| 127 |
|
| 128 |
def load_rebalance():
|
|
|
|
| 130 |
if not tok:
|
| 131 |
return ""
|
| 132 |
try:
|
| 133 |
+
log = json.load(open(hf_hub_download("s-ttp/marketfm-panel", "deepquant_log.json", repo_type="dataset",
|
| 134 |
+
token=tok, force_download=True)))
|
| 135 |
if not log:
|
| 136 |
return ""
|
| 137 |
e = log[-1]
|