feat: 添加 Redis 消息展示功能到监控面板
- 新增 /api/messages API 接口,支持从 Redis Stream 读取消息 - 支持按策略筛选消息和分页展示 - 前端新增消息列表卡片,展示时间、策略、股票代码、动作、价格和状态 - 自动判断消息处理状态(已处理/待处理) - 消息列表每30秒自动刷新,支持手动刷新
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user