Add hub perpetual-options hedge calculator tab and sizing formula.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-28 12:37:51 +08:00
parent f360242188
commit 4bcf88b5cb
6 changed files with 496 additions and 5 deletions
+86
View File
@@ -0,0 +1,86 @@
"""hub_perp_options_calc_lib 永期对冲测算."""
import unittest
from lib.hub.hub_perp_options_calc_lib import calc_perp_options_hedge
class HubPerpOptionsCalcTests(unittest.TestCase):
def test_example_1800_50_15_100(self):
data, err = calc_perp_options_hedge(
base="ETH",
spot=1800,
capital_usdt=3000,
target_profit_u=15,
move_mode="points",
move_value=50,
perp_leverage=10,
option_leverage=100,
ct_mult=0.01,
)
self.assertIsNone(err)
assert data is not None
self.assertEqual(data["prem_per_coin"], 18.0)
self.assertEqual(data["perp_gross_u"], 50.0)
# fee = (1800+1850)*0.0005 = 1.825
self.assertAlmostEqual(data["perp_fee_u"], 1.825, places=6)
self.assertAlmostEqual(data["premium_budget_u"], 33.175, places=6)
self.assertAlmostEqual(data["opt_coins"], 33.175 / 18.0, places=6)
self.assertAlmostEqual(data["opt_sheets"], data["opt_coins"] / 0.01, places=4)
self.assertAlmostEqual(data["case_a"]["net_u"], 15.0, places=6)
# B: opt_net = coins*50 - coins*18 = coins*32; portfolio = opt_net - 50
coins = data["opt_coins"]
self.assertAlmostEqual(data["case_b"]["opt_net_u"], coins * 32.0, places=6)
self.assertAlmostEqual(data["case_b"]["portfolio_net_u"], coins * 32.0 - 50.0, places=6)
self.assertAlmostEqual(data["perp_margin_u"], 180.0, places=6)
self.assertTrue(data["capital_ok"])
def test_pct_mode(self):
data, err = calc_perp_options_hedge(
base="BTC",
spot=100000,
capital_usdt=5000,
target_profit_u=100,
move_mode="pct",
move_value=1,
perp_leverage=5,
option_leverage=50,
ct_mult=0.01,
)
self.assertIsNone(err)
assert data is not None
self.assertAlmostEqual(data["move_points"], 1000.0, places=6)
self.assertAlmostEqual(data["perp_gross_u"], 1000.0, places=6)
self.assertAlmostEqual(data["prem_per_coin"], 2000.0, places=6)
def test_budget_too_small(self):
data, err = calc_perp_options_hedge(
base="ETH",
spot=1800,
capital_usdt=3000,
target_profit_u=60,
move_mode="points",
move_value=50,
perp_leverage=10,
option_leverage=100,
)
self.assertIsNone(data)
self.assertIn("无法开期权", err or "")
def test_bad_base(self):
data, err = calc_perp_options_hedge(
base="SOL",
spot=100,
capital_usdt=1000,
target_profit_u=10,
move_mode="points",
move_value=5,
perp_leverage=5,
option_leverage=20,
)
self.assertIsNone(data)
self.assertIsNotNone(err)
if __name__ == "__main__":
unittest.main()