手动刷新与自动补跑共用可用数据判定:日线推算或上一交易日快照记为部分/准备中成功,避免前端误报刷新失败。HTTP JSON 解析错误不再把请求正文写入日志。 Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: multica-agent <github@multica.ai>
47 lines
1.7 KiB
Python
47 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, time as dt_time
|
|
|
|
|
|
def dashboard_has_usable_data(dashboard: dict[str, object]) -> bool:
|
|
if not isinstance(dashboard, dict) or dashboard.get("status") == "failed":
|
|
return False
|
|
meta = dashboard.get("meta") or {}
|
|
overview = dashboard.get("overview") or {}
|
|
if isinstance(meta, dict) and (meta.get("trade_date") or meta.get("carried_forward")):
|
|
return True
|
|
return bool(isinstance(overview, dict) and overview)
|
|
|
|
|
|
def verified_dashboard_result(dashboard: dict[str, object]) -> dict[str, object]:
|
|
"""Manual refresh and automatic catch-up share this rule.
|
|
|
|
Derived limit lists or a previous usable snapshot are not whole-job failures.
|
|
Only a payload with no displayable market data is recorded as failed.
|
|
"""
|
|
if dashboard_has_usable_data(dashboard):
|
|
return dashboard
|
|
meta = dashboard.get("meta") if isinstance(dashboard, dict) else None
|
|
notice = ""
|
|
if isinstance(meta, dict):
|
|
notice = str(meta.get("notice") or meta.get("display_notice") or "")
|
|
return {
|
|
"status": "failed",
|
|
"error": notice or "未获取到可用行情",
|
|
}
|
|
|
|
|
|
def official_catchup_due(today: str, snapshot: dict[str, object]) -> bool:
|
|
now = datetime.now().astimezone().time().replace(tzinfo=None)
|
|
if not (dt_time(15, 5) <= now < dt_time(22, 0)):
|
|
return False
|
|
meta = snapshot.get("meta") if isinstance(snapshot.get("meta"), dict) else {}
|
|
actual = str(meta.get("trade_date") or "").replace("-", "")
|
|
if (
|
|
actual == today
|
|
and meta.get("limit_data_source") != "derived"
|
|
and not meta.get("carried_forward")
|
|
):
|
|
return False
|
|
return True
|