feat: 添加 Redis 消息展示功能到监控面板

- 新增 /api/messages API 接口,支持从 Redis Stream 读取消息
- 支持按策略筛选消息和分页展示
- 前端新增消息列表卡片,展示时间、策略、股票代码、动作、价格和状态
- 自动判断消息处理状态(已处理/待处理)
- 消息列表每30秒自动刷新,支持手动刷新
This commit is contained in:
2026-03-01 22:06:42 +08:00
parent e88ba5bcf9
commit 7bb0a0537b
14 changed files with 1814 additions and 806 deletions

View File

@@ -725,11 +725,15 @@ class MultiEngineManager:
)
if is_trading:
for s_name in self.config.strategies.keys():
self.process_route(s_name)
self.process_route(s_name)
self.process_route(s_name, is_trading_hours=True)
self.process_route(s_name, is_trading_hours=True)
else:
# 休盘后:消费消息但不下单
for s_name in self.config.strategies.keys():
self.process_route(s_name, is_trading_hours=False)
# --- 收盘结算与标志位重置 ---
elif "150500" <= curr_hms <= "151500":
if "150500" <= curr_hms <= "151500":
for unit in self.units.values():
if unit.settler and not unit.settler.has_settled:
unit.settler.run_settlement()
@@ -744,19 +748,20 @@ class MultiEngineManager:
self.logger.error(traceback.format_exc())
time.sleep(10)
def process_route(self, strategy_name):
def process_route(self, strategy_name, is_trading_hours=True):
"""处理策略消息路由 - 使用 Redis Stream
从 Redis Stream 消费消息,处理成功后 ACK失败则进入失败队列。
Args:
strategy_name: 策略名称
is_trading_hours: 是否在交易时间内False 表示休盘后只消费消息不下单
"""
strat_cfg = self.config.get_strategy(strategy_name)
if not strat_cfg:
self.logger.warning(f"[{strategy_name}] 策略配置不存在")
return
unit = self.units.get(strat_cfg.qmt_id)
if not unit or not unit.callback or not unit.callback.is_connected:
return
unit = self.units.get(strat_cfg.get("qmt_id"))
if not unit or not unit.callback or not unit.callback.is_connected:
return
@@ -808,19 +813,37 @@ class MultiEngineManager:
result=True,
)
# 3. 执行交易动作
# 3. 执行交易动作(仅在交易时间内执行实际下单)
action = data.get("action")
# 获取策略配置,确定下单模式
# 获取策略配置,确定下单模式
strat_cfg = self.config.get_strategy(strategy_name)
if not strat_cfg:
self.logger.warning(f"[{strategy_name}] 策略配置不存在")
continue
order_mode = strat_cfg.order_mode
order_mode = strat_cfg.order_mode
order_mode = strat_cfg.get("order_mode", "slots")
if action == "BUY":
if not is_trading_hours:
# 休盘后:只记录日志,不下单
self.logger.info(
f"[{strategy_name}] [休盘后消息处理] "
f"action={action}, code={data.get('stock_code')}, "
f"order_mode={order_mode}, msg_time={data.get('timestamp')} - "
f"仅消费消息,跳过实际下单"
)
self.qmt_logger.log_validation(
validation_type="market_hours_check",
strategy_name=strategy_name,
details={
"action": action,
"code": data.get("stock_code"),
"order_mode": order_mode,
"msg_time": data.get("timestamp"),
"skip_reason": "休盘后只消费消息不下单"
},
result=True,
)
elif action == "BUY":
self.qmt_logger.log_validation(
validation_type="action_check",
strategy_name=strategy_name,