"""币安符号解析与中性到期工具测试。""" from app.exchange.binance.parse import parse_option_symbol, rows_to_option_contracts from app.exchange.expiry import expiry_ms_from_ymd, ymd_from_expiry_ms from app.exchange.runtime import normalize_exchange_name def test_binance_parse_option_symbol() -> None: y, stk, side = parse_option_symbol("ETH-250726-1860-C") assert y == "250726" assert stk == 1860.0 assert side == "C" y2, _, side2 = parse_option_symbol("ETH-250726-1860-P") assert y2 == "250726" and side2 == "P" assert parse_option_symbol("ETHUSDT")[0] is None def test_binance_rows_to_contracts() -> None: rows = [ { "symbol": "ETH-250726-1860-C", "status": "TRADING", "strikePrice": "1860", "side": "CALL", "expiryDate": expiry_ms_from_ymd("250726"), "unit": "1", "underlying": "ETHUSDT", }, { "symbol": "ETH-250726-1860-P", "status": "TRADING", "strikePrice": "1860", "side": "PUT", "expiryDate": expiry_ms_from_ymd("250726"), "unit": 1, "underlying": "ETHUSDT", }, ] out = rows_to_option_contracts(rows) assert len(out) == 2 assert out[0]["expiry_ymd"] == "250726" assert out[0]["ct_mult"] == 1.0 assert out[0]["side"] in ("C", "P") def test_expiry_ms_roundtrip() -> None: ms = expiry_ms_from_ymd("250726") assert ymd_from_expiry_ms(ms) == "250726" # UTC 08:00 from datetime import datetime, timezone dt = datetime.fromtimestamp(ms / 1000, tz=timezone.utc) assert dt.hour == 8 and dt.minute == 0 def test_normalize_exchange() -> None: assert normalize_exchange_name("BN") == "binance" assert normalize_exchange_name("okx") == "okx" assert normalize_exchange_name(None) == "okx" def test_binance_maps_okx_family_name() -> None: """误传 OKX family 时不应按 startswith(ETH) 乱匹配,应映射到 ETHUSDT。""" from app.exchange.binance.rest import BinanceRestClient cli = BinanceRestClient.__new__(BinanceRestClient) cli._exchange_info = { "optionSymbols": [ { "symbol": "ETH-260726-1860-C", "underlying": "ETHUSDT", "status": "TRADING", "strikePrice": "1860", "side": "CALL", "expiryDate": 1785052800000, "unit": "1", }, { "symbol": "BTC-260726-100000-C", "underlying": "BTCUSDT", "status": "TRADING", "strikePrice": "100000", "side": "CALL", "expiryDate": 1785052800000, "unit": "1", }, ] } rows = BinanceRestClient.fetch_option_instruments(cli, "ETH-USD_UM") assert len(rows) == 1 assert rows[0]["symbol"] == "ETH-260726-1860-C"