feat(risk): show live countdown on freeze status badges
Expose freeze_until_ms from risk API and tick hub/instance badges with remaining 1h/4h/daily time. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -405,6 +405,44 @@ def apply_manual_close_journal_cooloff(
|
||||
)
|
||||
|
||||
|
||||
def _next_trading_day_reset_ms(now: datetime, reset_hour: int) -> int:
|
||||
from datetime import timedelta
|
||||
|
||||
h = max(0, min(23, int(reset_hour)))
|
||||
candidate = now.replace(hour=h, minute=0, second=0, microsecond=0)
|
||||
if now >= candidate:
|
||||
candidate = candidate + timedelta(days=1)
|
||||
return _now_ms(candidate)
|
||||
|
||||
|
||||
def enrich_risk_status_countdown(
|
||||
st: dict[str, Any],
|
||||
*,
|
||||
now: Optional[datetime] = None,
|
||||
daily_reset_hour: int = 8,
|
||||
) -> dict[str, Any]:
|
||||
"""补充 freeze_until_ms / freeze_remaining_sec,供前端倒计时展示。"""
|
||||
if not st.get("enabled", True):
|
||||
return st
|
||||
dt = now or datetime.now()
|
||||
now_ms = _now_ms(dt)
|
||||
until_ms: Optional[int] = None
|
||||
if st.get("daily_frozen"):
|
||||
until_ms = _next_trading_day_reset_ms(dt, daily_reset_hour)
|
||||
elif st.get("cooloff_until_ms"):
|
||||
try:
|
||||
until_ms = int(st["cooloff_until_ms"])
|
||||
except (TypeError, ValueError):
|
||||
until_ms = None
|
||||
if until_ms is not None and until_ms > now_ms:
|
||||
st["freeze_until_ms"] = until_ms
|
||||
st["freeze_remaining_sec"] = max(0, (until_ms - now_ms) // 1000)
|
||||
else:
|
||||
st["freeze_until_ms"] = None
|
||||
st["freeze_remaining_sec"] = 0
|
||||
return st
|
||||
|
||||
|
||||
def compute_account_risk_status(
|
||||
conn,
|
||||
*,
|
||||
|
||||
Reference in New Issue
Block a user