Handle ambiguous futes contracts in `get_fute()`
Use (the only available in `ib_async`) `returnAll=True` in `qualifyContractsAsync()` calls within `get_fute()` and handle the case where IB returns a list of ambiguous contract matches instead of a single result. Deats, - add `returnAll=True` to both `ContFuture` and `Future` qualification calls. - add `isinstance(con, list)` check after unpacking first result to detect ambiguous contract sets. - log warning with input params and matched contracts when ambiguous. - update return type annot to `Contract|list[Contract]`. Also, - handle list-of-contracts case in `find_contracts()` by unpacking `*contracts` into the `qualifyContractsAsync()` call. - reformat `qualifyContractsAsync()` calls to multiline style. (this commit msg was generated in some part by [`claude-code`][claude-code-gh]) [claude-code-gh]: https://github.com/anthropics/claude-codeib_async_CONT
parent
6fa805b0a4
commit
433db3a140
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue