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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user