mirror of
https://github.com/OpenByteInc/QuantDinger.git
synced 2026-09-28 15:22:56 +08:00
155 lines
4.3 KiB
Python
155 lines
4.3 KiB
Python
import pytest
|
|
|
|
from app.services import instrument_rules
|
|
from app.services.grid.exchange_orders import normalize_grid_order_quantity
|
|
from app.services.instrument_rules import InstrumentRules
|
|
from app.services.live_trading.base import BaseRestClient
|
|
from app.services.live_trading.gate import GateSpotClient, GateUsdtFuturesClient
|
|
from app.services.live_trading.htx import HtxClient
|
|
|
|
|
|
def _gate_client(order_size_min="1", multiplier="0.0001"):
|
|
client = GateUsdtFuturesClient.__new__(GateUsdtFuturesClient)
|
|
client.get_contract = lambda **_kwargs: {
|
|
"order_size_min": order_size_min,
|
|
"quanto_multiplier": multiplier,
|
|
}
|
|
return client
|
|
|
|
|
|
def test_gate_futures_never_rounds_sub_minimum_quantity_up():
|
|
client = _gate_client()
|
|
|
|
size, headers = client._resolve_order_size(
|
|
contract="BTC_USDT",
|
|
side="sell",
|
|
base_size=0.00005,
|
|
)
|
|
|
|
assert size == "0"
|
|
assert headers is None
|
|
|
|
|
|
def test_gate_grid_quantity_is_floored_and_returned_in_base_units():
|
|
client = _gate_client()
|
|
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.00039,
|
|
market_type="swap",
|
|
) == 0.0003
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.00005,
|
|
market_type="swap",
|
|
) == 0.0
|
|
|
|
|
|
def test_htx_futures_never_rounds_sub_contract_quantity_up():
|
|
client = HtxClient.__new__(HtxClient)
|
|
client.get_contract_info = lambda **_kwargs: {"contract_size": "0.001"}
|
|
|
|
assert client._base_to_contracts(symbol="BTC/USDT", qty=0.0005) == 0
|
|
|
|
|
|
def test_gate_spot_grid_rejects_float_dust_and_floors_native_precision():
|
|
client = GateSpotClient.__new__(GateSpotClient)
|
|
client.get_currency_pair = lambda **_kwargs: {
|
|
"amount_precision": 6,
|
|
"precision": 2,
|
|
"min_base_amount": "0.0001",
|
|
"min_quote_amount": "1",
|
|
}
|
|
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=3.3532799999999997e-07,
|
|
market_type="spot",
|
|
price=100_000,
|
|
) == 0.0
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.0001239,
|
|
market_type="spot",
|
|
price=100_000,
|
|
) == pytest.approx(0.000123)
|
|
|
|
|
|
def test_htx_spot_grid_rejects_float_dust_and_minimum_notional():
|
|
client = HtxClient.__new__(HtxClient)
|
|
client.get_spot_symbol_info = lambda **_kwargs: {
|
|
"amount-precision": 6,
|
|
"price-precision": 2,
|
|
"min-order-amt": "0.0001",
|
|
"min-order-value": "1",
|
|
}
|
|
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=3.3532799999999997e-07,
|
|
market_type="spot",
|
|
price=100_000,
|
|
) == 0.0
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.0001,
|
|
market_type="spot",
|
|
price=5_000,
|
|
) == 0.0
|
|
|
|
|
|
@pytest.mark.parametrize("exchange_id", ["binance", "okx", "bitget", "bybit", "gate", "htx"])
|
|
@pytest.mark.parametrize("market_type", ["spot", "swap"])
|
|
def test_all_grid_exchanges_apply_common_minimum_rules(
|
|
monkeypatch,
|
|
exchange_id,
|
|
market_type,
|
|
):
|
|
rules = InstrumentRules(
|
|
key=f"Crypto:BTC/USDT@{exchange_id}:{market_type}",
|
|
exchange_id=exchange_id,
|
|
market_type=market_type,
|
|
symbol="BTC/USDT",
|
|
amount_step=0.001,
|
|
min_amount=0.01,
|
|
min_notional=5.0,
|
|
)
|
|
|
|
class FakeProvider:
|
|
def get_rules(self, *_args, **_kwargs):
|
|
return rules
|
|
|
|
monkeypatch.setattr(instrument_rules, "get_instrument_rules_provider", lambda: FakeProvider())
|
|
client = BaseRestClient("https://example.invalid")
|
|
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.0099,
|
|
market_type=market_type,
|
|
exchange_config={"exchange_id": exchange_id},
|
|
price=1_000,
|
|
) == 0.0
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.0129,
|
|
market_type=market_type,
|
|
exchange_config={"exchange_id": exchange_id},
|
|
price=100,
|
|
) == 0.0
|
|
assert normalize_grid_order_quantity(
|
|
client,
|
|
symbol="BTC/USDT",
|
|
quantity=0.1239,
|
|
market_type=market_type,
|
|
exchange_config={"exchange_id": exchange_id},
|
|
price=100,
|
|
) == pytest.approx(0.123)
|