diff --git a/piker/brokers/ib/api.py b/piker/brokers/ib/api.py index b359ab06..b467ee0e 100644 --- a/piker/brokers/ib/api.py +++ b/piker/brokers/ib/api.py @@ -768,26 +768,48 @@ class Client: expiry: str = '', front: bool = False, - ) -> Contract: + ) -> Contract|list[Contract]: ''' Get an unqualifed contract for the current "continous" future. + When input params result in a so called "ambiguous contract" + situation, we return the list of all matches provided by, + + `IB.qualifyContractsAsync(..., returnAll=True)` + ''' # it's the "front" contract returned here if front: - con = (await self.ib.qualifyContractsAsync( - ContFuture(symbol, exchange=exchange) - ))[0] - else: - cons = (await self.ib.qualifyContractsAsync( - Future( - symbol, - exchange=exchange, - lastTradeDateOrContractMonth=expiry, + cons = ( + await self.ib.qualifyContractsAsync( + ContFuture(symbol, exchange=exchange), + returnAll=True, ) - )) - con = cons[0] + ) + else: + cons = ( + await self.ib.qualifyContractsAsync( + Future( + symbol, + exchange=exchange, + lastTradeDateOrContractMonth=expiry, + ), + returnAll=True, + ) + ) + + con = cons[0] + if isinstance(con, list): + log.warning( + f'{len(con)!r} futes cons matched for input params,\n' + f'symbol={symbol!r}\n' + f'exchange={exchange!r}\n' + f'expiry={expiry!r}\n' + f'\n' + f'cons:\n' + f'{con!r}\n' + ) return con @@ -912,11 +934,17 @@ class Client: ) exch = 'SMART' if not exch else exch - contracts: list[Contract] = [con] + if isinstance(con, list): + contracts: list[Contract] = con + else: + contracts: list[Contract] = [con] + if qualify: try: contracts: list[Contract] = ( - await self.ib.qualifyContractsAsync(con) + await self.ib.qualifyContractsAsync( + *contracts + ) ) except RequestError as err: msg = err.message