Fix roll first-lots display and make market add use pending orders.

Store initial_lots on roll groups, submit market roll as CTP pending legs with cancel closing empty groups, and backfill first-lots for existing active groups.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-02 22:12:04 +08:00
parent 3c53b2063f
commit 530738ae93
5 changed files with 392 additions and 105 deletions
@@ -50,6 +50,25 @@ def roll_sync_after_external_close(conn, *, monitor_id: int) -> None:
)
def close_roll_group_if_idle(conn, gid: int) -> None:
"""无已成交腿且无 pending 腿时关闭滚仓组(如市价挂单撤单后)。"""
gid = int(gid)
filled = int(conn.execute(
"SELECT COUNT(*) AS n FROM roll_legs WHERE roll_group_id=? AND status=?",
(gid, LEG_STATUS_FILLED),
).fetchone()["n"] or 0)
pending = int(conn.execute(
"SELECT COUNT(*) AS n FROM roll_legs WHERE roll_group_id=? AND status=?",
(gid, LEG_STATUS_PENDING),
).fetchone()["n"] or 0)
if filled > 0 or pending > 0:
return
conn.execute(
"UPDATE roll_groups SET status='closed', updated_at=? WHERE id=? AND status='active'",
(_now(), gid),
)
def cancel_roll_leg(conn, leg_id: int) -> tuple[bool, str]:
row = conn.execute(
"SELECT * FROM roll_legs WHERE id=? AND status=?",
@@ -57,10 +76,12 @@ def cancel_roll_leg(conn, leg_id: int) -> tuple[bool, str]:
).fetchone()
if not row:
return False, "仅可删除监控中的腿"
leg = dict(row)
conn.execute(
"UPDATE roll_legs SET status=? WHERE id=?",
(LEG_STATUS_CANCELLED, int(leg_id)),
)
close_roll_group_if_idle(conn, int(leg["roll_group_id"]))
return True, "已删除"
@@ -89,6 +110,9 @@ def check_roll_monitors(
).fetchall()
for raw in rows:
leg = dict(raw)
mode = (leg.get("add_mode") or "").strip().lower()
if mode == ADD_MODE_MARKET:
continue
if (leg.get("mon_status") or "").strip().lower() != "active":
_invalidate_leg(conn, leg, "监控已结束")
continue