ib: add back `src/dst` parsing for fiat pairs

account_tests
Tyler Goodlet 2023-08-03 16:56:33 -04:00
parent ae444d1bc7
commit e9dfd28aac
2 changed files with 50 additions and 15 deletions

View File

@ -650,12 +650,14 @@ class Client:
exch in {'IDEALPRO'} exch in {'IDEALPRO'}
or sectype == 'CASH' or sectype == 'CASH'
): ):
# if '/' in symbol: pair: str = symbol
# currency = '' if '/' in symbol:
# symbol, currency = symbol.split('/') src, dst = symbol.split('/')
pair: str = ''.join([src, dst])
con = Forex( con = Forex(
pair=''.join((symbol, currency)), pair=pair,
currency=currency, currency='',
) )
con.bars_kwargs = {'whatToShow': 'MIDPOINT'} con.bars_kwargs = {'whatToShow': 'MIDPOINT'}

View File

@ -30,6 +30,7 @@ import time
from typing import ( from typing import (
Any, Any,
Callable, Callable,
TYPE_CHECKING,
) )
from async_generator import aclosing from async_generator import aclosing
@ -65,6 +66,9 @@ from .api import (
from ._util import data_reset_hack from ._util import data_reset_hack
from .symbols import get_mkt_info from .symbols import get_mkt_info
if TYPE_CHECKING:
from trio._core._run import Task
# XXX NOTE: See available types table docs: # XXX NOTE: See available types table docs:
# https://interactivebrokers.github.io/tws-api/tick_types.html # https://interactivebrokers.github.io/tws-api/tick_types.html
@ -308,7 +312,7 @@ async def wait_on_data_reset(
return False return False
_data_resetter_task: trio.Task | None = None _data_resetter_task: Task | None = None
_failed_resets: int = 0 _failed_resets: int = 0
@ -334,7 +338,15 @@ async def get_bars(
task_status: TaskStatus[trio.CancelScope] = trio.TASK_STATUS_IGNORED, task_status: TaskStatus[trio.CancelScope] = trio.TASK_STATUS_IGNORED,
) -> (dict, np.ndarray): ) -> tuple[
tuple[ # result tuple
ibis.objects.BarDataList,
np.ndarray,
datetime,
datetime,
] | None,
bool, # timed out hint
]:
''' '''
Retrieve historical data from a ``trio``-side task using Retrieve historical data from a ``trio``-side task using
a ``MethoProxy``. a ``MethoProxy``.
@ -420,7 +432,12 @@ async def get_bars(
if data_cs: if data_cs:
data_cs.cancel() data_cs.cancel()
result = (bars, bars_array, first_dt, last_dt) result = (
bars, # ib native
bars_array, # numpy
first_dt,
last_dt,
)
# signal data reset loop parent task # signal data reset loop parent task
result_ready.set() result_ready.set()
@ -428,7 +445,7 @@ async def get_bars(
return result return result
except RequestError as err: except RequestError as err:
msg = err.message msg: str = err.message
if 'No market data permissions for' in msg: if 'No market data permissions for' in msg:
# TODO: signalling for no permissions searches # TODO: signalling for no permissions searches
@ -466,21 +483,29 @@ async def get_bars(
nodatas_count += 1 nodatas_count += 1
continue continue
elif 'API historical data query cancelled' in err.message: elif (
'API historical data query cancelled'
in
err.message
):
log.warning( log.warning(
'Query cancelled by IB (:eyeroll:):\n' 'Query cancelled by IB (:eyeroll:):\n'
f'{err.message}' f'{err.message}'
) )
continue continue
elif ( elif (
'Trading TWS session is connected from a different IP' 'Trading TWS session is connected from a different IP'
in err.message in
err.message
): ):
log.warning("ignoring ip address warning") log.warning("ignoring ip address warning")
continue continue
# XXX: more or less same as above timeout case # XXX: more or less same as above timeout case
elif _pacing in msg: elif (
_pacing in msg
):
log.warning( log.warning(
'History throttle rate reached!\n' 'History throttle rate reached!\n'
'Resetting farms with `ctrl-alt-f` hack\n' 'Resetting farms with `ctrl-alt-f` hack\n'
@ -532,9 +557,10 @@ async def get_bars(
# don't double invoke the reset hack if another # don't double invoke the reset hack if another
# requester task already has it covered. # requester task already has it covered.
continue continue
else: else:
_data_resetter_task = trio.lowlevel.current_task() _data_resetter_task = trio.lowlevel.current_task()
unset_resetter = True unset_resetter: bool = True
# spawn new data reset task # spawn new data reset task
data_cs, reset_done = await nurse.start( data_cs, reset_done = await nurse.start(
@ -547,9 +573,16 @@ async def get_bars(
# sync wait on reset to complete # sync wait on reset to complete
await reset_done.wait() await reset_done.wait()
_data_resetter_task = None if unset_resetter else _data_resetter_task _data_resetter_task = (
None
if unset_resetter
else _data_resetter_task
)
assert result assert result
return result, data_cs is not None return (
result,
data_cs is not None,
)
_quote_streams: dict[str, trio.abc.ReceiveStream] = {} _quote_streams: dict[str, trio.abc.ReceiveStream] = {}