Files
sanguo_vnpy_v2/scripts/reanchor_value.py
T

84 lines
2.8 KiB
Python

# -*- coding: utf-8 -*-
"""value 双轨重锚工序(2026-09-11 夜,用户拍板A)。
stop(live_21+shadow_62) -> 等停死 -> 备份+删 live_state.json 的 strategy_start_date -> start。
安全闸: 引擎未停死拒绝改档。用法: python -X utf8 C:\\sanguo_bigqmt\\reanchor_value.py [edit-only]
"""
from __future__ import annotations
import datetime
import json
import shutil
import sqlite3
import sys
import time
DB = r"C:\sanguo_vnpy_v2\data\backtest_results.db"
RUNTIMES = [r"C:\sanguo_vnpy_v2\runtime\live_21\live_state.json",
r"C:\sanguo_vnpy_v2\runtime\shadow_62\live_state.json"]
def _children_alive():
"""返回 (live_21存活, shadow_62存活)。"""
import psutil
live21 = shadow62 = False
for p in psutil.process_iter(["pid", "name", "cmdline"]):
if "python" not in (p.info["name"] or "").lower():
continue
cmd = p.info["cmdline"] or []
joined = " ".join(cmd)
if "runner_live" in joined and "21" in cmd:
live21 = True
if "sanguo_trader.shadow" in joined and "62" in cmd and "--auto" not in joined:
shadow62 = True
return live21, shadow62
def _set_status(value):
with sqlite3.connect(DB, timeout=15) as c:
c.execute("UPDATE live_accounts SET status=? WHERE id=21", (value,))
c.execute("UPDATE paper_accounts SET status=? WHERE id=62 "
"AND mode='shadow' AND strategy_type='portfolio'", (value,))
c.commit()
print("STATUS ->", value)
def main():
edit_only = len(sys.argv) > 1 and sys.argv[1] == "edit-only"
if not edit_only:
# 1. stop
_set_status("stopped")
t0 = time.time()
while time.time() - t0 < 150:
l, s = _children_alive()
if not l and not s:
print("HARVEST_DONE %.0fs" % (time.time() - t0))
break
time.sleep(10)
else:
print("HARVEST_TIMEOUT live21=%s shadow62=%s" % _children_alive())
raise SystemExit(1)
# 2. 安全闸 + 备份 + 删字段
l, s = _children_alive()
if l or s:
print("SAFETY_ABORT engines still alive", l, s)
raise SystemExit(1)
stamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
for path in RUNTIMES:
bak = path + ".bak_reanchor_" + stamp
shutil.copy2(path, bak)
st = json.load(open(path, encoding="utf-8"))
strat = st.get("strategy") or {}
old = strat.pop("strategy_start_date", None)
st["strategy"] = strat
json.dump(st, open(path, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
print("EDIT", path, "old_start=", old, "bak=", bak.split("\\")[-1])
if edit_only:
return
# 3. start
_set_status("running")
print("STARTED — 等 boot 后读新锚(post 锚=首个交易日事件日)")
if __name__ == "__main__":
main()