72 lines
2.6 KiB
Python
72 lines
2.6 KiB
Python
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
from decimal import Decimal
|
||
|
|
|
||
|
|
from nautilus_trader.config import InstrumentProviderConfig
|
||
|
|
from nautilus_trader.config import LiveExecClientConfig
|
||
|
|
from nautilus_trader.config import PositiveInt
|
||
|
|
|
||
|
|
from .enums import BINGX_VENUE
|
||
|
|
from .enums import BingxEnvironment
|
||
|
|
|
||
|
|
|
||
|
|
def require_mainnet_opt_in(environment: BingxEnvironment, allow_mainnet: bool, *, context: str) -> None:
|
||
|
|
"""
|
||
|
|
Fail closed unless the caller explicitly opts into BingX LIVE mainnet.
|
||
|
|
"""
|
||
|
|
if environment is BingxEnvironment.LIVE and not allow_mainnet:
|
||
|
|
raise ValueError(f"{context} LIVE requires allow_mainnet=True")
|
||
|
|
|
||
|
|
|
||
|
|
class BingxInstrumentProviderConfig(InstrumentProviderConfig, frozen=True):
|
||
|
|
"""
|
||
|
|
Configuration for the BingX perpetual futures instrument provider.
|
||
|
|
"""
|
||
|
|
|
||
|
|
symbol_filters: tuple[str, ...] | None = None
|
||
|
|
default_maker_fee: Decimal = Decimal("0.0002")
|
||
|
|
default_taker_fee: Decimal = Decimal("0.0005")
|
||
|
|
|
||
|
|
|
||
|
|
class BingxExecClientConfig(LiveExecClientConfig, frozen=True):
|
||
|
|
"""
|
||
|
|
Configuration for the BingX live execution client.
|
||
|
|
"""
|
||
|
|
|
||
|
|
venue = BINGX_VENUE
|
||
|
|
api_key: str | None = None
|
||
|
|
secret_key: str | None = None
|
||
|
|
environment: BingxEnvironment = BingxEnvironment.VST
|
||
|
|
allow_mainnet: bool = False
|
||
|
|
base_url_http: str | None = None
|
||
|
|
base_url_http_backup: str | None = None
|
||
|
|
base_url_ws_private: str | None = None
|
||
|
|
http_timeout_secs: PositiveInt = 10
|
||
|
|
recv_window_ms: PositiveInt = 5_000
|
||
|
|
max_retries: PositiveInt = 3
|
||
|
|
retry_delay_initial_ms: PositiveInt = 250
|
||
|
|
retry_delay_max_ms: PositiveInt = 2_000
|
||
|
|
instrument_provider: BingxInstrumentProviderConfig = BingxInstrumentProviderConfig(load_all=True)
|
||
|
|
use_gtd: bool = False
|
||
|
|
use_reduce_only: bool = True
|
||
|
|
use_position_ids: bool = False
|
||
|
|
prefer_websocket: bool = True
|
||
|
|
ws_listenkey_keepalive_interval_secs: PositiveInt = 1_800
|
||
|
|
ws_event_stale_after_ms: PositiveInt = 15_000
|
||
|
|
ws_reconnect_initial_ms: PositiveInt = 500
|
||
|
|
ws_reconnect_max_ms: PositiveInt = 10_000
|
||
|
|
poll_open_orders_interval_ms: PositiveInt = 500
|
||
|
|
poll_account_interval_ms: PositiveInt = 2_000
|
||
|
|
poll_positions_interval_ms: PositiveInt = 2_000
|
||
|
|
default_leverage: PositiveInt = 1
|
||
|
|
exchange_leverage_cap: PositiveInt = 3
|
||
|
|
sizing_mode: str = "engine"
|
||
|
|
leverage_by_symbol: dict[str, PositiveInt] | None = None
|
||
|
|
margin_type_by_symbol: dict[str, str] | None = None
|
||
|
|
enforce_integer_leverage: bool = True
|
||
|
|
journal_strategy: str | None = None
|
||
|
|
journal_db: str | None = None
|
||
|
|
|
||
|
|
def validate_mainnet_opt_in(self) -> None:
|
||
|
|
require_mainnet_opt_in(self.environment, self.allow_mainnet, context="BingX execution client")
|