ib: fill out contract tables in `.get_mkt_info()`
Since getting a global symcache result from the API is basically impossible, we ad-hoc fill out the needed client tables on demand per client code queries to the mkt info EP. Also, use `unpack_fqme()` in fqme (search) pattern parser instead of hacky `str.partition()`.account_tests
parent
50b221f788
commit
b33be86b2f
|
@ -37,6 +37,7 @@ import trio
|
||||||
from piker.accounting import (
|
from piker.accounting import (
|
||||||
Asset,
|
Asset,
|
||||||
MktPair,
|
MktPair,
|
||||||
|
unpack_fqme,
|
||||||
)
|
)
|
||||||
from piker._cacheables import (
|
from piker._cacheables import (
|
||||||
async_lifo_cache,
|
async_lifo_cache,
|
||||||
|
@ -49,6 +50,7 @@ from ._util import (
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from .api import (
|
from .api import (
|
||||||
MethodProxy,
|
MethodProxy,
|
||||||
|
Client,
|
||||||
)
|
)
|
||||||
|
|
||||||
_futes_venues = (
|
_futes_venues = (
|
||||||
|
@ -358,24 +360,23 @@ def parse_patt2fqme(
|
||||||
# fqme parsing stage
|
# fqme parsing stage
|
||||||
# ------------------
|
# ------------------
|
||||||
if '.ib' in pattern:
|
if '.ib' in pattern:
|
||||||
from piker.accounting import unpack_fqme
|
|
||||||
_, symbol, venue, expiry = unpack_fqme(pattern)
|
_, symbol, venue, expiry = unpack_fqme(pattern)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
symbol = pattern
|
symbol = pattern
|
||||||
expiry = ''
|
expiry = ''
|
||||||
|
|
||||||
# another hack for forex pairs lul.
|
# # another hack for forex pairs lul.
|
||||||
if (
|
# if (
|
||||||
'.idealpro' in symbol
|
# '.idealpro' in symbol
|
||||||
# or '/' in symbol
|
# # or '/' in symbol
|
||||||
):
|
# ):
|
||||||
exch = 'IDEALPRO'
|
# exch: str = 'IDEALPRO'
|
||||||
symbol = symbol.removesuffix('.idealpro')
|
# symbol = symbol.removesuffix('.idealpro')
|
||||||
if '/' in symbol:
|
# if '/' in symbol:
|
||||||
symbol, currency = symbol.split('/')
|
# symbol, currency = symbol.split('/')
|
||||||
|
|
||||||
else:
|
# else:
|
||||||
# TODO: yes, a cache..
|
# TODO: yes, a cache..
|
||||||
# try:
|
# try:
|
||||||
# # give the cache a go
|
# # give the cache a go
|
||||||
|
@ -387,9 +388,9 @@ def parse_patt2fqme(
|
||||||
symbol, _, expiry = symbol.rpartition('.')
|
symbol, _, expiry = symbol.rpartition('.')
|
||||||
|
|
||||||
# use heuristics to figure out contract "type"
|
# use heuristics to figure out contract "type"
|
||||||
symbol, exch = symbol.upper().rsplit('.', maxsplit=1)
|
symbol, venue = symbol.upper().rsplit('.', maxsplit=1)
|
||||||
|
|
||||||
return symbol, currency, exch, expiry
|
return symbol, currency, venue, expiry
|
||||||
|
|
||||||
|
|
||||||
def con2fqme(
|
def con2fqme(
|
||||||
|
@ -406,9 +407,12 @@ def con2fqme(
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# should be real volume for this contract by default
|
# should be real volume for this contract by default
|
||||||
calc_price = False
|
calc_price: bool = False
|
||||||
if con.conId:
|
if con.conId:
|
||||||
try:
|
try:
|
||||||
|
# TODO: LOL so apparently IB just changes the contract
|
||||||
|
# ID (int) on a whim.. so we probably need to use an
|
||||||
|
# FQME style key after all...
|
||||||
return _cache[con.conId]
|
return _cache[con.conId]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
@ -475,8 +479,9 @@ async def get_mkt_info(
|
||||||
|
|
||||||
) -> tuple[MktPair, ibis.ContractDetails]:
|
) -> tuple[MktPair, ibis.ContractDetails]:
|
||||||
|
|
||||||
# XXX: we don't need to split off any fqme broker part?
|
if '.ib' not in fqme:
|
||||||
# bs_fqme, _, broker = fqme.partition('.')
|
fqme += '.ib'
|
||||||
|
broker, pair, venue, expiry = unpack_fqme(fqme)
|
||||||
|
|
||||||
proxy: MethodProxy
|
proxy: MethodProxy
|
||||||
if proxy is not None:
|
if proxy is not None:
|
||||||
|
@ -492,7 +497,7 @@ async def get_mkt_info(
|
||||||
(
|
(
|
||||||
con, # Contract
|
con, # Contract
|
||||||
details, # ContractDetails
|
details, # ContractDetails
|
||||||
) = await proxy.get_sym_details(symbol=fqme)
|
) = await proxy.get_sym_details(fqme=fqme)
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
log.exception(f'Proxy is ded {proxy._aio_ns}')
|
log.exception(f'Proxy is ded {proxy._aio_ns}')
|
||||||
raise
|
raise
|
||||||
|
@ -558,4 +563,14 @@ async def get_mkt_info(
|
||||||
_fqme_without_src=(atype != 'fiat'),
|
_fqme_without_src=(atype != 'fiat'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# if possible register the bs_mktid to the just-built
|
||||||
|
# mkt so that it can be retreived by order mode tasks later.
|
||||||
|
# TODO NOTE: this is going to be problematic if/when we split
|
||||||
|
# out the datatd vs. brokerd actors since the mktmap lookup
|
||||||
|
# table will now be inaccessible..
|
||||||
|
if proxy is not None:
|
||||||
|
client: Client = proxy._aio_ns
|
||||||
|
client._contracts[mkt.bs_fqme] = con
|
||||||
|
client._cons2mkts[con] = mkt
|
||||||
|
|
||||||
return mkt, details
|
return mkt, details
|
||||||
|
|
Loading…
Reference in New Issue