Jitendra12421 commited on
Commit
b8a054e
·
verified ·
1 Parent(s): 54824a6

Upload 38 files

Browse files
Files changed (1) hide show
  1. runtime.py +64 -22
runtime.py CHANGED
@@ -1244,25 +1244,7 @@ def load_tplus1_test_predictions() -> pd.DataFrame:
1244
  return df.sort_values("date").reset_index(drop=True)
1245
 
1246
 
1247
- def sync_mfe_outputs() -> bool:
1248
- """Refresh bundled MFE artifacts from the forecasting project when available."""
1249
- if not MFE_SOURCE_OUTPUT_DIR.exists():
1250
- return MFE_SUMMARY_PATH.exists()
1251
- MFE_OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
1252
- synced = False
1253
- for name in ("summary.json", "latest_prediction.csv", "test_predictions.csv"):
1254
- source = MFE_SOURCE_OUTPUT_DIR / name
1255
- target = MFE_OUTPUT_DIR / name
1256
- if not source.exists():
1257
- continue
1258
- if not target.exists() or source.stat().st_mtime > target.stat().st_mtime:
1259
- target.write_bytes(source.read_bytes())
1260
- synced = True
1261
- return synced or MFE_SUMMARY_PATH.exists()
1262
-
1263
-
1264
  def load_mfe_summary() -> dict[str, Any]:
1265
- sync_mfe_outputs()
1266
  if not MFE_SUMMARY_PATH.exists():
1267
  return {}
1268
  try:
@@ -1272,7 +1254,6 @@ def load_mfe_summary() -> dict[str, Any]:
1272
 
1273
 
1274
  def load_mfe_latest() -> dict[str, Any]:
1275
- sync_mfe_outputs()
1276
  summary = load_mfe_summary()
1277
  if MFE_LATEST_PATH.exists():
1278
  try:
@@ -1280,7 +1261,7 @@ def load_mfe_latest() -> dict[str, Any]:
1280
  up_pts = float(row.get("predicted_up_points", summary.get("latest_predicted_up_points", 0)))
1281
  down_pts = float(row.get("predicted_down_points", summary.get("latest_predicted_down_points", 0)))
1282
  return {
1283
- "input_date": str(row.get("input_date") or summary.get("latest_input_date", ""))[:10],
1284
  "first5_start": row.get("first5_start") or summary.get("latest_first5_start"),
1285
  "first5_end": row.get("first5_end") or summary.get("latest_first5_end"),
1286
  "first5_close": float(row.get("first5_close") or summary.get("latest_first5_close") or 0),
@@ -1306,7 +1287,6 @@ def load_mfe_latest() -> dict[str, Any]:
1306
 
1307
 
1308
  def load_mfe_backtest() -> pd.DataFrame:
1309
- sync_mfe_outputs()
1310
  if not MFE_TEST_PREDICTIONS_PATH.exists():
1311
  return pd.DataFrame()
1312
  frame = pd.read_csv(MFE_TEST_PREDICTIONS_PATH)
@@ -1697,6 +1677,58 @@ def refresh_first5_prediction(session_date: date | None = None, minutes: pd.Data
1697
  return prediction
1698
 
1699
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1700
  def refresh_daily_data() -> dict[str, Any]:
1701
  daily = fetch_yahoo_daily(period="1mo")
1702
  combined = append_parquet_rows(NIFTY_1D_PATH, daily, ["date"])
@@ -2151,6 +2183,7 @@ def stale_data_status(now: datetime | None = None) -> dict[str, Any]:
2151
  latest_daily = latest_parquet_date(NIFTY_1D_PATH)
2152
  latest_minutes = latest_parquet_date(NIFTY_1M_PATH)
2153
  latest_t5 = latest_prediction_input_date(LATEST_PATH)
 
2154
  latest_tomorrow = latest_tomorrow_input_date()
2155
  latest_tplus1 = latest_prediction_input_date(TPLUS1_LATEST_PATH)
2156
  return {
@@ -2161,11 +2194,13 @@ def stale_data_status(now: datetime | None = None) -> dict[str, Any]:
2161
  "latest_daily_date": latest_daily.isoformat() if latest_daily else None,
2162
  "latest_minute_date": latest_minutes.isoformat() if latest_minutes else None,
2163
  "latest_t5_date": latest_t5.isoformat() if latest_t5 else None,
 
2164
  "latest_tomorrow_date": latest_tomorrow.isoformat() if latest_tomorrow else None,
2165
  "latest_tplus1_date": latest_tplus1.isoformat() if latest_tplus1 else None,
2166
  "daily_stale": is_stale(latest_daily, expected_daily),
2167
  "minutes_stale": is_stale(latest_minutes, expected_minutes),
2168
  "t5_stale": is_stale(latest_t5, expected_minutes),
 
2169
  "tomorrow_stale": is_stale(latest_tomorrow, expected_daily),
2170
  "tplus1_stale": is_stale(latest_tplus1, expected_tplus1),
2171
  }
@@ -2174,7 +2209,7 @@ def stale_data_status(now: datetime | None = None) -> dict[str, Any]:
2174
  def refresh_stale_data_once(now: datetime | None = None) -> dict[str, Any]:
2175
  now = now or datetime.now(IST)
2176
  status = stale_data_status(now)
2177
- if not any(status[key] for key in ("daily_stale", "minutes_stale", "t5_stale", "tomorrow_stale", "tplus1_stale")):
2178
  return {"status": "fresh", **status, "actions": []}
2179
  if not _stale_refresh_lock.acquire(blocking=False):
2180
  return {"status": "skipped", "reason": "stale refresh already running", **status, "actions": []}
@@ -2221,6 +2256,13 @@ def refresh_stale_data_once(now: datetime | None = None) -> dict[str, Any]:
2221
  prediction = refresh_first5_prediction(session_date=now.date())
2222
  actions.append({"name": "t5_prediction", "input_date": prediction.input_date})
2223
 
 
 
 
 
 
 
 
2224
  if status["tplus1_stale"] and is_trading_day(now.date()) and now.time() >= TPLUS1_READY:
2225
  prediction = refresh_tplus1_prediction(session_date=now.date())
2226
  actions.append({"name": "tplus1_prediction", "input_date": prediction.get("input_date")})
 
1244
  return df.sort_values("date").reset_index(drop=True)
1245
 
1246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1247
  def load_mfe_summary() -> dict[str, Any]:
 
1248
  if not MFE_SUMMARY_PATH.exists():
1249
  return {}
1250
  try:
 
1254
 
1255
 
1256
  def load_mfe_latest() -> dict[str, Any]:
 
1257
  summary = load_mfe_summary()
1258
  if MFE_LATEST_PATH.exists():
1259
  try:
 
1261
  up_pts = float(row.get("predicted_up_points", summary.get("latest_predicted_up_points", 0)))
1262
  down_pts = float(row.get("predicted_down_points", summary.get("latest_predicted_down_points", 0)))
1263
  return {
1264
+ "input_date": str(row.get("input_date") or row.get("date") or summary.get("latest_input_date", ""))[:10],
1265
  "first5_start": row.get("first5_start") or summary.get("latest_first5_start"),
1266
  "first5_end": row.get("first5_end") or summary.get("latest_first5_end"),
1267
  "first5_close": float(row.get("first5_close") or summary.get("latest_first5_close") or 0),
 
1287
 
1288
 
1289
  def load_mfe_backtest() -> pd.DataFrame:
 
1290
  if not MFE_TEST_PREDICTIONS_PATH.exists():
1291
  return pd.DataFrame()
1292
  frame = pd.read_csv(MFE_TEST_PREDICTIONS_PATH)
 
1677
  return prediction
1678
 
1679
 
1680
+ def refresh_mfe_prediction(session_date: date | None = None, minutes: pd.DataFrame | None = None) -> dict[str, Any]:
1681
+ if session_date is None:
1682
+ today = datetime.now(IST).date()
1683
+ if not is_trading_day(today):
1684
+ raise RuntimeError(f"{today.isoformat()} is not an NSE trading session.")
1685
+ else:
1686
+ today = session_date
1687
+
1688
+ minutes = fetch_yahoo_minutes(period="7d") if minutes is None else minutes
1689
+ first5 = first5_features_from_minutes(minutes, session_date=session_date)
1690
+ row = build_model_row(first5)
1691
+
1692
+ payload = joblib.load(MFE_OUTPUT_DIR / "nifty_opening_mfe_regressor.joblib")
1693
+ up_model = payload["up_model"]
1694
+ down_model = payload["down_model"]
1695
+ up_features = payload["up_features"]
1696
+ down_features = payload["down_features"]
1697
+
1698
+ up_pred = float(up_model.predict(row[up_features])[0])
1699
+ down_pred = float(down_model.predict(row[down_features])[0])
1700
+
1701
+ input_date_str = str(pd.to_datetime(row["date"].iloc[0]).date())
1702
+ out = {
1703
+ "input_date": input_date_str,
1704
+ "first5_start": str(pd.to_datetime(row["first5_start"].iloc[0])),
1705
+ "first5_end": str(pd.to_datetime(row["first5_end"].iloc[0])),
1706
+ "first5_close": float(row["first5_close"].iloc[0]) if "first5_close" in row.columns else float(row["close"].iloc[0]),
1707
+ "predicted_up_points": up_pred,
1708
+ "predicted_down_points": down_pred,
1709
+ }
1710
+
1711
+ pd.DataFrame([out]).to_csv(MFE_LATEST_PATH, index=False)
1712
+
1713
+ if MFE_TEST_PREDICTIONS_PATH.exists():
1714
+ history = pd.read_csv(MFE_TEST_PREDICTIONS_PATH)
1715
+ if "date" in history.columns:
1716
+ history["date_obj"] = pd.to_datetime(history["date"], errors="coerce").dt.date
1717
+ history = history[history["date_obj"] != pd.to_datetime(input_date_str).date()].copy()
1718
+ history.drop(columns=["date_obj"], inplace=True)
1719
+
1720
+ new_row = pd.DataFrame([{
1721
+ "date": input_date_str,
1722
+ "first5_close": out["first5_close"],
1723
+ "predicted_up_points": out["predicted_up_points"],
1724
+ "predicted_down_points": out["predicted_down_points"]
1725
+ }])
1726
+ history = pd.concat([history, new_row], ignore_index=True)
1727
+ history.to_csv(MFE_TEST_PREDICTIONS_PATH, index=False)
1728
+
1729
+ return out
1730
+
1731
+
1732
  def refresh_daily_data() -> dict[str, Any]:
1733
  daily = fetch_yahoo_daily(period="1mo")
1734
  combined = append_parquet_rows(NIFTY_1D_PATH, daily, ["date"])
 
2183
  latest_daily = latest_parquet_date(NIFTY_1D_PATH)
2184
  latest_minutes = latest_parquet_date(NIFTY_1M_PATH)
2185
  latest_t5 = latest_prediction_input_date(LATEST_PATH)
2186
+ latest_mfe = latest_prediction_input_date(MFE_LATEST_PATH)
2187
  latest_tomorrow = latest_tomorrow_input_date()
2188
  latest_tplus1 = latest_prediction_input_date(TPLUS1_LATEST_PATH)
2189
  return {
 
2194
  "latest_daily_date": latest_daily.isoformat() if latest_daily else None,
2195
  "latest_minute_date": latest_minutes.isoformat() if latest_minutes else None,
2196
  "latest_t5_date": latest_t5.isoformat() if latest_t5 else None,
2197
+ "latest_mfe_date": latest_mfe.isoformat() if latest_mfe else None,
2198
  "latest_tomorrow_date": latest_tomorrow.isoformat() if latest_tomorrow else None,
2199
  "latest_tplus1_date": latest_tplus1.isoformat() if latest_tplus1 else None,
2200
  "daily_stale": is_stale(latest_daily, expected_daily),
2201
  "minutes_stale": is_stale(latest_minutes, expected_minutes),
2202
  "t5_stale": is_stale(latest_t5, expected_minutes),
2203
+ "mfe_stale": is_stale(latest_mfe, expected_minutes),
2204
  "tomorrow_stale": is_stale(latest_tomorrow, expected_daily),
2205
  "tplus1_stale": is_stale(latest_tplus1, expected_tplus1),
2206
  }
 
2209
  def refresh_stale_data_once(now: datetime | None = None) -> dict[str, Any]:
2210
  now = now or datetime.now(IST)
2211
  status = stale_data_status(now)
2212
+ if not any(status[key] for key in ("daily_stale", "minutes_stale", "t5_stale", "mfe_stale", "tomorrow_stale", "tplus1_stale")):
2213
  return {"status": "fresh", **status, "actions": []}
2214
  if not _stale_refresh_lock.acquire(blocking=False):
2215
  return {"status": "skipped", "reason": "stale refresh already running", **status, "actions": []}
 
2256
  prediction = refresh_first5_prediction(session_date=now.date())
2257
  actions.append({"name": "t5_prediction", "input_date": prediction.input_date})
2258
 
2259
+ if status["mfe_stale"] and is_trading_day(now.date()) and now.time() >= FIRST5_READY:
2260
+ try:
2261
+ mfe_pred = refresh_mfe_prediction(session_date=now.date())
2262
+ actions.append({"name": "mfe_prediction", "input_date": mfe_pred["input_date"]})
2263
+ except Exception as e:
2264
+ actions.append({"name": "mfe_prediction", "error": str(e)})
2265
+
2266
  if status["tplus1_stale"] and is_trading_day(now.date()) and now.time() >= TPLUS1_READY:
2267
  prediction = refresh_tplus1_prediction(session_date=now.date())
2268
  actions.append({"name": "tplus1_prediction", "input_date": prediction.get("input_date")})