Don't override `Account.pps: dict` entries..
Despite a `.bs_mktid` ideally being a bijection with `MktPair.fqme` values, apparently some backends (cough IB) will switch the .<venue>` part in txn records resulting in multiple account-conf-file sections for the same dst asset. Obviously that means we can't allocate new `Position` entries keyed by that `bs_mktid`, instead be sure to **update them instead**! Deats, - add case logic to avoid pp overwrites using a `pp_objs.get()` check. - warn on duplicated pos entries whenever the current account-file entry's `mkt` doesn't match the pre-existing position's. - mk `Position.add_clear()` return a `bool` indicating if the record was newly added, warn when it was already existing/added prior. Also, - drop the already deprecated `open_pps()`, also from sub-pkg exports. - draft TODO for `Position.summary()` idea as a replacement for `BrokerdPosition`-msgs.qt_w_graceful_SIGINT
parent
6cc3518143
commit
b0f273f091
|
@ -33,7 +33,6 @@ from ._pos import (
|
|||
Account,
|
||||
load_account,
|
||||
load_account_from_ledger,
|
||||
open_pps,
|
||||
open_account,
|
||||
Position,
|
||||
)
|
||||
|
@ -68,7 +67,6 @@ __all__ = [
|
|||
'load_account_from_ledger',
|
||||
'mk_allocator',
|
||||
'open_account',
|
||||
'open_pps',
|
||||
'open_trade_ledger',
|
||||
'unpack_fqme',
|
||||
'DerivTypes',
|
||||
|
|
|
@ -353,13 +353,12 @@ class Position(Struct):
|
|||
) -> bool:
|
||||
'''
|
||||
Update clearing table by calculating the rolling ppu and
|
||||
(accumulative) size in both the clears entry and local
|
||||
attrs state.
|
||||
(accumulative) size in both the clears entry and local attrs
|
||||
state.
|
||||
|
||||
Inserts are always done in datetime sorted order.
|
||||
|
||||
'''
|
||||
# added: bool = False
|
||||
tid: str = t.tid
|
||||
if tid in self._events:
|
||||
log.debug(
|
||||
|
@ -367,7 +366,7 @@ class Position(Struct):
|
|||
f'\n'
|
||||
f'{t}\n'
|
||||
)
|
||||
# return added
|
||||
return False
|
||||
|
||||
# TODO: apparently this IS possible with a dict but not
|
||||
# common and probably not that beneficial unless we're also
|
||||
|
@ -448,6 +447,12 @@ class Position(Struct):
|
|||
# def suggest_split(self) -> float:
|
||||
# ...
|
||||
|
||||
# ?TODO, for sending rendered state over the wire?
|
||||
# def summary(self) -> PositionSummary:
|
||||
# do minimal conversion to a subset of fields
|
||||
# currently defined in `.clearing._messages.BrokerdPosition`
|
||||
|
||||
|
||||
|
||||
class Account(Struct):
|
||||
'''
|
||||
|
@ -491,9 +496,9 @@ class Account(Struct):
|
|||
|
||||
def update_from_ledger(
|
||||
self,
|
||||
ledger: TransactionLedger | dict[str, Transaction],
|
||||
ledger: TransactionLedger|dict[str, Transaction],
|
||||
cost_scalar: float = 2,
|
||||
symcache: SymbologyCache | None = None,
|
||||
symcache: SymbologyCache|None = None,
|
||||
|
||||
_mktmap_table: dict[str, MktPair] | None = None,
|
||||
|
||||
|
@ -714,7 +719,7 @@ class Account(Struct):
|
|||
# XXX WTF: if we use a tomlkit.Integer here we get this
|
||||
# super weird --1 thing going on for cumsize!?1!
|
||||
# NOTE: the fix was to always float() the size value loaded
|
||||
# in open_pps() below!
|
||||
# in open_account() below!
|
||||
config.write(
|
||||
config=self.conf,
|
||||
path=self.conf_path,
|
||||
|
@ -898,7 +903,6 @@ def open_account(
|
|||
clears_table['dt'] = dt
|
||||
trans.append(Transaction(
|
||||
fqme=bs_mktid,
|
||||
# sym=mkt,
|
||||
bs_mktid=bs_mktid,
|
||||
tid=tid,
|
||||
# XXX: not sure why sometimes these are loaded as
|
||||
|
@ -921,11 +925,22 @@ def open_account(
|
|||
):
|
||||
expiry: pendulum.DateTime = pendulum.parse(expiry)
|
||||
|
||||
pp = pp_objs[bs_mktid] = Position(
|
||||
mkt,
|
||||
split_ratio=split_ratio,
|
||||
bs_mktid=bs_mktid,
|
||||
)
|
||||
# !XXX, should never be duplicates over
|
||||
# a backend-(broker)-system's unique market-IDs!
|
||||
if pos := pp_objs.get(bs_mktid):
|
||||
if mkt != pos.mkt:
|
||||
log.warning(
|
||||
f'Duplicated position but diff `MktPair.fqme` ??\n'
|
||||
f'bs_mktid: {bs_mktid!r}\n'
|
||||
f'pos.mkt: {pos.mkt}\n'
|
||||
f'mkt: {mkt}\n'
|
||||
)
|
||||
else:
|
||||
pos = pp_objs[bs_mktid] = Position(
|
||||
mkt,
|
||||
split_ratio=split_ratio,
|
||||
bs_mktid=bs_mktid,
|
||||
)
|
||||
|
||||
# XXX: super critical, we need to be sure to include
|
||||
# all pps.toml clears to avoid reusing clears that were
|
||||
|
@ -933,8 +948,13 @@ def open_account(
|
|||
# state, since today's records may have already been
|
||||
# processed!
|
||||
for t in trans:
|
||||
pp.add_clear(t)
|
||||
|
||||
added: bool = pos.add_clear(t)
|
||||
if not added:
|
||||
log.warning(
|
||||
f'Txn already recorded in pp ??\n'
|
||||
f'\n'
|
||||
f'{t}\n'
|
||||
)
|
||||
try:
|
||||
yield acnt
|
||||
finally:
|
||||
|
@ -942,20 +962,6 @@ def open_account(
|
|||
acnt.write_config()
|
||||
|
||||
|
||||
# TODO: drop the old name and THIS!
|
||||
@cm
|
||||
def open_pps(
|
||||
*args,
|
||||
**kwargs,
|
||||
) -> Generator[Account, None, None]:
|
||||
log.warning(
|
||||
'`open_pps()` is now deprecated!\n'
|
||||
'Please use `with open_account() as cnt:`'
|
||||
)
|
||||
with open_account(*args, **kwargs) as acnt:
|
||||
yield acnt
|
||||
|
||||
|
||||
def load_account_from_ledger(
|
||||
|
||||
brokername: str,
|
||||
|
|
Loading…
Reference in New Issue