feat(data): 全量分钟健康时策略页与监控注入切读本地分时

- 策略页: healthy 时解除分时列 100 只截断并 prefer_local 读本地分区
- 监控信号注入: 股票 healthy 时直接读本地当日分区, 免每分钟 bucket
  一次的全量 API 拉取; ETF 不在服务 universe, 不健康/读失败回落原路径
- minute-refresh status 增加 healthy 读侧新鲜度字段 (前端共享判断)
- 测试: 注入本地读 3 用例 (健康读本地/不健康回落/ETF 恒走 API)
This commit is contained in:
shy3130
2026-09-01 13:03:54 +08:00
parent dab8a2c676
commit f84cb671ef
5 changed files with 108 additions and 9 deletions
+17 -4
View File
@@ -1241,11 +1241,24 @@ class QuoteService:
)
capset = getattr(self._app_state, "capabilities", None)
support = intraday_monitor_support(capset)
if not support["available"] or len(symbols) > int(support["max_symbols"]):
return self._intraday_signal_evaluator.inject(enriched, [])
minute_df = fetch_intraday_monitor_batch(sorted(symbols), capset, now=now)
# 全量分钟健康时股票读本地分区 (服务按间隔持续落盘, 与 API 同一列契约),
# 免去每分钟 bucket 一次的全量 API 拉取; ETF 不在服务 universe 内,
# 本地读空/异常回落原 API 路径 (含能力与上限检查)
minute_df = pl.DataFrame()
if asset_type == "stock":
svc = getattr(self._app_state, "minute_refresh", None) if self._app_state else None
if svc is not None and svc.is_healthy() and self._repo is not None:
try:
minute_df = self._repo.get_minute_batch(sorted(symbols), cn_today())
except Exception as e: # 本地读异常回落 API
logger.warning("分时信号本地读失败, 回退 API 路径: %s", e)
minute_df = pl.DataFrame()
if minute_df.is_empty():
support = intraday_monitor_support(capset)
if not support["available"] or len(symbols) > int(support["max_symbols"]):
return self._intraday_signal_evaluator.inject(enriched, [])
minute_df = fetch_intraday_monitor_batch(sorted(symbols), capset, now=now)
prev_close: dict[str, float] = {}
available_cols = set(enriched.columns)
for row in enriched.filter(pl.col("symbol").is_in(sorted(symbols))).iter_rows(named=True):