Compare commits

..

No commits in common. "137aee510b09d123da515408c48d5037aa233207" and "2c45f90c5d755a2242b4c6e00e6f48e10398b82d" have entirely different histories.

3 changed files with 27 additions and 78 deletions

View File

@ -768,48 +768,26 @@ class Client:
expiry: str = '', expiry: str = '',
front: bool = False, front: bool = False,
) -> Contract|list[Contract]: ) -> 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:
cons = ( con = (await self.ib.qualifyContractsAsync(
await self.ib.qualifyContractsAsync( ContFuture(symbol, exchange=exchange)
ContFuture(symbol, exchange=exchange), ))[0]
returnAll=True,
)
)
else: else:
cons = ( cons = (await self.ib.qualifyContractsAsync(
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
@ -934,17 +912,11 @@ class Client:
) )
exch = 'SMART' if not exch else exch exch = 'SMART' if not exch else exch
if isinstance(con, list): contracts: list[Contract] = [con]
contracts: list[Contract] = con
else:
contracts: list[Contract] = [con]
if qualify: if qualify:
try: try:
contracts: list[Contract] = ( contracts: list[Contract] = (
await self.ib.qualifyContractsAsync( await self.ib.qualifyContractsAsync(con)
*contracts
)
) )
except RequestError as err: except RequestError as err:
msg = err.message msg = err.message

View File

@ -201,15 +201,6 @@ async def open_history_client(
fqme, fqme,
timeframe, timeframe,
end_dt=end_dt, end_dt=end_dt,
# XXX WARNING, we don't actually use this inside
# `Client.bars()` since it isn't really supported,
# the API instead supports a "duration" of time style
# from the `end_dt` (or at least that was the best
# way to get it working sanely)..
#
# SO, with that in mind be aware that any downstream
# logic based on this may be mostly futile Xp
start_dt=start_dt, start_dt=start_dt,
) )
latency = time.time() - query_start latency = time.time() - query_start
@ -287,27 +278,19 @@ async def open_history_client(
trimmed_bars = bars_array[ trimmed_bars = bars_array[
bars_array['time'] >= start_dt.timestamp() bars_array['time'] >= start_dt.timestamp()
] ]
# XXX, should NEVER get HERE! if (
if trimmed_bars.size: trimmed_first_dt := from_timestamp(trimmed_bars['time'][0])
trimmed_first_dt: datetime = from_timestamp(trimmed_bars['time'][0]) !=
if ( start_dt
trimmed_first_dt ):
>= # TODO! rm this once we're more confident it never hits!
start_dt # breakpoint()
): raise RuntimeError(
msg: str = ( f'OHLC-bars array start is gt `start_dt` limit !!\n'
f'OHLC-bars array start is gt `start_dt` limit !!\n' f'start_dt: {start_dt}\n'
f'start_dt: {start_dt}\n' f'first_dt: {first_dt}\n'
f'first_dt: {first_dt}\n' f'trimmed_first_dt: {trimmed_first_dt}\n'
f'trimmed_first_dt: {trimmed_first_dt}\n' )
f'\n'
f'Delivering shorted frame of {trimmed_bars.size!r}\n'
)
log.warning(msg)
# TODO! rm this once we're more confident it
# never breaks anything (in the caller)!
# breakpoint()
# raise RuntimeError(msg)
# XXX, overwrite with start_dt-limited frame # XXX, overwrite with start_dt-limited frame
bars_array = trimmed_bars bars_array = trimmed_bars

View File

@ -43,7 +43,6 @@ from pendulum import (
if TYPE_CHECKING: if TYPE_CHECKING:
from ib_async import ( from ib_async import (
TradingSession, TradingSession,
Contract,
ContractDetails, ContractDetails,
) )
from exchange_calendars.exchange_calendars import ( from exchange_calendars.exchange_calendars import (
@ -83,12 +82,7 @@ def has_holiday(
''' '''
tz: str = con_deats.timeZoneId tz: str = con_deats.timeZoneId
con: Contract = con_deats.contract exch: str = con_deats.contract.primaryExchange
exch: str = (
con.primaryExchange
or
con.exchange
)
# XXX, ad-hoc handle any IB exchange which are non-std # XXX, ad-hoc handle any IB exchange which are non-std
# via lookup table.. # via lookup table..