Allow risk-based 永期 exits via premium multiple as well as base×k.

Settings UI picks 基数 or 权利金×n; sizing preview and control monitor follow.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-07 18:13:11 +08:00
parent ab612df818
commit 06f612aa52
5 changed files with 161 additions and 28 deletions
+6 -2
View File
@@ -524,10 +524,14 @@ async def put_strategy_settings(
)
).strip().lower()
if sizing_mode == "risk_based":
data["exit_mode"] = "fixed_usdt"
# 永期以损:允许 exit_mode=fixed_usdt(基数×k)或 premium_multiple(权利金×倍)
# 期期仍强制 fixed(目标由预算×盈亏比写入)
if hedge_mode == "option_option":
data["exit_mode"] = "fixed_usdt"
data.pop("perp_qty_eth", None)
data.pop("option_qty_eth", None)
data.pop("net_profit_target", None)
if str(data.get("exit_mode") or db.get_setting("exit_mode", "") or "").strip().lower() != "premium_multiple":
data.pop("net_profit_target", None)
loss_mode = str(
data.get(
"risk_loss_mode",
+39 -6
View File
@@ -703,26 +703,42 @@ def apply_risk_sizing_to_ledger(
if not r.ok:
return r
# 以损定仓强制 fixed_usdt;出场 = exit_unit × k
database.set_setting("exit_mode", "fixed_usdt")
exit_mode = str(
ledger.get_setting_str("exit_mode", "fixed_usdt") or "fixed_usdt"
).strip().lower()
s = get_settings()
prem_mult = float(
ledger.get_setting_float("premium_exit_multiple", s.premium_exit_multiple)
or s.premium_exit_multiple
)
database.set_setting("perp_qty_eth", str(r.perp_qty_eth))
database.set_setting("option_qty_eth", str(r.option_qty_eth))
database.set_setting("net_profit_target", str(r.net_profit_target))
database.set_setting("risk_last_k", str(r.k))
database.set_setting(
"risk_last_max_loss",
f"{r.max_loss:.2f}" if r.max_loss is not None else "",
)
if exit_mode == "premium_multiple":
database.set_setting("exit_mode", "premium_multiple")
# 预估展示用:估权利金×倍数;开仓后以真实 initial_premium 锁定
est = float(r.premium_est or 0) * max(0.0, prem_mult)
if est > 0:
database.set_setting("net_profit_target", f"{est:.4f}")
exit_log = f"prem×{prem_mult:g}{est:.2f}"
else:
database.set_setting("exit_mode", "fixed_usdt")
database.set_setting("net_profit_target", str(r.net_profit_target))
exit_log = f"{r.net_profit_target or 0:.4f}"
logger.info(
"risk_sizing applied k=%.1f basis=%s sizing_ask=%.4f actual_ask=%.4f "
"perp=%.4f opt=%.4f exit=%.4f max_loss=%.4f budget=%.4f",
"perp=%.4f opt=%.4f exit=%s max_loss=%.4f budget=%.4f",
r.k or 0,
r.leverage_basis or "?",
r.option_ask or 0,
r.actual_option_ask or 0,
r.perp_qty_eth or 0,
r.option_qty_eth or 0,
r.net_profit_target or 0,
exit_log,
r.max_loss or 0,
r.budget or 0,
)
@@ -766,6 +782,20 @@ def preview_risk_sizing(db: Database | None = None) -> dict[str, Any]:
r = compute_risk_sizing(index_px=float(idx), option_ask=float(ask), db=database)
perp_u, opt_u, exit_u = read_risk_units(ledger)
mg = resolve_martingale(database, ledger=ledger)
s = get_settings()
exit_mode = str(
ledger.get_setting_str("exit_mode", s.exit_mode) or s.exit_mode
).strip().lower()
prem_mult = float(
ledger.get_setting_float("premium_exit_multiple", s.premium_exit_multiple)
or s.premium_exit_multiple
)
exit_target = r.net_profit_target
exit_label = "基数×k"
if exit_mode == "premium_multiple":
exit_label = f"权利金×{prem_mult:g}"
if r.ok and r.premium_est is not None:
exit_target = round(float(r.premium_est) * max(0.0, prem_mult), 2)
out.update(
{
"ok": r.ok,
@@ -778,7 +808,10 @@ def preview_risk_sizing(db: Database | None = None) -> dict[str, Any]:
"max_loss": r.max_loss,
"perp_qty_eth": r.perp_qty_eth,
"option_qty_eth": r.option_qty_eth,
"net_profit_target": r.net_profit_target,
"net_profit_target": exit_target,
"exit_mode": exit_mode if exit_mode in ("fixed_usdt", "premium_multiple") else "fixed_usdt",
"premium_exit_multiple": prem_mult,
"exit_label": exit_label,
"index_px": r.index_px,
"option_ask": r.option_ask,
"actual_option_ask": r.actual_option_ask,