fix: 开仓时间读CTP OpenDate,止盈止损持久化且重启不丢失

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-25 15:05:58 +08:00
parent 7daed9bd3a
commit 4d60b958ce
4 changed files with 130 additions and 38 deletions
+22
View File
@@ -124,6 +124,7 @@ class CtpBridge:
self._subscribed: set[str] = set()
self._last_position_query_ts: float = 0.0
self._position_margins: dict[str, float] = {}
self._position_open_times: dict[str, str] = {}
self._margin_hooked = False
self._tick_hooked = False
self._bar_generators: dict[str, Any] = {}
@@ -727,6 +728,16 @@ class CtpBridge:
def _position_margin_key(self, sym: str, direction: str) -> str:
return f"{(sym or '').lower()}:{(direction or 'long').strip().lower()}"
def _lookup_position_open_time(self, sym: str, direction: str) -> str:
return (self._position_open_times.get(self._position_margin_key(sym, direction)) or "").strip()
@staticmethod
def _parse_ctp_open_date(raw: str) -> str:
s = (raw or "").strip()
if len(s) >= 8 and s[:8].isdigit():
return f"{s[:4]}-{s[4:6]}-{s[6:8]} 09:00:00"
return ""
def _install_position_margin_hook(self) -> None:
"""拦截 CTP 持仓回报,缓存柜台 UseMargin。"""
if self._margin_hooked or not self._engine:
@@ -758,6 +769,14 @@ class CtpBridge:
bridge._position_margins[k] = (
bridge._position_margins.get(k, 0.0) + margin
)
open_date = bridge._parse_ctp_open_date(
str(data.get("OpenDate") or data.get("open_date") or "")
)
if sym and open_date:
k = bridge._position_margin_key(sym, d)
prev = bridge._position_open_times.get(k, "")
if not prev or open_date < prev:
bridge._position_open_times[k] = open_date
except Exception as exc:
logger.debug("margin hook row: %s", exc)
return original(data, error, reqid, last)
@@ -783,6 +802,7 @@ class CtpBridge:
exchange = getattr(pos, "exchange", None)
ex_name = str(exchange.value if hasattr(exchange, "value") else exchange or "")
margin = self._lookup_position_margin(sym, d)
open_time = self._lookup_position_open_time(sym, d) or None
out.append({
"symbol": sym,
"exchange": ex_name,
@@ -792,6 +812,7 @@ class CtpBridge:
"pnl": float(getattr(pos, "pnl", 0) or 0),
"frozen": int(getattr(pos, "frozen", 0) or 0),
"margin": round(margin, 2) if margin > 0 else None,
"open_time": open_time,
})
return out
@@ -809,6 +830,7 @@ class CtpBridge:
td = getattr(gw, "td_api", None)
if td and hasattr(td, "query_position"):
self._position_margins.clear()
self._position_open_times.clear()
td.query_position()
time.sleep(0.4)
except Exception as exc: