|
|
@@ -356,6 +356,23 @@ def positions_with_wrong_symbol_response() -> DummyResponse:
|
|
|
)
|
|
|
|
|
|
|
|
|
+def positions_with_invalid_pos_side_response() -> DummyResponse:
|
|
|
+ return DummyResponse(
|
|
|
+ {
|
|
|
+ "code": "0",
|
|
|
+ "msg": "",
|
|
|
+ "data": [
|
|
|
+ {
|
|
|
+ "instId": "BTC-USDT-SWAP",
|
|
|
+ "posSide": "net",
|
|
|
+ "pos": "1",
|
|
|
+ "avgPx": "25000",
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
def market_long_signal() -> TradeSignal:
|
|
|
return TradeSignal(
|
|
|
action="long",
|
|
|
@@ -468,6 +485,14 @@ def test_build_contract_size_fails_below_min_size():
|
|
|
build_contract_size(notional=250, price=25_100, metadata=metadata)
|
|
|
|
|
|
|
|
|
+@pytest.mark.parametrize("notional", [0, -1, float("nan"), float("inf")])
|
|
|
+def test_build_contract_size_rejects_invalid_notional(notional):
|
|
|
+ metadata = InstrumentMeta(ct_val=0.01, lot_sz=1, min_sz=1)
|
|
|
+
|
|
|
+ with pytest.raises(ValueError, match="contract sizing inputs are invalid"):
|
|
|
+ build_contract_size(notional=notional, price=25_000, metadata=metadata)
|
|
|
+
|
|
|
+
|
|
|
@pytest.mark.parametrize(
|
|
|
("price", "metadata"),
|
|
|
[
|
|
|
@@ -859,3 +884,11 @@ def test_get_positions_rejects_mismatched_symbol():
|
|
|
|
|
|
with pytest.raises(ValueError, match="okx response payload is invalid"):
|
|
|
client.get_positions(symbol="BTC-USDT-SWAP")
|
|
|
+
|
|
|
+
|
|
|
+def test_get_positions_rejects_invalid_pos_side():
|
|
|
+ session = DummySession([positions_with_invalid_pos_side_response()])
|
|
|
+ client = OkxClient(config=sample_config(), session=session)
|
|
|
+
|
|
|
+ with pytest.raises(ValueError, match="okx response payload is invalid"):
|
|
|
+ client.get_positions(symbol="BTC-USDT-SWAP")
|