Fix position flicker, drop futures cooloff, prioritize startup display.
Preserve trading state when CTP memory is empty, bootstrap equity/positions on page load, stabilize risk status from DB monitors, and remove app-layer manual close cooling periods. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+16
-45
@@ -51,17 +51,12 @@ def risk_control_enabled() -> bool:
|
||||
|
||||
|
||||
def cooling_hours_manual() -> float:
|
||||
try:
|
||||
return max(0.0, float(os.getenv("RISK_COOLING_HOURS_MANUAL", "4")))
|
||||
except (TypeError, ValueError):
|
||||
return 4.0
|
||||
"""期货版不使用应用层冷静期(交易所自有规则),恒为 0。"""
|
||||
return 0.0
|
||||
|
||||
|
||||
def cooling_hours_manual_journal() -> float:
|
||||
try:
|
||||
return max(0.0, float(os.getenv("RISK_COOLING_HOURS_MANUAL_JOURNAL", "1")))
|
||||
except (TypeError, ValueError):
|
||||
return 1.0
|
||||
return 0.0
|
||||
|
||||
|
||||
def manual_close_daily_limit() -> int:
|
||||
@@ -286,15 +281,16 @@ def on_user_initiated_close(conn, *, trading_day: str, now: Optional[datetime] =
|
||||
if count >= manual_close_daily_limit():
|
||||
conn.execute(
|
||||
"""UPDATE account_risk_state SET trading_day=?, manual_close_count=?,
|
||||
daily_frozen=1, cooloff_until_ms=NULL, last_close_at_ms=?, updated_at=? WHERE id=1""",
|
||||
daily_frozen=1, cooloff_until_ms=NULL, cooloff_hours=NULL,
|
||||
last_close_at_ms=?, updated_at=? WHERE id=1""",
|
||||
(td, count, close_ms, datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
||||
)
|
||||
return
|
||||
until = close_ms + int(cooling_hours_manual() * 3600 * 1000)
|
||||
conn.execute(
|
||||
"""UPDATE account_risk_state SET trading_day=?, manual_close_count=?,
|
||||
daily_frozen=0, cooloff_until_ms=?, cooloff_hours=?, last_close_at_ms=?, updated_at=? WHERE id=1""",
|
||||
(td, count, until, int(cooling_hours_manual()), close_ms, datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
||||
daily_frozen=0, cooloff_until_ms=NULL, cooloff_hours=NULL,
|
||||
last_close_at_ms=?, updated_at=? WHERE id=1""",
|
||||
(td, count, close_ms, datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
||||
)
|
||||
|
||||
|
||||
@@ -310,26 +306,9 @@ def on_mood_journal_freeze(conn, *, trading_day: str) -> None:
|
||||
|
||||
|
||||
def reduce_cooloff_after_journal(conn, *, trading_day: str, now: Optional[datetime] = None) -> None:
|
||||
"""复盘手动平仓说明后,4h 冷静期降为 1h。"""
|
||||
if not risk_control_enabled():
|
||||
return
|
||||
ensure_account_risk_schema(conn)
|
||||
row = conn.execute("SELECT * FROM account_risk_state WHERE id=1").fetchone()
|
||||
if int(_row_get(row, "daily_frozen") or 0):
|
||||
return
|
||||
until = _row_get(row, "cooloff_until_ms")
|
||||
if not until:
|
||||
return
|
||||
now_ms = _now_ms(now)
|
||||
if int(until) <= now_ms:
|
||||
return
|
||||
last = int(_row_get(row, "last_close_at_ms") or now_ms)
|
||||
journal_ms = int(cooling_hours_manual_journal() * 3600 * 1000)
|
||||
new_until = max(now_ms, last + journal_ms)
|
||||
conn.execute(
|
||||
"""UPDATE account_risk_state SET cooloff_until_ms=?, cooloff_hours=?, updated_at=? WHERE id=1""",
|
||||
(new_until, int(cooling_hours_manual_journal()), datetime.now().strftime("%Y-%m-%d %H:%M:%S")),
|
||||
)
|
||||
"""期货版无应用层冷静期,保留空实现兼容旧复盘钩子。"""
|
||||
del conn, trading_day, now
|
||||
return
|
||||
|
||||
|
||||
def get_risk_status(
|
||||
@@ -355,6 +334,11 @@ def get_risk_status(
|
||||
now_ms = _now_ms(now)
|
||||
daily = int(_row_get(row, "daily_frozen") or 0) == 1
|
||||
until = _row_get(row, "cooloff_until_ms")
|
||||
if until:
|
||||
conn.execute(
|
||||
"UPDATE account_risk_state SET cooloff_until_ms=NULL, cooloff_hours=NULL WHERE id=1"
|
||||
)
|
||||
conn.commit()
|
||||
active = count_active_trade_monitors(conn) if active_count is None else int(active_count)
|
||||
mx = max_active_positions()
|
||||
pos_limit = active >= mx
|
||||
@@ -387,19 +371,6 @@ def get_risk_status(
|
||||
"can_roll": False,
|
||||
"reason": "当日日冻结,禁止新开仓",
|
||||
}
|
||||
if until and int(until) > now_ms:
|
||||
rem = int((int(until) - now_ms) / 1000)
|
||||
hours = float(_row_get(row, "cooloff_hours") or cooling_hours_manual())
|
||||
st = STATUS_FREEZE_1H if hours <= cooling_hours_manual_journal() + 0.01 else STATUS_FREEZE_4H
|
||||
return {
|
||||
**base,
|
||||
"status": st,
|
||||
"status_label": STATUS_LABELS[st],
|
||||
"can_trade": False,
|
||||
"can_roll": pos_limit,
|
||||
"reason": f"冷静期中,剩余约 {rem // 3600}h {(rem % 3600) // 60}m",
|
||||
"freeze_remaining_sec": rem,
|
||||
}
|
||||
if daily_risk_limit_hit:
|
||||
return {
|
||||
**base,
|
||||
|
||||
Reference in New Issue
Block a user