@@ -222,68 +222,54 @@ def _score(value: float, low: float, high: float) -> int:
|
||||
return max(0, min(100, round((value - low) / (high - low) * 100)))
|
||||
|
||||
|
||||
def _quote_status(request: Request) -> dict:
|
||||
qs = getattr(request.app.state, "quote_service", None)
|
||||
if not qs:
|
||||
return {"enabled": False, "running": False, "quote_age_ms": None, "is_trading_hours": False}
|
||||
return qs.status()
|
||||
|
||||
|
||||
def _index_quotes(request: Request, as_of: date | None = None) -> list[dict]:
|
||||
qs = getattr(request.app.state, "quote_service", None)
|
||||
rows: list[dict] = []
|
||||
if qs and as_of is None:
|
||||
df = qs.get_index_quotes(list(CORE_INDEX_SYMBOLS))
|
||||
if not df.is_empty():
|
||||
rows = df.to_dicts()
|
||||
|
||||
if not rows:
|
||||
repo = getattr(request.app.state, "repo", None)
|
||||
if repo:
|
||||
placeholders = ", ".join("?" for _ in CORE_INDEX_SYMBOLS)
|
||||
try:
|
||||
db_rows = repo.execute_all(
|
||||
f"""
|
||||
WITH ranked AS (
|
||||
SELECT symbol, date, close,
|
||||
row_number() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
|
||||
FROM kline_index_daily
|
||||
WHERE symbol IN ({placeholders})
|
||||
AND (? IS NULL OR date <= ?)
|
||||
), latest AS (
|
||||
SELECT symbol,
|
||||
max(CASE WHEN rn = 1 THEN date END) AS date,
|
||||
max(CASE WHEN rn = 1 THEN close END) AS last_price,
|
||||
max(CASE WHEN rn = 2 THEN close END) AS prev_close
|
||||
FROM ranked
|
||||
WHERE rn <= 2
|
||||
GROUP BY symbol
|
||||
)
|
||||
SELECT symbol, date, last_price, prev_close
|
||||
FROM latest
|
||||
""",
|
||||
[*CORE_INDEX_SYMBOLS, as_of, as_of],
|
||||
repo = getattr(request.app.state, "repo", None)
|
||||
if repo:
|
||||
placeholders = ", ".join("?" for _ in CORE_INDEX_SYMBOLS)
|
||||
try:
|
||||
db_rows = repo.execute_all(
|
||||
f"""
|
||||
WITH ranked AS (
|
||||
SELECT symbol, date, close,
|
||||
row_number() OVER (PARTITION BY symbol ORDER BY date DESC) AS rn
|
||||
FROM kline_index_daily
|
||||
WHERE symbol IN ({placeholders})
|
||||
AND (? IS NULL OR date <= ?)
|
||||
), latest AS (
|
||||
SELECT symbol,
|
||||
max(CASE WHEN rn = 1 THEN date END) AS date,
|
||||
max(CASE WHEN rn = 1 THEN close END) AS last_price,
|
||||
max(CASE WHEN rn = 2 THEN close END) AS prev_close
|
||||
FROM ranked
|
||||
WHERE rn <= 2
|
||||
GROUP BY symbol
|
||||
)
|
||||
except Exception: # noqa: BLE001
|
||||
db_rows = []
|
||||
for symbol, dt, last_price, prev_close in db_rows:
|
||||
change_amount = None
|
||||
change_pct = None
|
||||
lp = _finite(last_price)
|
||||
pc = _finite(prev_close)
|
||||
if lp is not None and pc not in (None, 0):
|
||||
change_amount = lp - pc
|
||||
change_pct = change_amount / pc * 100
|
||||
rows.append({
|
||||
"symbol": symbol,
|
||||
"name": CORE_INDEX_NAMES.get(symbol),
|
||||
"date": str(dt) if dt else None,
|
||||
"last_price": lp,
|
||||
"close": lp,
|
||||
"prev_close": pc,
|
||||
"change_amount": change_amount,
|
||||
"change_pct": change_pct,
|
||||
})
|
||||
SELECT symbol, date, last_price, prev_close
|
||||
FROM latest
|
||||
""",
|
||||
[*CORE_INDEX_SYMBOLS, as_of, as_of],
|
||||
)
|
||||
except Exception: # noqa: BLE001
|
||||
db_rows = []
|
||||
for symbol, dt, last_price, prev_close in db_rows:
|
||||
change_amount = None
|
||||
change_pct = None
|
||||
lp = _finite(last_price)
|
||||
pc = _finite(prev_close)
|
||||
if lp is not None and pc not in (None, 0):
|
||||
change_amount = lp - pc
|
||||
change_pct = change_amount / pc * 100
|
||||
rows.append({
|
||||
"symbol": symbol,
|
||||
"name": CORE_INDEX_NAMES.get(symbol),
|
||||
"date": str(dt) if dt else None,
|
||||
"last_price": lp,
|
||||
"close": lp,
|
||||
"prev_close": pc,
|
||||
"change_amount": change_amount,
|
||||
"change_pct": change_pct,
|
||||
})
|
||||
|
||||
by_symbol = {r.get("symbol"): r for r in rows}
|
||||
out = []
|
||||
@@ -351,8 +337,6 @@ def _build_overview(request: Request, as_of: date | None = None) -> dict:
|
||||
from app.services.market_overview_builder import build_market_overview
|
||||
return build_market_overview(
|
||||
repo=request.app.state.repo,
|
||||
quote_service=getattr(request.app.state, "quote_service", None),
|
||||
depth_service=getattr(request.app.state, "depth_service", None),
|
||||
as_of=as_of,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user