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:
@@ -0,0 +1,53 @@
|
||||
"""以损定仓纯函数测试。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from app.strategy.risk_sizing import (
|
||||
BASE_EXIT_USDT,
|
||||
BASE_OPTION_ETH,
|
||||
BASE_PERP_ETH,
|
||||
compute_k,
|
||||
floor_k_1dp,
|
||||
unit_cost,
|
||||
)
|
||||
|
||||
|
||||
def test_floor_k_1dp() -> None:
|
||||
assert floor_k_1dp(1.29) == 1.2
|
||||
assert floor_k_1dp(0.19) == 0.1
|
||||
assert floor_k_1dp(0.09) == 0.0
|
||||
assert floor_k_1dp(2.0) == 2.0
|
||||
|
||||
|
||||
def test_compute_k_scales_1_2_15() -> None:
|
||||
# I=2000, A=20, fee=0.0005 → unit = 2*20 + 2000*0.0005*3 = 40 + 3 = 43
|
||||
# budget=43 → k=1.0
|
||||
r = compute_k(budget=43.0, index_px=2000.0, option_ask=20.0, fee_rate=0.0005)
|
||||
assert r.ok
|
||||
assert r.k == 1.0
|
||||
assert r.perp_qty_eth == BASE_PERP_ETH
|
||||
assert r.option_qty_eth == BASE_OPTION_ETH
|
||||
assert r.net_profit_target == BASE_EXIT_USDT
|
||||
assert r.max_loss is not None and r.max_loss <= 43.0 + 1e-6
|
||||
|
||||
|
||||
def test_compute_k_never_exceeds_budget() -> None:
|
||||
r = compute_k(budget=50.0, index_px=1900.0, option_ask=18.5, fee_rate=0.0005)
|
||||
assert r.ok
|
||||
assert r.k is not None
|
||||
assert abs(r.k * 10 - round(r.k * 10)) < 1e-9 # 一位小数
|
||||
assert r.max_loss is not None and r.max_loss <= 50.0 + 1e-6
|
||||
assert r.perp_qty_eth == round(1.0 * r.k, 4)
|
||||
assert r.option_qty_eth == round(2.0 * r.k, 4)
|
||||
assert r.net_profit_target == round(15.0 * r.k, 4)
|
||||
|
||||
|
||||
def test_compute_k_too_small() -> None:
|
||||
# unit≈43, budget=2 → k_raw≪0.1
|
||||
r = compute_k(budget=2.0, index_px=2000.0, option_ask=20.0, fee_rate=0.0005)
|
||||
assert not r.ok
|
||||
assert "最小仓" in r.detail or "k=" in r.detail
|
||||
|
||||
|
||||
def test_unit_cost() -> None:
|
||||
assert abs(unit_cost(index_px=2000, option_ask=20, fee_rate=0.0005) - 43.0) < 1e-9
|
||||
Reference in New Issue
Block a user