加一个监测脚本
This commit is contained in:
parent
375de72309
commit
d376a55fbd
|
|
@ -208,6 +208,58 @@ def outbound():
|
||||||
f"这才是「发不出去」, 看 pms-ws 日志")
|
f"这才是「发不出去」, 看 pms-ws 日志")
|
||||||
|
|
||||||
|
|
||||||
|
def crosscheck():
|
||||||
|
"""出口表与父指令必须对得上 —— 对不上是**本端记账掉了一环**, 比发不出去更隐蔽。
|
||||||
|
|
||||||
|
正常次序 (设计「先记账后动作」): executor 判 FIRE → dispatcher 落出口表 →
|
||||||
|
立刻把父指令置 DISPATCHED 并把这一笔记进 progress.children。三件事要么都成,
|
||||||
|
要么都没发生。只成了第一件的话:
|
||||||
|
|
||||||
|
* 父指令不知道自己今天已经发过 → 下一跳可能重复出手 (出口表 instruction_id
|
||||||
|
唯一索引会拦住, 于是它转而卡死: 每一跳都撞重复键, 再也发不出去)
|
||||||
|
* 当日配额 fired_today 恒为 0 → 分日节奏失效
|
||||||
|
* 页面看到的是「PROPOSED / 已成 0」, 而 QMT 那边单子挂着 —— 两边说的不是一回事
|
||||||
|
|
||||||
|
2026-08-03 实机撞到过一次, 所以做成常驻检查。
|
||||||
|
"""
|
||||||
|
from app.repo import pms_repo, qmt_repo
|
||||||
|
from app.services import param_store
|
||||||
|
if param_store.get("PMS_DISPATCH_MODE", "shadow") != "ws":
|
||||||
|
return
|
||||||
|
try:
|
||||||
|
orders = qmt_repo.list_orders(limit=200)
|
||||||
|
ins = {r["instruction_id"]: r for r in pms_repo.list_instructions(limit=200)}
|
||||||
|
except Exception:
|
||||||
|
return
|
||||||
|
bad = []
|
||||||
|
by_parent = {}
|
||||||
|
for o in orders:
|
||||||
|
by_parent.setdefault(o.get("parent_id"), []).append(o)
|
||||||
|
for pid, os_ in by_parent.items():
|
||||||
|
p = ins.get(pid)
|
||||||
|
if not p:
|
||||||
|
bad.append(f"出口表有 {len(os_)} 张 {os_[0]['ts_code']} 的委托, "
|
||||||
|
f"但本端找不到父指令 {pid}")
|
||||||
|
continue
|
||||||
|
n_child = len((p.get("progress") or {}).get("children") or [])
|
||||||
|
if p["status"] in ("PROPOSED", "RULE_PASSED"):
|
||||||
|
bad.append(f"{p['ts_code']} 出口表已有 {len(os_)} 张委托 "
|
||||||
|
f"({os_[0]['status']}), 而父指令还停在 {p['status']} —— "
|
||||||
|
f"下发成了但**本端没记上**")
|
||||||
|
if n_child != len(os_):
|
||||||
|
bad.append(f"{p['ts_code']} 父指令记着 {n_child} 笔子单, "
|
||||||
|
f"出口表实际有 {len(os_)} 张 —— 分日配额会算错")
|
||||||
|
if not p.get("dispatch_ref"):
|
||||||
|
bad.append(f"{p['ts_code']} 出口表有委托但父指令 dispatch_ref 是空的")
|
||||||
|
if not bad:
|
||||||
|
return
|
||||||
|
_sec("⚠ 出口表与本端指令对不上")
|
||||||
|
for b in dict.fromkeys(bad):
|
||||||
|
print(f" ✗ {b}")
|
||||||
|
print(" 这一类不是「发不出去」, 是**发出去了但账没记全**。查 executor.run_tick 里")
|
||||||
|
print(" dispatcher.dispatch 之后那几行 (update_instruction / insert_ledger) 报了什么。")
|
||||||
|
|
||||||
|
|
||||||
def positions():
|
def positions():
|
||||||
from app.services import portfolio
|
from app.services import portfolio
|
||||||
try:
|
try:
|
||||||
|
|
@ -278,6 +330,7 @@ def render(wide, clear=False):
|
||||||
account()
|
account()
|
||||||
instructions()
|
instructions()
|
||||||
outbound()
|
outbound()
|
||||||
|
crosscheck()
|
||||||
positions()
|
positions()
|
||||||
if wide:
|
if wide:
|
||||||
plans()
|
plans()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue