Fix slow CTP position sync after restart and link positions to 15m K-line.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+36
-1
@@ -73,6 +73,8 @@ def _load_persisted_last_error() -> str:
|
||||
return (get_setting(CTP_LAST_ERROR_KEY, "") or "").strip()
|
||||
|
||||
_position_refresh_callback: Optional[Callable[[], None]] = None
|
||||
_position_refresh_debounce_lock = threading.Lock()
|
||||
_position_refresh_debounce_ts: float = 0.0
|
||||
|
||||
|
||||
def set_position_refresh_callback(fn: Optional[Callable[[], None]]) -> None:
|
||||
@@ -89,6 +91,23 @@ def _fire_position_refresh_callback() -> None:
|
||||
except Exception as exc:
|
||||
logger.debug("position refresh callback: %s", exc)
|
||||
|
||||
|
||||
def _fire_position_refresh_callback_debounced(*, min_interval: float = 0.35) -> None:
|
||||
global _position_refresh_debounce_ts
|
||||
now = time.monotonic()
|
||||
with _position_refresh_debounce_lock:
|
||||
if now - _position_refresh_debounce_ts < min_interval:
|
||||
return
|
||||
_position_refresh_debounce_ts = now
|
||||
_fire_position_refresh_callback()
|
||||
|
||||
|
||||
def _fire_position_refresh_burst() -> None:
|
||||
"""连接后持仓回报可能分批到达,分多次触发快照刷新。"""
|
||||
_fire_position_refresh_callback()
|
||||
for delay in (1.5, 4.0, 10.0, 25.0):
|
||||
threading.Timer(delay, _fire_position_refresh_callback).start()
|
||||
|
||||
_bridge: Optional["CtpBridge"] = None
|
||||
_bridge_lock = threading.Lock()
|
||||
_ctp_td_lock = threading.RLock()
|
||||
@@ -203,6 +222,7 @@ class CtpBridge:
|
||||
self._last_trade_query_ts: float = 0.0
|
||||
self._last_connect_ok_ts: float = 0.0
|
||||
self._tick_hooked = False
|
||||
self._position_hooked = False
|
||||
self._bar_generators: dict[str, Any] = {}
|
||||
self._bars_1m: dict[str, deque] = {}
|
||||
self._init_engine()
|
||||
@@ -217,11 +237,26 @@ class CtpBridge:
|
||||
self._ee = EventEngine()
|
||||
self._engine = MainEngine(self._ee)
|
||||
self._engine.add_gateway(CtpGateway)
|
||||
self._ensure_position_event_hook()
|
||||
except ImportError:
|
||||
self._last_error = "未安装 vnpy / vnpy_ctp,请 pip install vnpy vnpy_ctp"
|
||||
except Exception as exc:
|
||||
self._last_error = str(exc)
|
||||
|
||||
def _ensure_position_event_hook(self) -> None:
|
||||
if self._position_hooked or not self._ee:
|
||||
return
|
||||
try:
|
||||
from vnpy.trader.event import EVENT_POSITION
|
||||
except ImportError:
|
||||
return
|
||||
|
||||
def _on_position(_event) -> None:
|
||||
_fire_position_refresh_callback_debounced()
|
||||
|
||||
self._ee.register(EVENT_POSITION, _on_position)
|
||||
self._position_hooked = True
|
||||
|
||||
def available(self) -> bool:
|
||||
return self._engine is not None
|
||||
|
||||
@@ -414,7 +449,7 @@ class CtpBridge:
|
||||
mode, self._td_logged_in(),
|
||||
len(self._engine.get_all_accounts() or []))
|
||||
self._schedule_fee_sync(mode)
|
||||
_fire_position_refresh_callback()
|
||||
_fire_position_refresh_burst()
|
||||
return
|
||||
finally:
|
||||
self._ee.unregister(EVENT_LOG, _on_log)
|
||||
|
||||
Reference in New Issue
Block a user