repo hygiene: track the PINK launcher import closure

67 production .py modules that the running PINK service imports but which
were never committed: prod/bingx/ (HTTP client, market/user streams,
journal, config), prod/clean_arch/ adapters/persistence/runtime/dita/dita_v2
production modules and their co-located tests. Rule going forward: every
module imported by launch_dolphin_pink.py / pink_direct.py must appear in
git ls-files. Excludes _backup dirs, __pycache__, and non-code files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Codex
2026-06-12 15:09:32 +02:00
parent c3a18f693a
commit 84e4a50e3f
67 changed files with 15090 additions and 0 deletions

View File

@@ -0,0 +1,80 @@
from __future__ import annotations
from decimal import Decimal
from nautilus_trader.common.providers import InstrumentProvider
from nautilus_trader.model.identifiers import InstrumentId
from nautilus_trader.model.identifiers import Symbol
from nautilus_trader.model.instruments import CryptoPerpetual
from nautilus_trader.model.objects import Currency
from nautilus_trader.model.objects import Money
from nautilus_trader.model.objects import Price
from nautilus_trader.model.objects import Quantity
from .config import BingxInstrumentProviderConfig
from .enums import BINGX_VENUE
from .http import BingxHttpClient
from .schemas import BingxContract
class BingxInstrumentProvider(InstrumentProvider):
def __init__(
self,
client: BingxHttpClient,
config: BingxInstrumentProviderConfig | None = None,
) -> None:
super().__init__(config=config)
self._client = client
self._cfg = config or BingxInstrumentProviderConfig()
async def load_all_async(self, filters: dict | None = None) -> None:
raw_contracts = await self._client.public_get("/openApi/swap/v2/quote/contracts")
contracts = raw_contracts if isinstance(raw_contracts, list) else raw_contracts.get("contracts", [])
requested = set(self._cfg.symbol_filters or ())
for row in contracts:
contract = BingxContract.from_http(row)
if requested and contract.symbol not in requested and contract.venue_symbol not in requested:
continue
self.add(self._parse_contract(contract))
async def load_ids_async(
self,
instrument_ids: list[InstrumentId],
filters: dict | None = None,
) -> None:
self._cfg = BingxInstrumentProviderConfig(
load_all=True,
symbol_filters=tuple(i.symbol.value for i in instrument_ids),
default_maker_fee=self._cfg.default_maker_fee,
default_taker_fee=self._cfg.default_taker_fee,
)
await self.load_all_async(filters)
def _parse_contract(self, contract: BingxContract) -> CryptoPerpetual:
base_currency = Currency.from_str(contract.base_asset)
quote_currency = Currency.from_str(contract.quote_asset)
symbol = Symbol(contract.symbol)
return CryptoPerpetual(
instrument_id=InstrumentId(symbol=symbol, venue=BINGX_VENUE),
raw_symbol=Symbol(contract.venue_symbol),
base_currency=base_currency,
quote_currency=quote_currency,
settlement_currency=quote_currency,
is_inverse=False,
price_precision=contract.price_precision,
price_increment=Price.from_str(str(contract.tick_size)),
size_precision=contract.quantity_precision,
size_increment=Quantity.from_str(str(contract.step_size)),
max_quantity=Quantity.from_str("1000000000"),
min_quantity=Quantity.from_str(str(contract.min_quantity)),
max_notional=None,
min_notional=Money(contract.min_notional, quote_currency),
max_price=Price.from_str("1000000000"),
min_price=Price.from_str(str(contract.tick_size)),
margin_init=Decimal("0.11111111") if contract.max_leverage >= 9 else Decimal("1") / Decimal(contract.max_leverage or 1),
margin_maint=Decimal("0.05"),
maker_fee=contract.maker_fee or self._cfg.default_maker_fee,
taker_fee=contract.taker_fee or self._cfg.default_taker_fee,
ts_event=0,
ts_init=0,
)