Upload 2 files
Browse files- runtime.py +95 -0
- test.py +12 -0
runtime.py
CHANGED
|
@@ -1410,6 +1410,91 @@ def save_live_accuracy(data: dict[str, Any]) -> None:
|
|
| 1410 |
LIVE_ACCURACY_PATH.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
| 1411 |
|
| 1412 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1413 |
def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
| 1414 |
"""Score today's predictions against actual outcomes and update the ledger.
|
| 1415 |
|
|
@@ -1419,6 +1504,11 @@ def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
|
| 1419 |
we want to score).
|
| 1420 |
"""
|
| 1421 |
ledger = load_live_accuracy()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1422 |
daily = pd.read_parquet(NIFTY_1D_PATH)
|
| 1423 |
daily["_date"] = pd.to_datetime(daily["date"], errors="coerce").dt.normalize()
|
| 1424 |
today_rows = daily[daily["_date"].dt.date == session_date]
|
|
@@ -1445,6 +1535,7 @@ def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
|
| 1445 |
"prediction": pred,
|
| 1446 |
"actual": actual_close_gt_open,
|
| 1447 |
"correct": pred == actual_close_gt_open,
|
|
|
|
| 1448 |
})
|
| 1449 |
except Exception:
|
| 1450 |
pass
|
|
@@ -1462,6 +1553,7 @@ def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
|
| 1462 |
"prediction": pred,
|
| 1463 |
"actual": actual_close_gt_open,
|
| 1464 |
"correct": pred == actual_close_gt_open,
|
|
|
|
| 1465 |
})
|
| 1466 |
except Exception:
|
| 1467 |
pass
|
|
@@ -1495,6 +1587,7 @@ def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
|
| 1495 |
"prediction": pred,
|
| 1496 |
"actual": t1_actual,
|
| 1497 |
"correct": pred == t1_actual,
|
|
|
|
| 1498 |
})
|
| 1499 |
except Exception:
|
| 1500 |
pass
|
|
@@ -1503,8 +1596,10 @@ def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
|
| 1503 |
for model_id in ("t5", "tomorrow", "tplus1"):
|
| 1504 |
entries = ledger[model_id]["entries"]
|
| 1505 |
total = len(entries)
|
|
|
|
| 1506 |
correct = sum(1 for e in entries if e.get("correct"))
|
| 1507 |
ledger[model_id]["total"] = total
|
|
|
|
| 1508 |
ledger[model_id]["correct_count"] = correct
|
| 1509 |
ledger[model_id]["accuracy"] = correct / total if total > 0 else None
|
| 1510 |
|
|
|
|
| 1410 |
LIVE_ACCURACY_PATH.write_text(json.dumps(data, indent=2), encoding="utf-8")
|
| 1411 |
|
| 1412 |
|
| 1413 |
+
def seed_live_accuracy_from_backtest() -> dict[str, Any]:
|
| 1414 |
+
"""Seed the live accuracy ledger from backtest test predictions.
|
| 1415 |
+
|
| 1416 |
+
This creates the baseline entries from the test set so that
|
| 1417 |
+
accuracy starts at the backtest level and moves smoothly.
|
| 1418 |
+
"""
|
| 1419 |
+
ledger = {
|
| 1420 |
+
"tomorrow": {"entries": [], "accuracy": None, "total": 0, "correct_count": 0, "live_count": 0},
|
| 1421 |
+
"t5": {"entries": [], "accuracy": None, "total": 0, "correct_count": 0, "live_count": 0},
|
| 1422 |
+
"tplus1": {"entries": [], "accuracy": None, "total": 0, "correct_count": 0, "live_count": 0},
|
| 1423 |
+
}
|
| 1424 |
+
|
| 1425 |
+
# Seed T+5
|
| 1426 |
+
t5_test = load_test_predictions()
|
| 1427 |
+
if not t5_test.empty and "correct" in t5_test.columns:
|
| 1428 |
+
for _, row in t5_test.iterrows():
|
| 1429 |
+
day = pd.to_datetime(row.get("date")).date().isoformat()
|
| 1430 |
+
pred = str(row.get("prediction", "")).upper()
|
| 1431 |
+
correct = bool(row.get("correct"))
|
| 1432 |
+
actual = pred if correct else ("DOWN" if pred == "UP" else "UP")
|
| 1433 |
+
ledger["t5"]["entries"].append({
|
| 1434 |
+
"date": day, "prediction": pred,
|
| 1435 |
+
"actual": actual, "correct": correct,
|
| 1436 |
+
"source": "backtest",
|
| 1437 |
+
})
|
| 1438 |
+
|
| 1439 |
+
# Seed Tomorrow
|
| 1440 |
+
tom_test = load_tomorrow_test_predictions()
|
| 1441 |
+
if not tom_test.empty:
|
| 1442 |
+
if "pred" in tom_test.columns and "prediction" not in tom_test.columns:
|
| 1443 |
+
tom_test["prediction"] = np.where(pd.to_numeric(tom_test["pred"], errors="coerce") == 1, "UP", "DOWN")
|
| 1444 |
+
if "correct" not in tom_test.columns and {"target", "pred"}.issubset(tom_test.columns):
|
| 1445 |
+
tom_test["correct"] = pd.to_numeric(tom_test["target"], errors="coerce") == pd.to_numeric(tom_test["pred"], errors="coerce")
|
| 1446 |
+
if "correct" in tom_test.columns:
|
| 1447 |
+
for _, row in tom_test.iterrows():
|
| 1448 |
+
target_date = row.get("target_date")
|
| 1449 |
+
if pd.isna(target_date):
|
| 1450 |
+
continue
|
| 1451 |
+
day = pd.to_datetime(target_date).date().isoformat()
|
| 1452 |
+
pred = str(row.get("prediction", "")).upper()
|
| 1453 |
+
correct = bool(row.get("correct"))
|
| 1454 |
+
actual = pred if correct else ("DOWN" if pred == "UP" else "UP")
|
| 1455 |
+
ledger["tomorrow"]["entries"].append({
|
| 1456 |
+
"date": day, "prediction": pred,
|
| 1457 |
+
"actual": actual, "correct": correct,
|
| 1458 |
+
"source": "backtest",
|
| 1459 |
+
})
|
| 1460 |
+
|
| 1461 |
+
# Seed T+1
|
| 1462 |
+
t1_test = load_tplus1_test_predictions()
|
| 1463 |
+
if not t1_test.empty:
|
| 1464 |
+
for _, row in t1_test.iterrows():
|
| 1465 |
+
target_date = row.get("target_date")
|
| 1466 |
+
if pd.isna(target_date):
|
| 1467 |
+
continue
|
| 1468 |
+
day = pd.to_datetime(target_date).date().isoformat()
|
| 1469 |
+
pred = str(row.get("prediction", "")).upper()
|
| 1470 |
+
if "correct" in t1_test.columns:
|
| 1471 |
+
correct = bool(row.get("correct"))
|
| 1472 |
+
actual = pred if correct else ("DOWN" if pred == "UP" else "UP")
|
| 1473 |
+
elif {"target", "prediction"}.issubset(t1_test.columns):
|
| 1474 |
+
target_val = pd.to_numeric(row.get("target"), errors="coerce")
|
| 1475 |
+
actual = "UP" if target_val == 1 else "DOWN"
|
| 1476 |
+
correct = pred == actual
|
| 1477 |
+
else:
|
| 1478 |
+
continue
|
| 1479 |
+
ledger["tplus1"]["entries"].append({
|
| 1480 |
+
"date": day, "prediction": pred,
|
| 1481 |
+
"actual": actual, "correct": correct,
|
| 1482 |
+
"source": "backtest",
|
| 1483 |
+
})
|
| 1484 |
+
|
| 1485 |
+
for model_id in ("t5", "tomorrow", "tplus1"):
|
| 1486 |
+
entries = ledger[model_id]["entries"]
|
| 1487 |
+
total = len(entries)
|
| 1488 |
+
correct = sum(1 for e in entries if e.get("correct"))
|
| 1489 |
+
ledger[model_id]["total"] = total
|
| 1490 |
+
ledger[model_id]["correct_count"] = correct
|
| 1491 |
+
ledger[model_id]["accuracy"] = correct / total if total > 0 else None
|
| 1492 |
+
ledger[model_id]["live_count"] = 0
|
| 1493 |
+
|
| 1494 |
+
save_live_accuracy(ledger)
|
| 1495 |
+
return ledger
|
| 1496 |
+
|
| 1497 |
+
|
| 1498 |
def update_live_accuracy(session_date: date) -> dict[str, Any]:
|
| 1499 |
"""Score today's predictions against actual outcomes and update the ledger.
|
| 1500 |
|
|
|
|
| 1504 |
we want to score).
|
| 1505 |
"""
|
| 1506 |
ledger = load_live_accuracy()
|
| 1507 |
+
|
| 1508 |
+
# If ledger is empty/unseeded, seed from backtest first
|
| 1509 |
+
if not any(ledger[m].get("entries") for m in ("t5", "tomorrow", "tplus1")):
|
| 1510 |
+
ledger = seed_live_accuracy_from_backtest()
|
| 1511 |
+
|
| 1512 |
daily = pd.read_parquet(NIFTY_1D_PATH)
|
| 1513 |
daily["_date"] = pd.to_datetime(daily["date"], errors="coerce").dt.normalize()
|
| 1514 |
today_rows = daily[daily["_date"].dt.date == session_date]
|
|
|
|
| 1535 |
"prediction": pred,
|
| 1536 |
"actual": actual_close_gt_open,
|
| 1537 |
"correct": pred == actual_close_gt_open,
|
| 1538 |
+
"source": "live",
|
| 1539 |
})
|
| 1540 |
except Exception:
|
| 1541 |
pass
|
|
|
|
| 1553 |
"prediction": pred,
|
| 1554 |
"actual": actual_close_gt_open,
|
| 1555 |
"correct": pred == actual_close_gt_open,
|
| 1556 |
+
"source": "live",
|
| 1557 |
})
|
| 1558 |
except Exception:
|
| 1559 |
pass
|
|
|
|
| 1587 |
"prediction": pred,
|
| 1588 |
"actual": t1_actual,
|
| 1589 |
"correct": pred == t1_actual,
|
| 1590 |
+
"source": "live",
|
| 1591 |
})
|
| 1592 |
except Exception:
|
| 1593 |
pass
|
|
|
|
| 1596 |
for model_id in ("t5", "tomorrow", "tplus1"):
|
| 1597 |
entries = ledger[model_id]["entries"]
|
| 1598 |
total = len(entries)
|
| 1599 |
+
live_count = sum(1 for e in entries if e.get("source") == "live")
|
| 1600 |
correct = sum(1 for e in entries if e.get("correct"))
|
| 1601 |
ledger[model_id]["total"] = total
|
| 1602 |
+
ledger[model_id]["live_count"] = live_count
|
| 1603 |
ledger[model_id]["correct_count"] = correct
|
| 1604 |
ledger[model_id]["accuracy"] = correct / total if total > 0 else None
|
| 1605 |
|
test.py
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
sys.path.append('backend')
|
| 3 |
+
from nifty_backend.runtime import update_live_accuracy, load_live_accuracy, dashboard_payload
|
| 4 |
+
from datetime import datetime
|
| 5 |
+
|
| 6 |
+
print('Seeding live accuracy...')
|
| 7 |
+
update_live_accuracy(datetime.now().date())
|
| 8 |
+
ledger = load_live_accuracy()
|
| 9 |
+
for m in ('t5', 'tomorrow', 'tplus1'):
|
| 10 |
+
print(f'{m}: total={ledger[m].get("total")}, accuracy={ledger[m].get("accuracy")}')
|
| 11 |
+
|
| 12 |
+
print('\nDone')
|