Add hub strategy compare page for perp vs options vs 7:3 hedge.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
"""策略对比仓位与情景测算."""
|
||||
from __future__ import annotations
|
||||
|
||||
from lib.hub.hub_compare_lib import run_compare
|
||||
|
||||
|
||||
def test_long_eth_realistic_asks():
|
||||
out = run_compare(
|
||||
{
|
||||
"base": "ETH",
|
||||
"direction": "long",
|
||||
"entry": 3500,
|
||||
"sl": 3400,
|
||||
"tp": 3700,
|
||||
"risk_u": 10,
|
||||
"option": {"opt_type": "C", "strike": 3600, "ask": 50},
|
||||
"hedge": {
|
||||
"main": {"opt_type": "C", "strike": 3600, "ask": 50},
|
||||
"side": {"opt_type": "P", "strike": 3400, "ask": 30},
|
||||
},
|
||||
}
|
||||
)
|
||||
assert out["ok"] is True
|
||||
perp = out["perp"]
|
||||
# 每张止损 = 100 * 0.01 = 1U → 10 张
|
||||
assert perp["sheets"] == 10
|
||||
assert abs(perp["path_b_sl"] + 10) < 1e-6
|
||||
assert perp["path_a_tp"] > 0
|
||||
assert perp["path_c_realized"] == perp["path_b_sl"]
|
||||
assert perp["path_c_missed"] == perp["path_a_tp"]
|
||||
|
||||
opt = out["option"]
|
||||
assert opt["ok"] is True
|
||||
# unit = 50 * 0.01 = 0.5U → 20 张, premium = 10
|
||||
assert opt["sheets"] == 20
|
||||
assert abs(opt["premium_u"] - 10) < 1e-6
|
||||
assert abs(opt["path_b_worst"] + 10) < 1e-6
|
||||
# at TP 3700, call 3600 intrinsic = 100 * 20 * 0.01 = 20, pnl = 20-10 = 10
|
||||
assert abs(opt["path_a_tp"] - 10) < 1e-6
|
||||
assert abs(opt["path_c_hold_to_tp"] - opt["path_a_tp"]) < 1e-6
|
||||
|
||||
hedge = out["hedge"]
|
||||
assert hedge["ok"] is True
|
||||
# main budget 7, unit 0.5 → 14 sheets; side budget 3, unit 0.3 → 10 sheets
|
||||
assert hedge["main"]["sheets"] == 14
|
||||
assert hedge["side"]["sheets"] == 10
|
||||
assert out["recommend"]["choice"] in ("合约", "单期权", "期期对冲")
|
||||
|
||||
|
||||
def test_short_validation():
|
||||
bad = run_compare(
|
||||
{
|
||||
"base": "ETH",
|
||||
"direction": "short",
|
||||
"entry": 3500,
|
||||
"sl": 3400,
|
||||
"tp": 3300,
|
||||
"risk_u": 10,
|
||||
}
|
||||
)
|
||||
assert bad["ok"] is False
|
||||
|
||||
|
||||
def test_recommend_has_bullets():
|
||||
out = run_compare(
|
||||
{
|
||||
"base": "ETH",
|
||||
"direction": "long",
|
||||
"entry": 3500,
|
||||
"sl": 3490,
|
||||
"tp": 3520,
|
||||
"risk_u": 10,
|
||||
"option": {"opt_type": "C", "strike": 3500, "ask": 20},
|
||||
"hedge": {
|
||||
"main": {"opt_type": "C", "strike": 3500, "ask": 20},
|
||||
"side": {"opt_type": "P", "strike": 3480, "ask": 15},
|
||||
},
|
||||
}
|
||||
)
|
||||
assert out["ok"] is True
|
||||
assert out["recommend"]["choice"]
|
||||
assert len(out["recommend"]["bullets"]) == 3
|
||||
Reference in New Issue
Block a user