271865fa3d
审计:开关关闭时隐藏全仓芯片并自动勾选指定张数;报价/余额热同步 compound_full_enabled;API 将 compound_full 归一为 sheets(缺张数默认1);单测覆盖开关开关两种归一路径。 Co-authored-by: Cursor <cursoragent@cursor.com>
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
"""按可用余额打满 / 全仓复利定仓."""
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from lib.options.options_pricing_lib import (
|
|
resolve_budget_full_usdc,
|
|
resolve_compound_full_usdc,
|
|
)
|
|
from lib.options.options_position_limit_lib import (
|
|
compound_full_single_position_block_msg,
|
|
count_live_option_positions,
|
|
)
|
|
|
|
|
|
class TestOptionsBudgetModes(unittest.TestCase):
|
|
def test_balance_above_budget_uses_budget(self):
|
|
self.assertEqual(resolve_budget_full_usdc(100.0, 10.0), 10.0)
|
|
|
|
def test_balance_below_budget_uses_balance(self):
|
|
self.assertEqual(resolve_budget_full_usdc(5.0, 10.0), 5.0)
|
|
|
|
def test_balance_equals_budget(self):
|
|
self.assertEqual(resolve_budget_full_usdc(10.0, 10.0), 10.0)
|
|
|
|
def test_compound_full_no_cap_uses_all(self):
|
|
self.assertEqual(
|
|
resolve_compound_full_usdc(200.0, cap_enabled=False, cap_usdc=50.0),
|
|
200.0,
|
|
)
|
|
|
|
def test_compound_full_cap_on(self):
|
|
self.assertEqual(
|
|
resolve_compound_full_usdc(200.0, cap_enabled=True, cap_usdc=50.0),
|
|
50.0,
|
|
)
|
|
self.assertEqual(
|
|
resolve_compound_full_usdc(30.0, cap_enabled=True, cap_usdc=50.0),
|
|
30.0,
|
|
)
|
|
|
|
def test_compound_full_cap_invalid_falls_back_to_balance(self):
|
|
self.assertEqual(
|
|
resolve_compound_full_usdc(80.0, cap_enabled=True, cap_usdc=0),
|
|
80.0,
|
|
)
|
|
self.assertEqual(
|
|
resolve_compound_full_usdc(80.0, cap_enabled=True, cap_usdc=None),
|
|
80.0,
|
|
)
|
|
|
|
def test_compound_full_blocks_when_position_open(self):
|
|
rows = [{"instId": "ETH-USD_UM-260812-1870-P", "pos": "1"}]
|
|
msg = compound_full_single_position_block_msg(
|
|
object(), fetch_positions=lambda _ex: rows
|
|
)
|
|
self.assertIsNotNone(msg)
|
|
self.assertIn("1 笔", msg or "")
|
|
|
|
def test_compound_full_allows_when_flat(self):
|
|
msg = compound_full_single_position_block_msg(
|
|
object(), fetch_positions=lambda _ex: []
|
|
)
|
|
self.assertIsNone(msg)
|
|
self.assertEqual(count_live_option_positions([]), 0)
|
|
|
|
def test_normalize_size_mode_when_compound_off(self):
|
|
import os
|
|
from unittest.mock import patch
|
|
|
|
from lib.options import options_register as reg
|
|
|
|
with patch.dict(os.environ, {"OKX_OPTIONS_COMPOUND_FULL_ENABLED": "false"}):
|
|
mode, note = reg._normalize_size_mode("compound_full")
|
|
self.assertEqual(mode, "sheets")
|
|
self.assertIsNotNone(note)
|
|
mode2, note2 = reg._normalize_size_mode("budget_full")
|
|
self.assertEqual(mode2, "budget_full")
|
|
self.assertIsNone(note2)
|
|
mode3, _ = reg._normalize_size_mode("sheets")
|
|
self.assertEqual(mode3, "sheets")
|
|
|
|
def test_normalize_size_mode_when_compound_on(self):
|
|
import os
|
|
from unittest.mock import patch
|
|
|
|
from lib.options import options_register as reg
|
|
|
|
with patch.dict(os.environ, {"OKX_OPTIONS_COMPOUND_FULL_ENABLED": "true"}):
|
|
mode, note = reg._normalize_size_mode("budget_full")
|
|
self.assertEqual(mode, "compound_full")
|
|
self.assertIsNone(note)
|
|
mode2, _ = reg._normalize_size_mode("compound_full")
|
|
self.assertEqual(mode2, "compound_full")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|