"""期权合约 ID 工具:从持仓合约还原同到期同行权价的 Call/Put 对。""" from __future__ import annotations from .expiry import expiry_ms_from_ymd from .types import OptionPair def flip_option_side(inst_id: str) -> str | None: """ETH-...-1880-P ↔ ...-C;币安 ETH-YYMMDD-STRIKE-P ↔ -C。""" s = (inst_id or "").strip() if not s: return None if s.endswith("-C"): return s[:-1] + "P" if s.endswith("-P"): return s[:-1] + "C" if s.endswith("-c"): return s[:-1] + "p" if s.endswith("-p"): return s[:-1] + "c" return None def pair_from_option_inst(inst_id: str) -> OptionPair | None: """由任一腿合约 ID 还原同 strike/expiry 的 OptionPair。""" from .okx.parse import parse_option_inst_id from .binance.parse import parse_option_symbol s = (inst_id or "").strip() if not s: return None ymd, strike, side = parse_option_inst_id(s) if ymd is None: ymd, strike, side = parse_option_symbol(s) if ymd is None or strike is None or side not in ("C", "P"): return None other = flip_option_side(s) if not other: return None call_id = s if side == "C" else other put_id = s if side == "P" else other try: ems = expiry_ms_from_ymd(ymd) except ValueError: return None return OptionPair( expiry_ymd=ymd, expiry_ms=int(ems), strike=float(strike), call_inst_id=call_id, put_inst_id=put_id, )