`ib`: parse and load info for new `Transaction.sym: Symbol` field
parent
3a4794e9d1
commit
69b85aa7e5
|
@ -70,7 +70,10 @@ from piker.clearing._messages import (
|
||||||
BrokerdFill,
|
BrokerdFill,
|
||||||
BrokerdError,
|
BrokerdError,
|
||||||
)
|
)
|
||||||
from piker.data._source import Symbol
|
from piker.data._source import (
|
||||||
|
Symbol,
|
||||||
|
float_digits,
|
||||||
|
)
|
||||||
from .api import (
|
from .api import (
|
||||||
_accounts2clients,
|
_accounts2clients,
|
||||||
con2fqsn,
|
con2fqsn,
|
||||||
|
@ -304,6 +307,9 @@ async def update_ledger_from_api_trades(
|
||||||
|
|
||||||
entry['listingExchange'] = pexch
|
entry['listingExchange'] = pexch
|
||||||
|
|
||||||
|
# pack in the ``Contract.secType``
|
||||||
|
entry['asset_type'] = condict['secType']
|
||||||
|
|
||||||
conf = get_config()
|
conf = get_config()
|
||||||
entries = api_trades_to_ledger_entries(
|
entries = api_trades_to_ledger_entries(
|
||||||
conf['accounts'].inverse,
|
conf['accounts'].inverse,
|
||||||
|
@ -616,9 +622,10 @@ async def trades_dialogue(
|
||||||
# from the api trades it seems we get a key
|
# from the api trades it seems we get a key
|
||||||
# error from ``update[bsuid]`` ?
|
# error from ``update[bsuid]`` ?
|
||||||
pp = table.pps[bsuid]
|
pp = table.pps[bsuid]
|
||||||
|
pairinfo = pp.symbol
|
||||||
if msg.size != pp.size:
|
if msg.size != pp.size:
|
||||||
log.error(
|
log.error(
|
||||||
f'Position mismatch {pp.symbol.front_fqsn()}:\n'
|
f'Pos size mismatch {pairinfo.front_fqsn()}:\n'
|
||||||
f'ib: {msg.size}\n'
|
f'ib: {msg.size}\n'
|
||||||
f'piker: {pp.size}\n'
|
f'piker: {pp.size}\n'
|
||||||
)
|
)
|
||||||
|
@ -1095,13 +1102,15 @@ def norm_trade_records(
|
||||||
|
|
||||||
'''
|
'''
|
||||||
records: list[Transaction] = []
|
records: list[Transaction] = []
|
||||||
for tid, record in ledger.items():
|
|
||||||
|
|
||||||
|
for tid, record in ledger.items():
|
||||||
conid = record.get('conId') or record['conid']
|
conid = record.get('conId') or record['conid']
|
||||||
comms = record.get('commission')
|
comms = record.get('commission')
|
||||||
if comms is None:
|
if comms is None:
|
||||||
comms = -1*record['ibCommission']
|
comms = -1*record['ibCommission']
|
||||||
|
|
||||||
price = record.get('price') or record['tradePrice']
|
price = record.get('price') or record['tradePrice']
|
||||||
|
price_tick_digits = float_digits(price)
|
||||||
|
|
||||||
# the api doesn't do the -/+ on the quantity for you but flex
|
# the api doesn't do the -/+ on the quantity for you but flex
|
||||||
# records do.. are you fucking serious ib...!?
|
# records do.. are you fucking serious ib...!?
|
||||||
|
@ -1144,9 +1153,14 @@ def norm_trade_records(
|
||||||
|
|
||||||
# special handling of symbol extraction from
|
# special handling of symbol extraction from
|
||||||
# flex records using some ad-hoc schema parsing.
|
# flex records using some ad-hoc schema parsing.
|
||||||
instr = record.get('assetCategory')
|
asset_type: str = record.get('assetCategory') or record['secType']
|
||||||
if instr == 'FUT':
|
|
||||||
symbol = record['description'][:3]
|
# TODO: XXX: WOA this is kinda hacky.. probably
|
||||||
|
# should figure out the correct future pair key more
|
||||||
|
# explicitly and consistently?
|
||||||
|
if asset_type == 'FUT':
|
||||||
|
# (flex) ledger entries don't have any simple 3-char key?
|
||||||
|
symbol = record['symbol'][:3]
|
||||||
|
|
||||||
# try to build out piker fqsn from record.
|
# try to build out piker fqsn from record.
|
||||||
expiry = record.get(
|
expiry = record.get(
|
||||||
|
@ -1156,10 +1170,34 @@ def norm_trade_records(
|
||||||
suffix = f'{exch}.{expiry}'
|
suffix = f'{exch}.{expiry}'
|
||||||
expiry = pendulum.parse(expiry)
|
expiry = pendulum.parse(expiry)
|
||||||
|
|
||||||
fqsn = Symbol.from_fqsn(
|
src: str = record['currency']
|
||||||
|
|
||||||
|
pair = Symbol.from_fqsn(
|
||||||
fqsn=f'{symbol}.{suffix}.ib',
|
fqsn=f'{symbol}.{suffix}.ib',
|
||||||
info={},
|
info={
|
||||||
).front_fqsn().rstrip('.ib')
|
'tick_size_digits': price_tick_digits,
|
||||||
|
|
||||||
|
# NOTE: for "legacy" assets, volume is normally discreet, not
|
||||||
|
# a float, but we keep a digit in case the suitz decide
|
||||||
|
# to get crazy and change it; we'll be kinda ready
|
||||||
|
# schema-wise..
|
||||||
|
'lot_size_digits': 1,
|
||||||
|
|
||||||
|
# TODO: remove when we switching from
|
||||||
|
# ``Symbol`` -> ``MktPair``
|
||||||
|
'asset_type': asset_type,
|
||||||
|
|
||||||
|
# TODO: figure out a target fin-type name
|
||||||
|
# set and normalize to that here!
|
||||||
|
'dst_type': asset_type.lower(),
|
||||||
|
|
||||||
|
# starting to use new key naming as in ``MktPair``
|
||||||
|
# type have drafted...
|
||||||
|
'src': src,
|
||||||
|
'src_type': 'fiat',
|
||||||
|
},
|
||||||
|
)
|
||||||
|
fqsn = pair.front_fqsn().rstrip('.ib')
|
||||||
|
|
||||||
# NOTE: for flex records the normal fields for defining an fqsn
|
# NOTE: for flex records the normal fields for defining an fqsn
|
||||||
# sometimes won't be available so we rely on two approaches for
|
# sometimes won't be available so we rely on two approaches for
|
||||||
|
@ -1175,6 +1213,7 @@ def norm_trade_records(
|
||||||
records,
|
records,
|
||||||
Transaction(
|
Transaction(
|
||||||
fqsn=fqsn,
|
fqsn=fqsn,
|
||||||
|
sym=pair,
|
||||||
tid=tid,
|
tid=tid,
|
||||||
size=size,
|
size=size,
|
||||||
price=price,
|
price=price,
|
||||||
|
@ -1201,7 +1240,11 @@ def parse_flex_dt(
|
||||||
|
|
||||||
def api_trades_to_ledger_entries(
|
def api_trades_to_ledger_entries(
|
||||||
accounts: bidict,
|
accounts: bidict,
|
||||||
trade_entries: list[object],
|
|
||||||
|
# TODO: maybe we should just be passing through the
|
||||||
|
# ``ib_insync.order.Trade`` instance directly here
|
||||||
|
# instead of pre-casting to dicts?
|
||||||
|
trade_entries: list[dict],
|
||||||
|
|
||||||
) -> dict:
|
) -> dict:
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -770,7 +770,7 @@ async def stream_quotes(
|
||||||
|
|
||||||
syminfo['price_tick_size'] = max(syminfo['minTick'], min_tick)
|
syminfo['price_tick_size'] = max(syminfo['minTick'], min_tick)
|
||||||
|
|
||||||
# for "traditional" assets, volume is normally discreet, not
|
# for "legacy" assets, volume is normally discreet, not
|
||||||
# a float
|
# a float
|
||||||
syminfo['lot_tick_size'] = 0.0
|
syminfo['lot_tick_size'] = 0.0
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue