Configure allocator from pos msg on startup

This fixes a regression added after moving the msg parsing to later in
the order mode startup sequence. The `Allocator` needs to be configured
*to* the initial pos otherwise default settings will show in the UI..

Move the startup config logic from inside `mk_allocator()` to
`PositionTracker.update_from_pp()` and add a flag to allow setting the
`.startup_pp` from the current live one as is needed during initial
load.
size_in_shm_token
Tyler Goodlet 2022-08-29 11:36:09 -04:00
parent 46d3fe88ca
commit d5c1cdd91d
3 changed files with 57 additions and 56 deletions

View File

@ -244,14 +244,6 @@ class Allocator(Struct):
return round(prop * self.slots)
_derivs = (
'future',
'continuous_future',
'option',
'futures_option',
)
def mk_allocator(
symbol: Symbol,
@ -278,45 +270,9 @@ def mk_allocator(
'currency_limit': 6e3,
'slots': 6,
}
defaults.update(user_def)
alloc = Allocator(
return Allocator(
symbol=symbol,
**defaults,
)
asset_type = symbol.type_key
# specific configs by asset class / type
if asset_type in _derivs:
# since it's harder to know how currency "applies" in this case
# given leverage properties
alloc.size_unit = '# units'
# set units limit to slots size thus making make the next
# entry step 1.0
alloc.units_limit = alloc.slots
else:
alloc.size_unit = 'currency'
# if the current position is already greater then the limit
# settings, increase the limit to the current position
if alloc.size_unit == 'currency':
startup_size = startup_pp.size * startup_pp.ppu
if startup_size > alloc.currency_limit:
alloc.currency_limit = round(startup_size, ndigits=2)
else:
startup_size = abs(startup_pp.size)
if startup_size > alloc.units_limit:
alloc.units_limit = startup_size
if asset_type in _derivs:
alloc.slots = alloc.units_limit
return alloc

View File

@ -458,6 +458,14 @@ def position_line(
return line
_derivs = (
'future',
'continuous_future',
'option',
'futures_option',
)
class PositionTracker:
'''
Track and display real-time positions for a single symbol
@ -564,14 +572,54 @@ class PositionTracker:
def update_from_pp(
self,
position: Optional[Position] = None,
set_as_startup: bool = False,
) -> None:
'''Update graphics and data from average price and size passed in our
EMS ``BrokerdPosition`` msg.
'''
Update graphics and data from average price and size passed in
our EMS ``BrokerdPosition`` msg.
'''
# live pp updates
pp = position or self.live_pp
if set_as_startup:
startup_pp = pp
else:
startup_pp = self.startup_pp
alloc = self.alloc
# update allocator settings
asset_type = pp.symbol.type_key
# specific configs by asset class / type
if asset_type in _derivs:
# since it's harder to know how currency "applies" in this case
# given leverage properties
alloc.size_unit = '# units'
# set units limit to slots size thus making make the next
# entry step 1.0
alloc.units_limit = alloc.slots
else:
alloc.size_unit = 'currency'
# if the current position is already greater then the limit
# settings, increase the limit to the current position
if alloc.size_unit == 'currency':
startup_size = self.startup_pp.size * startup_pp.ppu
if startup_size > alloc.currency_limit:
alloc.currency_limit = round(startup_size, ndigits=2)
else:
startup_size = abs(startup_pp.size)
if startup_size > alloc.units_limit:
alloc.units_limit = startup_size
if asset_type in _derivs:
alloc.slots = alloc.units_limit
self.update_line(
pp.ppu,
@ -581,7 +629,7 @@ class PositionTracker:
# label updates
self.size_label.fields['slots_used'] = round(
self.alloc.slots_used(pp), ndigits=1)
alloc.slots_used(pp), ndigits=1)
self.size_label.render()
if pp.size == 0:

View File

@ -639,11 +639,6 @@ async def open_order_mode(
iter(accounts.keys())
) if accounts else 'paper'
# Pack position messages by account, should only be one-to-one.
# NOTE: requires the backend exactly specifies
# the expected symbol key in its positions msg.
# pps_by_account = {}
# update pp trackers with data relayed from ``brokerd``.
for account_name in accounts:
@ -656,6 +651,7 @@ async def open_order_mode(
# XXX: BLEH, do we care about this on the client side?
bsuid=symbol,
)
# allocator config
alloc = mk_allocator(
symbol=symbol,
@ -750,7 +746,6 @@ async def open_order_mode(
# to order sync pane handler
for key in ('account', 'size_unit',):
w = form.fields[key]
w.currentTextChanged.connect(
partial(
order_pane.on_selection_change,
@ -773,6 +768,9 @@ async def open_order_mode(
# Begin order-response streaming
done()
# Pack position messages by account, should only be one-to-one.
# NOTE: requires the backend exactly specifies
# the expected symbol key in its positions msg.
for (broker, acctid), msgs in position_msgs.items():
for msg in msgs:
log.info(f'Loading pp for {symkey}:\n{pformat(msg)}')
@ -869,8 +867,7 @@ async def process_trade_msg(
log.info(f'{fqsn} matched pp msg: {fmsg}')
tracker = mode.trackers[msg['account']]
tracker.live_pp.update_from_msg(msg)
# update order pane widgets
tracker.update_from_pp()
tracker.update_from_pp(set_as_startup=True) # status/pane UI
mode.pane.update_status_ui(tracker)
if tracker.live_pp.size: