Files
sanguo_vnpy_v2/sanguo_trader/shadow/__main__.py
T

65 lines
1.6 KiB
Python

"""影子柜台 CLI 入口。
用法:
python -m sanguo_trader.shadow # 读 env(见 runner.py docstring)
python -m sanguo_trader.shadow --auto # 主管模式:轮询 paper 库自动拉起影子账户
"""
from __future__ import annotations
import logging
import os
import sys
from pathlib import Path
LOCK_FILE = Path(
os.environ.get("SANGUO_SHADOW_LOCK")
or Path.home() / ".sanguo_shadow_desk.lock"
)
def _acquire_lock() -> "object | None":
"""单实例锁(Windows/msvcrt 与 POSIX/fcntl 双兼容)。"""
LOCK_FILE.parent.mkdir(parents=True, exist_ok=True)
try:
import fcntl # POSIX
fh = open(LOCK_FILE, "w")
fcntl.flock(fh, fcntl.LOCK_EX | fcntl.LOCK_NB)
return fh
except ImportError:
pass
except OSError:
return None # 已有实例在跑
try:
import msvcrt # Windows
fh = open(LOCK_FILE, "w")
msvcrt.locking(fh.fileno(), msvcrt.LK_NBLCK, 1)
return fh
except (ImportError, OSError):
return None
def main() -> int:
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
if "--auto" in sys.argv:
from .supervisor import run_auto_supervisor
run_auto_supervisor()
return 0
lock = _acquire_lock()
if lock is None:
print("影子柜台已在运行(锁占用),本次启动退出。", flush=True)
return 0
from .runner import run_shadow
run_shadow()
return 0
if __name__ == "__main__":
sys.exit(main())