fix(risk): trigger cooldown only on user-initiated closes
Remove external-close risk hooks; register user_instance, user_hub, and user_trend_stop via hub API and trend stop; update docs and tests. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1177,6 +1177,21 @@ async def _fetch_flask_json(
|
||||
return {"ok": False, "error": str(e)}
|
||||
|
||||
|
||||
async def _notify_instance_user_close(
|
||||
client: httpx.AsyncClient, ex: dict, *, count: int = 1
|
||||
) -> dict | None:
|
||||
"""登记实例侧用户主动平仓风控(中控点平仓/全平)。"""
|
||||
if count <= 0 or not (ex.get("flask_url") or "").strip():
|
||||
return None
|
||||
return await _fetch_flask_json(
|
||||
client,
|
||||
ex,
|
||||
"/api/hub/account-risk/user-close",
|
||||
method="POST",
|
||||
json_body={"source": "user_hub", "count": int(count)},
|
||||
)
|
||||
|
||||
|
||||
def _flask_error_from_hub_mon(hub_mon: dict | None) -> str | None:
|
||||
if not isinstance(hub_mon, dict) or hub_mon.get("ok") is not False:
|
||||
return None
|
||||
@@ -1936,6 +1951,9 @@ async def api_close_position(exchange_id: str, body: ClosePositionBody):
|
||||
)
|
||||
if isinstance(sync_parsed, dict):
|
||||
out["trend_sync"] = sync_parsed
|
||||
risk_sync = await _notify_instance_user_close(flask_client, ex, count=1)
|
||||
if isinstance(risk_sync, dict):
|
||||
out["risk_sync"] = risk_sync
|
||||
_schedule_board_refresh()
|
||||
return out
|
||||
|
||||
@@ -1985,7 +2003,15 @@ async def api_close_exchange(exchange_id: str):
|
||||
body = r.json()
|
||||
except Exception:
|
||||
body = {"raw": (r.text or "")[:2000]}
|
||||
out = {"exchange": ex, "status_code": r.status_code, "payload": body}
|
||||
ok = bool(isinstance(body, dict) and body.get("ok"))
|
||||
out = {"exchange": ex, "status_code": r.status_code, "payload": body, "ok": ok}
|
||||
if ok and isinstance(body, dict):
|
||||
closed = body.get("closed") or []
|
||||
n = len(closed) if isinstance(closed, list) else 0
|
||||
if n > 0:
|
||||
risk_sync = await _notify_instance_user_close(client, ex, count=n)
|
||||
if isinstance(risk_sync, dict):
|
||||
out["risk_sync"] = risk_sync
|
||||
_schedule_board_refresh()
|
||||
return out
|
||||
|
||||
@@ -2005,7 +2031,15 @@ async def api_close_all(body: CloseAllBody | None = Body(default=None)):
|
||||
payload = r.json()
|
||||
except Exception:
|
||||
payload = {"raw": (r.text or "")[:2000]}
|
||||
return {"id": ex["id"], "name": ex["name"], "status_code": r.status_code, "payload": payload}
|
||||
row = {"id": ex["id"], "name": ex["name"], "status_code": r.status_code, "payload": payload}
|
||||
if isinstance(payload, dict) and payload.get("ok"):
|
||||
closed = payload.get("closed") or []
|
||||
n = len(closed) if isinstance(closed, list) else 0
|
||||
if n > 0:
|
||||
risk_sync = await _notify_instance_user_close(client, ex, count=n)
|
||||
if isinstance(risk_sync, dict):
|
||||
row["risk_sync"] = risk_sync
|
||||
return row
|
||||
except Exception as e:
|
||||
return {"id": ex["id"], "name": ex["name"], "status_code": None, "error": str(e)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user