Initial CoinOX instance: coin-margined options + USDT hedge.
Forked from crypto_monitor OKX instance (copy-only). Keeps standalone options, perp-options and options-options hedge; drops standalone perp entrypoints; forces coin margin; adds sim wallets; default port 5010. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
"""币本位模式预算与合约族单测."""
|
||||
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()
|
||||
Reference in New Issue
Block a user