From e9887cb6110cd59aed6964c38244be3c50a6a033 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Fri, 22 Sep 2023 14:48:50 -0400 Subject: [PATCH] binance: parse .expiry separate from .venue Apparently they're being massive cucks and changing their futes pair schema again now adding a `NEXT_QUARTER` contract type which we weren't handling at all. The good news is falling back to an old symcache file would have prevented this from crashing. Add a new `FutesPair.expiry: str` field so that `.bs_fqme` can simply call it during the summary FQME-ification output rendering.. --- piker/brokers/binance/venues.py | 59 ++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/piker/brokers/binance/venues.py b/piker/brokers/binance/venues.py index dc3312be..a82c3324 100644 --- a/piker/brokers/binance/venues.py +++ b/piker/brokers/binance/venues.py @@ -194,6 +194,37 @@ class FutesPair(Pair): def quoteAssetPrecision(self) -> int: return self.quotePrecision + @property + def expiry(self) -> str: + symbol: str = self.symbol + contype: str = self.contractType + match contype: + case ( + 'CURRENT_QUARTER' + | 'NEXT_QUARTER' # su madre binance.. + ): + pair, _, expiry = symbol.partition('_') + assert pair == self.pair # sanity + return f'{expiry}' + + case 'PERPETUAL': + return 'PERP' + + case '': + subtype: list[str] = self.underlyingSubType + if not subtype: + if self.status == 'PENDING_TRADING': + return 'PENDING' + + match subtype: + case ['DEFI']: + return 'PERP' + + # XXX: yeah no clue then.. + raise ValueError( + f'Bad .expiry token match: {contype} for {symbol}' + ) + @property def venue(self) -> str: symbol: str = self.symbol @@ -202,36 +233,46 @@ class FutesPair(Pair): match ctype: case 'PERPETUAL': - return f'{margin}M.PERP' + return f'{margin}M' - case 'CURRENT_QUARTER': + case ( + 'CURRENT_QUARTER' + | 'NEXT_QUARTER' # su madre binance.. + ): _, _, expiry = symbol.partition('_') - return f'{margin}M.{expiry}' + return f'{margin}M' case '': subtype: list[str] = self.underlyingSubType if not subtype: if self.status == 'PENDING_TRADING': - return f'{margin}M.PENDING' + return f'{margin}M' match subtype: case ['DEFI']: - return f'{subtype[0]}.PERP' + return f'{subtype[0]}' # XXX: yeah no clue then.. - return 'WTF.PWNED.BBQ' + raise ValueError( + f'Bad .venue token match: {ctype}' + ) @property def bs_fqme(self) -> str: symbol: str = self.symbol ctype: str = self.contractType venue: str = self.venue + pair: str = self.pair match ctype: - case 'CURRENT_QUARTER': - symbol, _, expiry = symbol.partition('_') + case ( + 'CURRENT_QUARTER' + | 'NEXT_QUARTER' # su madre binance.. + ): + pair, _, expiry = symbol.partition('_') + assert pair == self.pair - return f'{symbol}.{venue}' + return f'{pair}.{venue}.{self.expiry}' @property def bs_src_asset(self) -> str: