Spaces:
Running
Running
Upload runtime.py
Browse files- runtime.py +41 -8
runtime.py
CHANGED
|
@@ -182,6 +182,31 @@ def previous_trading_day(start: date) -> date:
|
|
| 182 |
return pd.Timestamp(schedule.index[-1]).date()
|
| 183 |
|
| 184 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 185 |
class ProbabilityBlend:
|
| 186 |
def __init__(self, models: list[Any], weights: np.ndarray):
|
| 187 |
self.models = models
|
|
@@ -1296,7 +1321,6 @@ def _rolling_tomorrow_prediction(
|
|
| 1296 |
|
| 1297 |
|
| 1298 |
def build_prediction_track_record(
|
| 1299 |
-
daily: pd.DataFrame,
|
| 1300 |
sessions: int = 10,
|
| 1301 |
) -> list[dict[str, Any]]:
|
| 1302 |
"""Rolling last-N Tomorrow simulation: predict each session, score vs prior close."""
|
|
@@ -1306,14 +1330,20 @@ def build_prediction_track_record(
|
|
| 1306 |
fallback_prob = float(summary.get("latest_forecast_prob_up", 0.49900560447008563))
|
| 1307 |
forecaster_by_target = _load_forecaster_predictions_by_target()
|
| 1308 |
|
| 1309 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1310 |
daily_rows["date"] = pd.to_datetime(daily_rows["date"], errors="coerce").dt.normalize()
|
| 1311 |
daily_rows = daily_rows.dropna(subset=["date"]).sort_values("date")
|
| 1312 |
daily_rows = daily_rows[
|
| 1313 |
daily_rows["close"].map(lambda value: np.isfinite(float(value)) if pd.notna(value) else False)
|
| 1314 |
].copy()
|
| 1315 |
-
completed_day = expected_completed_daily_date()
|
| 1316 |
-
daily_rows = daily_rows[daily_rows["date"].dt.date <= completed_day]
|
| 1317 |
if daily_rows.empty:
|
| 1318 |
return []
|
| 1319 |
|
|
@@ -1323,10 +1353,13 @@ def build_prediction_track_record(
|
|
| 1323 |
if pd.notna(row["close"]) and np.isfinite(float(row["close"]))
|
| 1324 |
}
|
| 1325 |
|
|
|
|
|
|
|
| 1326 |
records: list[dict[str, Any]] = []
|
| 1327 |
-
for
|
| 1328 |
-
|
| 1329 |
-
day_close
|
|
|
|
| 1330 |
actual_move, actual_direction = _tomorrow_actual_outcome(target_day, day_close, closes_by_date)
|
| 1331 |
if actual_direction is None:
|
| 1332 |
continue
|
|
@@ -1452,7 +1485,7 @@ def _dashboard_payload_cached(key: tuple[tuple[str, int | None, int | None], ...
|
|
| 1452 |
"total_test_days": int(tomorrow_summary.get("n_test") or len(tomorrow_test) or 0),
|
| 1453 |
"models": model_metrics,
|
| 1454 |
}
|
| 1455 |
-
track_record = build_prediction_track_record(
|
| 1456 |
return {
|
| 1457 |
"latest": t5_latest,
|
| 1458 |
"tomorrow_latest": tomorrow_latest,
|
|
|
|
| 182 |
return pd.Timestamp(schedule.index[-1]).date()
|
| 183 |
|
| 184 |
|
| 185 |
+
def last_n_trading_sessions(end_day: date, count: int) -> list[date]:
|
| 186 |
+
"""Return the last ``count`` NSE sessions ending on (or before) ``end_day``."""
|
| 187 |
+
sessions: list[date] = []
|
| 188 |
+
cursor = end_day
|
| 189 |
+
guard = 0
|
| 190 |
+
while len(sessions) < count and guard < count * 12:
|
| 191 |
+
guard += 1
|
| 192 |
+
if is_trading_day(cursor):
|
| 193 |
+
sessions.append(cursor)
|
| 194 |
+
if len(sessions) >= count:
|
| 195 |
+
break
|
| 196 |
+
cursor = previous_trading_day(cursor - timedelta(days=1))
|
| 197 |
+
sessions.reverse()
|
| 198 |
+
return sessions
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def _track_record_end_session(now: datetime | None = None) -> date:
|
| 202 |
+
"""Latest session the track record should score (today after the close refresh window)."""
|
| 203 |
+
now = now or datetime.now(IST)
|
| 204 |
+
today = now.date()
|
| 205 |
+
if is_trading_day(today) and now.time() >= CLOSE_REFRESH_READY:
|
| 206 |
+
return today
|
| 207 |
+
return expected_completed_daily_date(now)
|
| 208 |
+
|
| 209 |
+
|
| 210 |
class ProbabilityBlend:
|
| 211 |
def __init__(self, models: list[Any], weights: np.ndarray):
|
| 212 |
self.models = models
|
|
|
|
| 1321 |
|
| 1322 |
|
| 1323 |
def build_prediction_track_record(
|
|
|
|
| 1324 |
sessions: int = 10,
|
| 1325 |
) -> list[dict[str, Any]]:
|
| 1326 |
"""Rolling last-N Tomorrow simulation: predict each session, score vs prior close."""
|
|
|
|
| 1330 |
fallback_prob = float(summary.get("latest_forecast_prob_up", 0.49900560447008563))
|
| 1331 |
forecaster_by_target = _load_forecaster_predictions_by_target()
|
| 1332 |
|
| 1333 |
+
end_session = _track_record_end_session()
|
| 1334 |
+
latest_daily = latest_parquet_date(NIFTY_1D_PATH)
|
| 1335 |
+
if latest_daily is None or latest_daily < end_session:
|
| 1336 |
+
try:
|
| 1337 |
+
refresh_daily_data()
|
| 1338 |
+
except Exception:
|
| 1339 |
+
pass
|
| 1340 |
+
|
| 1341 |
+
daily_rows = pd.read_parquet(NIFTY_1D_PATH)
|
| 1342 |
daily_rows["date"] = pd.to_datetime(daily_rows["date"], errors="coerce").dt.normalize()
|
| 1343 |
daily_rows = daily_rows.dropna(subset=["date"]).sort_values("date")
|
| 1344 |
daily_rows = daily_rows[
|
| 1345 |
daily_rows["close"].map(lambda value: np.isfinite(float(value)) if pd.notna(value) else False)
|
| 1346 |
].copy()
|
|
|
|
|
|
|
| 1347 |
if daily_rows.empty:
|
| 1348 |
return []
|
| 1349 |
|
|
|
|
| 1353 |
if pd.notna(row["close"]) and np.isfinite(float(row["close"]))
|
| 1354 |
}
|
| 1355 |
|
| 1356 |
+
session_dates = last_n_trading_sessions(end_session, sessions)
|
| 1357 |
+
|
| 1358 |
records: list[dict[str, Any]] = []
|
| 1359 |
+
for target_day in session_dates:
|
| 1360 |
+
day_close = closes_by_date.get(target_day)
|
| 1361 |
+
if day_close is None:
|
| 1362 |
+
continue
|
| 1363 |
actual_move, actual_direction = _tomorrow_actual_outcome(target_day, day_close, closes_by_date)
|
| 1364 |
if actual_direction is None:
|
| 1365 |
continue
|
|
|
|
| 1485 |
"total_test_days": int(tomorrow_summary.get("n_test") or len(tomorrow_test) or 0),
|
| 1486 |
"models": model_metrics,
|
| 1487 |
}
|
| 1488 |
+
track_record = build_prediction_track_record(sessions=10)
|
| 1489 |
return {
|
| 1490 |
"latest": t5_latest,
|
| 1491 |
"tomorrow_latest": tomorrow_latest,
|