Files
crypto_monitor/tests/test_hub_exchange_orders_okx.py
2026-06-03 21:00:22 +08:00

68 lines
2.1 KiB
Python

"""OKX 中控委托:须为 OCO 条件单,不得带 reduceOnly 或分两笔 market。"""
from __future__ import annotations
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "manual_trading_hub"))
from exchange_orders import _okx_place_tp_sl # noqa: E402
class TestHubOkxPlaceTpsl(unittest.TestCase):
def test_okx_place_tpsl_single_oco_without_reduce_only(self):
captured: list[dict] = []
def fake_create_order(symbol, order_type, side, amount, price, params):
captured.append(
{
"symbol": symbol,
"type": order_type,
"side": side,
"amount": amount,
"params": dict(params or {}),
}
)
return {"id": "algo-1"}
ex = MagicMock()
ex.create_order = fake_create_order
ex.load_markets = MagicMock()
ex.amount_to_precision = lambda sym, amt: str(amt)
ex.price_to_precision = lambda sym, px: str(px)
with patch.dict(
"os.environ",
{"OKX_POS_MODE": "hedge", "OKX_TD_MODE": "cross"},
clear=False,
):
_okx_place_tp_sl(
ex,
"HYPE/USDT:USDT",
"short",
6.0,
75.5,
70.2,
)
self.assertEqual(len(captured), 1, captured)
call = captured[0]
self.assertEqual(call["type"], "oco")
self.assertEqual(call["side"], "buy")
params = call["params"]
self.assertNotIn("reduceOnly", params)
self.assertEqual(params.get("posSide"), "short")
self.assertEqual(params.get("positionSide"), "short")
self.assertEqual(params.get("stopLossPrice"), 75.5)
self.assertEqual(params.get("takeProfitPrice"), 70.2)
self.assertEqual(params.get("tpOrdPx"), "-1")
self.assertEqual(params.get("slOrdPx"), "-1")
self.assertNotIn("stopLoss", params)
if __name__ == "__main__":
unittest.main()