"""币本位模式预算与合约族单测.""" from __future__ import annotations import os import unittest from unittest.mock import patch class TestOptionsMarginMode(unittest.TestCase): def test_normalize_mode(self): from lib.options.options_margin_mode_lib import normalize_options_margin_mode self.assertEqual(normalize_options_margin_mode("usdc"), "usdc") self.assertEqual(normalize_options_margin_mode("coin"), "coin") self.assertEqual(normalize_options_margin_mode("币本位"), "coin") with patch.dict(os.environ, {}, clear=False): os.environ.pop("OKX_OPTIONS_MARGIN_MODE", None) self.assertEqual(normalize_options_margin_mode(None), "coin") self.assertEqual(normalize_options_margin_mode(""), "coin") def test_inst_family(self): from lib.options.options_margin_mode_lib import inst_family_for_underlying self.assertEqual(inst_family_for_underlying("ETH", margin_mode="usdc"), "ETH-USD_UM") self.assertEqual(inst_family_for_underlying("ETH", margin_mode="coin"), "ETH-USD") def test_margin_mode_from_inst_id(self): from lib.options.options_margin_mode_lib import margin_mode_from_inst_id self.assertEqual(margin_mode_from_inst_id("ETH-USD_UM-260701-2500-C"), "usdc") self.assertEqual(margin_mode_from_inst_id("ETH-USD-260701-2500-C"), "coin") def test_coin_budget_compound(self): from lib.options.options_margin_mode_lib import compute_coin_budget_usdt with patch.dict(os.environ, {}, clear=False): r = compute_coin_budget_usdt( 20.0, compound=True, buffer=0.95, max_enabled=False, ) self.assertTrue(r["ok"]) self.assertAlmostEqual(r["budget_usdt"], 19.0, places=6) def test_coin_budget_max_cap(self): from lib.options.options_margin_mode_lib import compute_coin_budget_usdt r = compute_coin_budget_usdt( 100.0, compound=True, buffer=0.95, max_enabled=True, max_usdt=50.0, ) self.assertTrue(r["ok"]) self.assertAlmostEqual(r["budget_usdt"], 50.0, places=6) self.assertTrue(r["capped_by_max"]) def test_coin_budget_fixed(self): from lib.options.options_margin_mode_lib import compute_coin_budget_usdt r = compute_coin_budget_usdt( 100.0, compound=False, buffer=0.95, fixed_budget_usdt=10.0, max_enabled=False, ) self.assertAlmostEqual(r["budget_usdt"], 9.5, places=6) def test_sheets_from_coin(self): from lib.options.options_margin_mode_lib import calc_sheets_from_coin_balance # ask 0.01 ETH per 1 ETH, ctMult 0.01 → 每张 0.0001 ETH; 0.01 ETH×0.97 缓冲可开 97 张 r = calc_sheets_from_coin_balance( quote_per_unit=0.01, ct_mult=0.01, min_sz=1, coin_available=0.01, ) self.assertTrue(r["ok"]) self.assertEqual(r["sheets"], 97) def test_spot_buy_buffer_normalize(self): from lib.options.options_margin_mode_lib import normalize_coin_spot_buy_buffer self.assertAlmostEqual(normalize_coin_spot_buy_buffer(1.10), 1.10) self.assertAlmostEqual(normalize_coin_spot_buy_buffer(0.10), 1.10) self.assertAlmostEqual(normalize_coin_spot_buy_buffer(1.25), 1.25) def test_plan_coin_open_by_budget(self): from lib.options.options_margin_mode_lib import plan_coin_open_by_budget # ask 0.01, ct 0.1 → 单张权利金 0.001 ETH;×1.1=0.0011;×指数 2000 → 2.2 USDT/张 r = plan_coin_open_by_budget( quote_per_unit=0.01, ct_mult=0.1, min_sz=1, budget_usdt=10.0, index_px=2000.0, ask_sz=100, spot_buy_buffer=1.10, ) self.assertTrue(r["ok"], r.get("msg")) self.assertEqual(r["sheets"], 4) # floor(10/2.2)=4 self.assertAlmostEqual(r["buy_usdt"], 4 * 0.01 * 0.1 * 1.10 * 2000, places=4) self.assertLess(r["buy_usdt"], 10.0) one = plan_coin_open_by_budget( quote_per_unit=0.01, ct_mult=0.1, min_sz=1, budget_usdt=10.0, index_px=2000.0, ask_sz=100, spot_buy_buffer=1.10, target_sheets=1, ) self.assertTrue(one["ok"], one.get("msg")) self.assertEqual(one["sheets"], 1) self.assertAlmostEqual(one["buy_usdt"], 0.01 * 0.1 * 1.10 * 2000, places=4) if __name__ == "__main__": unittest.main()