Count roll groups as one position slot and protect monitors during roll.
Include active roll groups in deduped position slots; normalize CTP position keys in reconcile; skip closing monitors tied to active roll groups. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -289,6 +289,15 @@ def active_position_slots_from_monitors(conn) -> set[tuple[str, str]]:
|
|||||||
sym = (r["symbol"] or "").strip()
|
sym = (r["symbol"] or "").strip()
|
||||||
if sym:
|
if sym:
|
||||||
keys.add(_position_slot_key(sym, r["direction"] or "long"))
|
keys.add(_position_slot_key(sym, r["direction"] or "long"))
|
||||||
|
for r in conn.execute(
|
||||||
|
"""SELECT m.symbol, m.direction
|
||||||
|
FROM roll_groups g
|
||||||
|
JOIN trade_order_monitors m ON m.id = g.order_monitor_id
|
||||||
|
WHERE g.status='active'"""
|
||||||
|
):
|
||||||
|
sym = (r["symbol"] or "").strip()
|
||||||
|
if sym:
|
||||||
|
keys.add(_position_slot_key(sym, r["direction"] or "long"))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
return keys
|
return keys
|
||||||
|
|||||||
@@ -647,9 +647,11 @@ def reconcile_monitors_without_position(conn, mode: str, *, grace_sec: int = 120
|
|||||||
for p in positions:
|
for p in positions:
|
||||||
if int(p.get("lots") or 0) <= 0:
|
if int(p.get("lots") or 0) <= 0:
|
||||||
continue
|
continue
|
||||||
sym = (p.get("symbol") or "").lower()
|
sym = (p.get("symbol") or "").strip()
|
||||||
direction = p.get("direction") or "long"
|
direction = p.get("direction") or "long"
|
||||||
position_keys.add((sym, direction))
|
if sym:
|
||||||
|
base = sym.lower().split(".")[0]
|
||||||
|
position_keys.add((base, (direction or "long").strip().lower()))
|
||||||
try:
|
try:
|
||||||
from modules.ctp.ctp_trading_state import trading_state
|
from modules.ctp.ctp_trading_state import trading_state
|
||||||
|
|
||||||
@@ -657,9 +659,11 @@ def reconcile_monitors_without_position(conn, mode: str, *, grace_sec: int = 120
|
|||||||
lots = int(p.get("lots") or 0)
|
lots = int(p.get("lots") or 0)
|
||||||
if lots <= 0:
|
if lots <= 0:
|
||||||
continue
|
continue
|
||||||
sym = (p.get("symbol") or "").lower()
|
sym = (p.get("symbol") or "").strip()
|
||||||
direction = p.get("direction") or "long"
|
direction = p.get("direction") or "long"
|
||||||
position_keys.add((sym, direction))
|
if sym:
|
||||||
|
base = sym.lower().split(".")[0]
|
||||||
|
position_keys.add((base, (direction or "long").strip().lower()))
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -709,6 +713,12 @@ def reconcile_monitors_without_position(conn, mode: str, *, grace_sec: int = 120
|
|||||||
break
|
break
|
||||||
if matched:
|
if matched:
|
||||||
continue
|
continue
|
||||||
|
mid = mon.get("id")
|
||||||
|
if conn.execute(
|
||||||
|
"SELECT 1 FROM roll_groups WHERE order_monitor_id=? AND status='active' LIMIT 1",
|
||||||
|
(mid,),
|
||||||
|
).fetchone():
|
||||||
|
continue
|
||||||
try:
|
try:
|
||||||
cancel_monitor_exit_orders(conn, mon, mode=mode)
|
cancel_monitor_exit_orders(conn, mon, mode=mode)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
|
|||||||
Reference in New Issue
Block a user