92 lines
2.5 KiB
Python
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
|