Show open-capacity labels, enlarge funds, move rules; WeCom on short funds.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-29 17:53:43 +08:00
parent 6081fb7e48
commit 80c561bdce
7 changed files with 399 additions and 31 deletions
+35
View File
@@ -17,6 +17,7 @@ from ..env_store import live_ready
from .clock import can_open_new, window_key
from .exits import check_expiry_close, check_exits, resolve_exit_target
from .group import next_group_id
from .open_capacity import assess_open_capacity, maybe_notify_funds_short
logger = logging.getLogger(__name__)
@@ -101,6 +102,23 @@ class StrategyEngine:
self._set_state(last_error=None)
last_error = None
allow_open = can_open_new(skip_weekends=skip_weekends)
try:
open_cap = assess_open_capacity(self.db)
except Exception:
logger.exception("assess_open_capacity failed")
open_cap = {
"perp_can_open": None,
"option_can_open": None,
"perp_label": f"永续{int(round(leverage))}x —",
"option_label": "期权 —",
"funds_ok": False,
"leverage": leverage,
}
if open_cap.get("perp_can_open") is False or open_cap.get("option_can_open") is False:
try:
maybe_notify_funds_short(open_cap)
except Exception:
pass
return {
"running": bool(row["running"]),
"phase": row["phase"],
@@ -120,6 +138,7 @@ class StrategyEngine:
"atm_open_offset_enabled": atm_off_on,
"max_atm_open_offset": max_atm_off,
"can_open": allow_open,
"open_capacity": open_cap,
"last_error": last_error,
"position": upl,
"residuals": self.matcher.list_residual_options(pending_only=True),
@@ -593,6 +612,22 @@ class StrategyEngine:
self._set_state(phase="open", last_error="有未平仓,禁止开下一组")
return
try:
cap = assess_open_capacity(self.db)
if cap.get("perp_can_open") is False or cap.get("option_can_open") is False:
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"
)
self._set_state(phase="wait_funds", last_error=f"资金不足,暂不可开新仓:{detail}")
maybe_notify_funds_short(cap)
return
if st["phase"] == "wait_funds":
self._set_state(phase="idle", last_error=None)
except Exception:
logger.exception("open capacity gate failed")
self._set_state(phase="wait_signal")
pick = await get_session().pick_for_open_async()
if pick is None: