Key pps by bsuid to avoid incorrect disparate entries

lifo_pps_ib
Tyler Goodlet 2022-06-19 16:30:08 -04:00
parent f1fe369bbf
commit 68b32208de
1 changed files with 48 additions and 21 deletions

View File

@ -125,7 +125,7 @@ class Position(Struct):
# ordered record of known constituent trade messages # ordered record of known constituent trade messages
clears: dict[ clears: dict[
Union[str, int, Status], # trade id Union[str, int, Status], # trade id
float, # cost dict[str, Any], # transaction history summaries
] = {} ] = {}
expiry: Optional[datetime] = None expiry: Optional[datetime] = None
@ -137,13 +137,16 @@ class Position(Struct):
} }
def to_pretoml(self) -> dict: def to_pretoml(self) -> dict:
'''
Prep this position's data contents for export to toml including
re-structuring of the ``.clears`` table to an array of
inline-subtables for better ``pps.toml`` compactness.
'''
d = self.to_dict() d = self.to_dict()
clears = d.pop('clears') clears = d.pop('clears')
expiry = d.pop('expiry') expiry = d.pop('expiry')
# if not expiry is None:
# breakpoint()
if expiry: if expiry:
d['expiry'] = str(expiry) d['expiry'] = str(expiry)
@ -151,8 +154,6 @@ class Position(Struct):
for tid, data in clears.items(): for tid, data in clears.items():
inline_table = toml.TomlDecoder().get_empty_inline_table() inline_table = toml.TomlDecoder().get_empty_inline_table()
# inline_table[f'{tid}'] = data
# inline_table = type('uhh', (dict, toml.decoder.InlineTableDict()),
inline_table['tid'] = tid inline_table['tid'] = tid
for k, v in data.items(): for k, v in data.items():
@ -161,7 +162,7 @@ class Position(Struct):
clears_list.append(inline_table) clears_list.append(inline_table)
d['clears'] = clears_list d['clears'] = clears_list
# d['clears'] = inline_table
return d return d
def update_from_msg( def update_from_msg(
@ -265,7 +266,7 @@ def update_pps(
for r in records: for r in records:
pp = pps.setdefault( pp = pps.setdefault(
r.fqsn or r.bsuid, r.bsuid,
# if no existing pp, allocate fresh one. # if no existing pp, allocate fresh one.
Position( Position(
@ -417,6 +418,9 @@ def get_pps(
return all_active return all_active
# TODO: instead see if we can hack tomli and tomli-w to do the same:
# - https://github.com/hukkin/tomli
# - https://github.com/hukkin/tomli-w
class PpsEncoder(toml.TomlEncoder): class PpsEncoder(toml.TomlEncoder):
''' '''
Special "styled" encoder that makes a ``pps.toml`` redable and Special "styled" encoder that makes a ``pps.toml`` redable and
@ -427,9 +431,11 @@ class PpsEncoder(toml.TomlEncoder):
separator = ',' separator = ','
def dump_list(self, v): def dump_list(self, v):
# breakpoint() '''
# super().dump_list(section) Dump an inline list with a newline after every element and
with consideration for denoted inline table types.
'''
retval = "[\n" retval = "[\n"
for u in v: for u in v:
if isinstance(u, toml.decoder.InlineTableDict): if isinstance(u, toml.decoder.InlineTableDict):
@ -543,14 +549,17 @@ class PpsEncoder(toml.TomlEncoder):
return (retstr, retdict) return (retstr, retdict)
def update_pps_conf( def load_pps_from_toml(
brokername: str, brokername: str,
acctid: str, acctid: str
trade_records: Optional[list[Transaction]] = None,
key_by: Optional[str] = None,
) -> dict[str, Position]: ) -> tuple[dict, dict[str, Position]]:
'''
Load and marshal to objects all pps from either an existing
``pps.toml`` config, or from scratch from a ledger file when
none yet exists.
'''
conf, path = config.load('pps') conf, path = config.load('pps')
brokersection = conf.setdefault(brokername, {}) brokersection = conf.setdefault(brokername, {})
pps = brokersection.setdefault(acctid, {}) pps = brokersection.setdefault(acctid, {})
@ -603,6 +612,19 @@ def update_pps_conf(
clears=clears, clears=clears,
) )
return conf, pp_objs
def update_pps_conf(
brokername: str,
acctid: str,
trade_records: Optional[list[Transaction]] = None,
key_by: Optional[str] = None,
) -> dict[str, Position]:
conf, pp_objs = load_pps_from_toml(brokername, acctid)
# update all pp objects from any (new) trade records which # update all pp objects from any (new) trade records which
# were passed in (aka incremental update case). # were passed in (aka incremental update case).
if trade_records: if trade_records:
@ -615,24 +637,29 @@ def update_pps_conf(
# dict-serialize all active pps # dict-serialize all active pps
pp_entries = {} pp_entries = {}
for fqsn, pp_dict in active.items():
print(f'Updating active pp: {fqsn}') for bsuid, pp_dict in active.items():
# normalize to a simpler flat dict format # normalize to a simpler flat dict format
_ = pp_dict.pop('symbol') s = pp_dict.pop('symbol')
# TODO: we need to figure out how to have one top level
# listing venue here even when the backend isn't providing
# it via the trades ledger..
fqsn = s.front_fqsn()
print(f'Updating active pp: {fqsn}')
# XXX: ugh, it's cuz we push the section under # XXX: ugh, it's cuz we push the section under
# the broker name.. maybe we need to rethink this? # the broker name.. maybe we need to rethink this?
brokerless_key = fqsn.rstrip(f'.{brokername}') brokerless_key = fqsn.rstrip(f'.{brokername}')
pp_entries[brokerless_key] = pp_dict pp_entries[brokerless_key] = pp_dict
for fqsn in closed: for bsuid in closed:
pp_objs.pop(fqsn, None) pp_objs.pop(bsuid, None)
conf[brokername][acctid] = pp_entries conf[brokername][acctid] = pp_entries
enc = PpsEncoder(preserve=True)
# TODO: why tf haven't they already done this for inline tables smh.. # TODO: why tf haven't they already done this for inline tables smh..
enc = PpsEncoder(preserve=True)
# table_bs_type = type(toml.TomlDecoder().get_empty_inline_table()) # table_bs_type = type(toml.TomlDecoder().get_empty_inline_table())
enc.dump_funcs[toml.decoder.InlineTableDict] = enc.dump_inline_table enc.dump_funcs[toml.decoder.InlineTableDict] = enc.dump_inline_table