2026-02-01 13:57:30 +00:00

92 lines
2.5 KiB
Python

from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Dict
import sys
import time
from fastapi import APIRouter
PROJECT_ROOT = Path(__file__).resolve().parents[1]
if str(PROJECT_ROOT) not in sys.path:
sys.path.append(str(PROJECT_ROOT))
from indian_paper_trading_strategy.engine.data import fetch_live_price, get_price_snapshot
NIFTY = "NIFTYBEES.NS"
GOLD = "GOLDBEES.NS"
router = APIRouter(prefix="/api/market", tags=["market"])
_LTP_CACHE: Dict[str, Any] = {
"ts_epoch": 0.0,
"data": None,
}
CACHE_TTL_SECONDS = 5
STALE_SECONDS = 60
@router.get("/ltp")
def get_ltp(allow_cache: bool = False):
now_epoch = time.time()
cached = _LTP_CACHE["data"]
if cached is not None and (now_epoch - _LTP_CACHE["ts_epoch"]) < CACHE_TTL_SECONDS:
return cached
nifty_ltp = None
gold_ltp = None
try:
nifty_ltp = fetch_live_price(NIFTY)
except Exception:
nifty_ltp = None
try:
gold_ltp = fetch_live_price(GOLD)
except Exception:
gold_ltp = None
nifty_meta = get_price_snapshot(NIFTY) or {}
gold_meta = get_price_snapshot(GOLD) or {}
now = datetime.now(timezone.utc)
def _is_stale(meta: Dict[str, Any], ltp: float | None) -> bool:
if ltp is None:
return True
source = meta.get("source")
ts = meta.get("ts")
if source != "live":
return True
if isinstance(ts, datetime):
return (now - ts).total_seconds() > STALE_SECONDS
return False
nifty_source = str(nifty_meta.get("source") or "").lower()
gold_source = str(gold_meta.get("source") or "").lower()
stale_map = {
NIFTY: _is_stale(nifty_meta, nifty_ltp),
GOLD: _is_stale(gold_meta, gold_ltp),
}
stale_any = stale_map[NIFTY] or stale_map[GOLD]
if allow_cache and stale_any:
cache_sources = {"cache", "cached", "history"}
if nifty_source in cache_sources and gold_source in cache_sources:
stale_map = {NIFTY: False, GOLD: False}
stale_any = False
payload = {
"ts": now.isoformat(),
"ltp": {
NIFTY: float(nifty_ltp) if nifty_ltp is not None else None,
GOLD: float(gold_ltp) if gold_ltp is not None else None,
},
"source": {
NIFTY: nifty_meta.get("source"),
GOLD: gold_meta.get("source"),
},
"stale": stale_map,
"stale_any": stale_any,
}
_LTP_CACHE["ts_epoch"] = now_epoch
_LTP_CACHE["data"] = payload
return payload