Add risk-based position sizing (以损定仓) with per-open k resize.

Manual vs risk modes are exclusive; each open floors k to 1 decimal so estimated premium+fees stay within the loss budget.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-29 23:32:42 +08:00
parent 0b51aa15ff
commit 3a4c8d639c
9 changed files with 803 additions and 16 deletions
+35
View File
@@ -96,9 +96,44 @@ async def sim_open_group(
option_inst = (
pick.pair.call_inst_id if option_side == "call" else pick.pair.put_inst_id
)
# 强制方向时用该腿卖一估权利金;否则用选向结果
sizing_ask = float(
option_ask
if force in ("call", "put")
else pick.option_ask
)
wkey = window_key()
db = get_db()
from ..strategy.risk_sizing import apply_risk_sizing_to_ledger
rs = apply_risk_sizing_to_ledger(
index_px=float(pick.underlying_px),
option_ask=sizing_ask,
db=db,
)
if not rs.ok:
raise HTTPException(status_code=409, detail=rs.detail)
try:
from ..strategy.open_capacity import assess_open_capacity
cap = assess_open_capacity(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"
)
raise HTTPException(
status_code=409,
detail=f"资金不足,暂不可开新仓:{detail}",
)
except HTTPException:
raise
except Exception:
pass
count = len(
db.fetchall("SELECT group_id FROM groups WHERE group_id LIKE ?", (f"G-{wkey}-%",))
)