Key pps by bsuid to avoid incorrect disparate entries
parent
f1fe369bbf
commit
68b32208de
69
piker/pp.py
69
piker/pp.py
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue