Harden strategy SoT: fail-closed funds gate, shared open pipeline, LIVE switch guards.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-30 01:06:32 +08:00
parent 4c537e7520
commit 200702d066
14 changed files with 471 additions and 139 deletions
+39 -4
View File
@@ -98,11 +98,18 @@ def _sim_balances(db: Database) -> dict[str, float]:
}
def assess_open_capacity(db: Database | None = None) -> dict[str, Any]:
def assess_open_capacity(
db: Database | None = None,
*,
option_ask: float | None = None,
option_qty_eth: float | None = None,
perp_qty_eth: float | None = None,
) -> dict[str, Any]:
"""
返回永续/期权是否有足够交易账户资金开新仓。
- 永续:交易账户 USDT >= 名义/杠杆
- 期权:交易账户 USDC >= 卖一×名义×(1+费率)
可选覆盖 ask/名义(选约后应用选中腿卖一,避免与 max(call,put) 打架)。
"""
global _notified_while_short
db = db or get_db()
@@ -111,11 +118,20 @@ def assess_open_capacity(db: Database | None = None) -> dict[str, Any]:
lev = float(ledger.get_setting_float("leverage", s.leverage) or 3)
if lev <= 0:
lev = 3.0
perp_qty = float(ledger.get_setting_float("perp_qty_eth", s.perp_qty_eth) or 1)
opt_qty = float(ledger.get_setting_float("option_qty_eth", s.option_qty_eth) or 2)
perp_qty = float(
perp_qty_eth
if perp_qty_eth is not None
else (ledger.get_setting_float("perp_qty_eth", s.perp_qty_eth) or 1)
)
opt_qty = float(
option_qty_eth
if option_qty_eth is not None
else (ledger.get_setting_float("option_qty_eth", s.option_qty_eth) or 2)
)
fee_rate = float(ledger.get_setting_float("fee_rate", s.fee_rate) or 0.0005)
idx, ask = _index_and_option_ask()
idx, ask_book = _index_and_option_ask()
ask = float(option_ask) if option_ask is not None and float(option_ask) > 0 else ask_book
margin_need = (float(idx) * perp_qty / lev) if idx and idx > 0 else None
premium_need = (
float(ask) * opt_qty * (1.0 + fee_rate) if ask is not None and ask > 0 else None
@@ -183,6 +199,25 @@ def assess_open_capacity(db: Database | None = None) -> dict[str, Any]:
}
def funds_gate_blocks(cap: dict[str, Any] | None) -> tuple[bool, str]:
"""
Fail-closed:仅当永续与期权均为 True 才放行。
None(未知,如币安未接余额)或 False → 拦截。
"""
if not cap:
return True, "资金可开判定结果为空,拒绝开仓"
if cap.get("perp_can_open") is not True or cap.get("option_can_open") is not True:
detail = (
f"{cap.get('perp_label')} · {cap.get('option_label')}"
f"永续需≈{cap.get('perp_need_usdt')}U/有{cap.get('perp_have_usdt')}U"
f"期权需≈{cap.get('option_need_usdc')}U/有{cap.get('option_have_usdc')}U"
)
if cap.get("perp_can_open") is None or cap.get("option_can_open") is None:
detail += "(余额/盘口未知,fail-closed 拒绝开仓)"
return True, f"资金不足或状态未知,暂不可开新仓:{detail}"
return False, ""
def maybe_notify_funds_short(cap: dict[str, Any] | None = None) -> None:
"""仅在「不能开」时推送一次;能开绝不通知。"""
global _notified_while_short