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