From 14f124164a715179e6aea8c0bb8cfd7fc2db77e4 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Thu, 21 Sep 2023 19:14:44 -0400 Subject: [PATCH] ib: fix mktpair fallback table: use `Client._con2mkts` to translate.. Previously we were assuming that the `Client._contracts: dict[str, Contract]` would suffice this directly, which obviously isn't true XD Also, - add the `NSE` venue to skip list. - use new `rapidfuzz.process.extract()` lib API. - only get con deats for non null exchange names.. --- piker/brokers/ib/api.py | 13 +++++++++---- piker/brokers/ib/broker.py | 14 +++++++++++++- piker/brokers/ib/symbols.py | 13 +++++++------ 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/piker/brokers/ib/api.py b/piker/brokers/ib/api.py index 63c38bc8..cc0ad051 100644 --- a/piker/brokers/ib/api.py +++ b/piker/brokers/ib/api.py @@ -416,20 +416,26 @@ class Client: futs: list[asyncio.Future] = [] for con in contracts: - if con.primaryExchange not in _exch_skip_list: + exch: str = con.primaryExchange or con.exchange + if ( + exch + and exch not in _exch_skip_list + ): futs.append(self.ib.reqContractDetailsAsync(con)) # batch request all details try: results: list[ContractDetails] = await asyncio.gather(*futs) except RequestError as err: - msg = err.message + msg: str = err.message if ( 'No security definition' in msg ): log.warning(f'{msg}: {contracts}') return {} + raise + # one set per future result details: dict[str, ContractDetails] = {} for details_set in results: @@ -1356,8 +1362,7 @@ async def open_aio_client_method_relay( # relay all method requests to ``asyncio``-side client and deliver # back results while not to_trio._closed: - msg = await from_trio.get() - + msg: tuple[str, dict] | dict | None = await from_trio.get() match msg: case None: # termination sentinel print('asyncio PROXY-RELAY SHUTDOWN') diff --git a/piker/brokers/ib/broker.py b/piker/brokers/ib/broker.py index 9b256f24..1b144e3c 100644 --- a/piker/brokers/ib/broker.py +++ b/piker/brokers/ib/broker.py @@ -846,6 +846,18 @@ async def emit_pp_update( # con: Contract = fill.contract + # provide a backup fqme -> MktPair table in case the + # symcache does not (yet) have an entry for the current mkt + # txn. + backup_table: dict[str, MktPair] = {} + for tid, txn in trans.items(): + fqme: str = txn.fqme + if fqme not in ledger.symcache.mktmaps: + # bs_mktid: str = txn.bs_mktid + backup_table[fqme] = client._cons2mkts[ + client._contracts[fqme] + ] + acnt.update_from_ledger( trans, @@ -855,7 +867,7 @@ async def emit_pp_update( # TODO: remove this hack by attempting to symcache an # incrementally updated table? - _mktmap_table=client._contracts + _mktmap_table=backup_table, ) # re-compute all positions that have changed state. diff --git a/piker/brokers/ib/symbols.py b/piker/brokers/ib/symbols.py index e792113e..99b3a801 100644 --- a/piker/brokers/ib/symbols.py +++ b/piker/brokers/ib/symbols.py @@ -165,6 +165,7 @@ _exch_skip_list = { 'MEXI', # mexican stocks # no idea + 'NSE', 'VALUE', 'FUNDSERV', 'SWB2', @@ -269,7 +270,7 @@ async def open_symbol_search(ctx: tractor.Context) -> None: stock_results.extend(results) - for i in range(10): + for _ in range(10): with trio.move_on_after(3) as cs: async with trio.open_nursery() as sn: sn.start_soon( @@ -292,7 +293,7 @@ async def open_symbol_search(ctx: tractor.Context) -> None: break # # match against our ad-hoc set immediately - # adhoc_matches = fuzzy.extractBests( + # adhoc_matches = fuzzy.extract( # pattern, # list(_adhoc_futes_set), # score_cutoff=90, @@ -305,7 +306,7 @@ async def open_symbol_search(ctx: tractor.Context) -> None: # adhoc_matches} log.debug(f'fuzzy matching stocks {stock_results}') - stock_matches = fuzzy.extractBests( + stock_matches = fuzzy.extract( pattern, stock_results, score_cutoff=50, @@ -423,9 +424,9 @@ def con2fqme( except KeyError: pass - suffix = con.primaryExchange or con.exchange - symbol = con.symbol - expiry = con.lastTradeDateOrContractMonth or '' + suffix: str = con.primaryExchange or con.exchange + symbol: str = con.symbol + expiry: str = con.lastTradeDateOrContractMonth or '' match con: case ibis.Option():