fix: hide hub close/entrust controls for intraday discipline profile

Expose intraday_discipline via hub meta and block manual close/tpsl APIs; Gate instance card no longer shows 全平/平仓/委托.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-06 02:26:22 +08:00
parent a268a93027
commit 4904a86e03
8 changed files with 119 additions and 22 deletions
+34
View File
@@ -2050,6 +2050,27 @@ def _merge_flask_exchange_tpsl(agent_row: dict, snap: dict | None, hub_mon: dict
)
_INTRADAY_CLOSE_BLOCK_MSG = (
"日内账户禁止中控手动平仓/改委托,请等待计划止损/止盈或整点强制清仓"
)
def _meta_intraday_discipline(meta: dict | None) -> bool:
if not isinstance(meta, dict):
return False
if meta.get("intraday_discipline") is True:
return True
return meta.get("order_entry_profile") == "intraday"
async def _fetch_exchange_intraday_discipline(
client: httpx.AsyncClient, ex: dict
) -> bool:
data = await _fetch_flask_json(client, ex, "/api/hub/meta")
meta = (data or {}).get("meta") if isinstance(data, dict) else None
return _meta_intraday_discipline(meta if isinstance(meta, dict) else None)
async def _fetch_exchange_flask_bundle(
client: httpx.AsyncClient, ex: dict, *, trading_day: str | None = None
) -> tuple[dict | None, dict | None, list | None, dict | None, dict | None, dict | None]:
@@ -2428,6 +2449,8 @@ async def api_close_position(exchange_id: str, body: ClosePositionBody):
raise HTTPException(status_code=400, detail="side 须为 long 或 short")
url = f"{ex['agent_url'].rstrip('/')}/emergency/close-position"
async with httpx.AsyncClient() as client:
if await _fetch_exchange_intraday_discipline(client, ex):
raise HTTPException(status_code=403, detail=_INTRADAY_CLOSE_BLOCK_MSG)
r = await client.post(
url,
headers=_agent_headers(),
@@ -2464,6 +2487,8 @@ async def api_place_tpsl(exchange_id: str, body: PlaceTpslBody):
raise HTTPException(status_code=404, detail="账户未启用")
url = f"{ex['agent_url'].rstrip('/')}/orders/place-tpsl"
async with httpx.AsyncClient() as client:
if await _fetch_exchange_intraday_discipline(client, ex):
raise HTTPException(status_code=403, detail=_INTRADAY_CLOSE_BLOCK_MSG)
r = await client.post(
url,
headers=_agent_headers(),
@@ -2521,6 +2546,8 @@ async def api_close_exchange(exchange_id: str):
raise HTTPException(status_code=404, detail="账户未启用")
url = f"{ex['agent_url'].rstrip('/')}/emergency/close-all"
async with httpx.AsyncClient() as client:
if await _fetch_exchange_intraday_discipline(client, ex):
raise HTTPException(status_code=403, detail=_INTRADAY_CLOSE_BLOCK_MSG)
r = await client.post(url, headers=_agent_headers(), timeout=120.0)
try:
body = r.json()
@@ -2557,6 +2584,13 @@ async def api_close_all(body: CloseAllBody | None = Body(default=None)):
async with httpx.AsyncClient() as client:
async def one(ex: dict):
if await _fetch_exchange_intraday_discipline(client, ex):
return {
"id": ex["id"],
"name": ex["name"],
"skipped": True,
"reason": _INTRADAY_CLOSE_BLOCK_MSG,
}
url = f"{ex['agent_url'].rstrip('/')}/emergency/close-all"
try:
r = await client.post(url, headers=_agent_headers(), timeout=120.0)