Add risk leverage basis option: actual ask vs selection leverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-08-01 17:01:18 +08:00
parent f1da2778ef
commit 9c515644a3
7 changed files with 201 additions and 7 deletions
+71
View File
@@ -8,6 +8,8 @@ from app.strategy.risk_sizing import (
BASE_PERP_ETH,
compute_k,
floor_k_1dp,
normalize_risk_leverage_basis,
resolve_sizing_option_ask,
unit_cost,
)
@@ -78,3 +80,72 @@ def test_compute_k_too_small() -> None:
def test_unit_cost() -> None:
assert abs(unit_cost(index_px=2000, option_ask=20, fee_rate=0.0005) - 43.0) < 1e-9
def test_normalize_risk_leverage_basis() -> None:
assert normalize_risk_leverage_basis("actual") == "actual"
assert normalize_risk_leverage_basis("selection") == "selection"
assert normalize_risk_leverage_basis("min_option_leverage") == "selection"
assert normalize_risk_leverage_basis("weird", default="selection") == "selection"
def test_resolve_sizing_ask_selection_vs_actual() -> None:
# 指数 2000、选约杠杆 100 → 隐含卖一 20;实际卖一更便宜 10
sel_ask, basis = resolve_sizing_option_ask(
index_px=2000.0,
option_ask=10.0,
leverage_basis="selection",
min_option_leverage=100.0,
)
assert basis == "selection"
assert abs(sel_ask - 20.0) < 1e-9
act_ask, basis2 = resolve_sizing_option_ask(
index_px=2000.0,
option_ask=10.0,
leverage_basis="actual",
min_option_leverage=100.0,
)
assert basis2 == "actual"
assert abs(act_ask - 10.0) < 1e-9
def test_selection_basis_yields_smaller_k_when_ask_cheap() -> None:
# 预算 43:选约隐含 ask=20 → k=1;若用实际 ask=10 → 单位成本更小 → k 更大
r_sel = compute_k(budget=43.0, index_px=2000.0, option_ask=20.0, fee_rate=0.0005)
r_act = compute_k(budget=43.0, index_px=2000.0, option_ask=10.0, fee_rate=0.0005)
assert r_sel.ok and r_act.ok
assert r_sel.k == 1.0
assert r_act.k is not None and r_act.k > r_sel.k
def test_compute_risk_sizing_respects_basis(tmp_path, monkeypatch) -> None:
monkeypatch.setenv("MODE", "SIM")
from app.models.db import Database
from app.strategy.risk_sizing import compute_risk_sizing
db = Database(tmp_path / "risk_basis.db")
db.set_setting("sizing_mode", "risk_based")
db.set_setting("risk_loss_mode", "absolute")
db.set_setting("risk_loss_usdt", "43")
db.set_setting("fee_rate", "0.0005")
db.set_setting("min_option_leverage", "100")
db.set_setting("risk_perp_unit", "1")
db.set_setting("risk_option_unit", "2")
db.set_setting("risk_exit_unit", "15")
db.set_setting("risk_leverage_basis", "selection")
r1 = compute_risk_sizing(index_px=2000.0, option_ask=10.0, db=db)
assert r1.ok
assert r1.leverage_basis == "selection"
assert r1.k == 1.0
assert r1.actual_option_ask == 10.0
assert r1.option_ask == 20.0
db.set_setting("risk_leverage_basis", "actual")
r2 = compute_risk_sizing(index_px=2000.0, option_ask=10.0, db=db)
assert r2.ok
assert r2.leverage_basis == "actual"
assert r2.k is not None and r2.k > 1.0
assert r2.option_ask == 10.0
db.close()