fix: 开仓时间读CTP OpenDate,止盈止损持久化且重启不丢失
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user