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 = '',
|
expiry: str = '',
|
||||||
front: bool = False,
|
front: bool = False,
|
||||||
|
|
||||||
) -> Contract:
|
) -> Contract|list[Contract]:
|
||||||
'''
|
'''
|
||||||
Get an unqualifed contract for the current "continous"
|
Get an unqualifed contract for the current "continous"
|
||||||
future.
|
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
|
# it's the "front" contract returned here
|
||||||
if front:
|
if front:
|
||||||
con = (await self.ib.qualifyContractsAsync(
|
cons = (
|
||||||
ContFuture(symbol, exchange=exchange)
|
await self.ib.qualifyContractsAsync(
|
||||||
))[0]
|
ContFuture(symbol, exchange=exchange),
|
||||||
|
returnAll=True,
|
||||||
|
)
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
cons = (await self.ib.qualifyContractsAsync(
|
cons = (
|
||||||
|
await self.ib.qualifyContractsAsync(
|
||||||
Future(
|
Future(
|
||||||
symbol,
|
symbol,
|
||||||
exchange=exchange,
|
exchange=exchange,
|
||||||
lastTradeDateOrContractMonth=expiry,
|
lastTradeDateOrContractMonth=expiry,
|
||||||
|
),
|
||||||
|
returnAll=True,
|
||||||
)
|
)
|
||||||
))
|
)
|
||||||
|
|
||||||
con = cons[0]
|
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
|
return con
|
||||||
|
|
||||||
|
|
@ -912,11 +934,17 @@ class Client:
|
||||||
)
|
)
|
||||||
exch = 'SMART' if not exch else exch
|
exch = 'SMART' if not exch else exch
|
||||||
|
|
||||||
|
if isinstance(con, list):
|
||||||
|
contracts: list[Contract] = con
|
||||||
|
else:
|
||||||
contracts: list[Contract] = [con]
|
contracts: list[Contract] = [con]
|
||||||
|
|
||||||
if qualify:
|
if qualify:
|
||||||
try:
|
try:
|
||||||
contracts: list[Contract] = (
|
contracts: list[Contract] = (
|
||||||
await self.ib.qualifyContractsAsync(con)
|
await self.ib.qualifyContractsAsync(
|
||||||
|
*contracts
|
||||||
|
)
|
||||||
)
|
)
|
||||||
except RequestError as err:
|
except RequestError as err:
|
||||||
msg = err.message
|
msg = err.message
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue