Show "slots used" aka proportion "x" on order lines

fsp_feeds
Tyler Goodlet 2021-08-29 16:01:25 -04:00
parent 09fccdf8e5
commit 32f8931d79
3 changed files with 59 additions and 48 deletions

View File

@ -18,6 +18,7 @@
Lines for orders, alerts, L2. Lines for orders, alerts, L2.
""" """
from functools import partial
from math import floor from math import floor
from typing import Tuple, Optional, List, Callable from typing import Tuple, Optional, List, Callable
@ -31,7 +32,8 @@ from ._anchors import (
marker_right_points, marker_right_points,
vbr_left, vbr_left,
right_axis, right_axis,
# gpath_pin, # pp_tight_and_right, # wanna keep it straight in the long run
gpath_pin,
) )
from ..calc import humanize from ..calc import humanize
from ._label import Label from ._label import Label
@ -166,16 +168,13 @@ class LevelLine(pg.InfiniteLine):
for label in self._labels: for label in self._labels:
label.color = self.color label.color = self.color
# print(f'color is {self.color}')
label.fields.update(fields_data) label.fields.update(fields_data)
label.render()
level = fields_data.get('level') level = fields_data.get('level')
if level: if level:
label.set_view_pos(y=level) label.set_view_pos(y=level)
label.render()
self.update() self.update()
def hide_labels(self) -> None: def hide_labels(self) -> None:
@ -658,16 +657,30 @@ def order_line(
marker_size = marker_size * 0.666 marker_size = marker_size * 0.666
else: else:
view = line.getViewBox()
# pp_label.scene_anchor = partial( pp_size_label = Label(
# gpath_pin, view=view,
# location_description='right-of-path-centered', color=line.color,
# gpath=marker,
# label=label,
# )
# this is "static" label
# update_on_range_change=False,
fmt_str='\n'.join((
'{slots_used:.1f}x',
)),
fields={
'slots_used': 0,
},
)
pp_size_label.render()
pp_size_label.show()
line._labels.append(pp_size_label)
# far-side label
label = Label( label = Label(
view=line.getViewBox(), view=view,
# display the order pos size, which is some multiple # display the order pos size, which is some multiple
# of the user defined base unit size # of the user defined base unit size
fmt_str=( fmt_str=(
@ -738,7 +751,26 @@ def order_line(
# testing to figure out why tf that's true. # testing to figure out why tf that's true.
# line.markers.append((marker, 0, marker_size)) # line.markers.append((marker, 0, marker_size))
marker.label = label if action != 'alert':
# TODO: pretty sure one of the reasons these "label
# updatess" are a bit "jittery" is because we aren't
# leveraging the "scene coordinates hierarchy" stuff:
# i.e. using some parent object as the coord "origin"
# which i presume would result in better pixel caching
# results? def something to dig into..
pp_size_label.scene_anchor = partial(
gpath_pin,
gpath=marker,
label=pp_size_label,
)
# XXX: without this the pp proportion label next the marker
# seems to lag? this is the same issue we had with position
# lines which we handle with ``.update_graphcis()``.
# marker._on_paint=lambda marker: pp_size_label.update()
marker._on_paint=lambda marker: pp_size_label.update()
marker.label = label
# sanity check # sanity check
line.update_labels({'level': level}) line.update_labels({'level': level})

View File

@ -155,12 +155,12 @@ class Allocator(BaseModel):
u_per_slot, currency_per_slot = self.step_sizes() u_per_slot, currency_per_slot = self.step_sizes()
if size_unit == 'units': if size_unit == 'units':
enter_step = u_per_slot slot_size = u_per_slot
l_sub_pp = self.units_limit - abs_live_size l_sub_pp = self.units_limit - abs_live_size
elif size_unit == 'currency': elif size_unit == 'currency':
live_cost_basis = abs_live_size * live_pp.avg_price live_cost_basis = abs_live_size * live_pp.avg_price
enter_step = currency_per_slot / price slot_size = currency_per_slot / price
l_sub_pp = (self.currency_limit - live_cost_basis) / price l_sub_pp = (self.currency_limit - live_cost_basis) / price
# an entry (adding-to or starting a pp) # an entry (adding-to or starting a pp)
@ -170,7 +170,7 @@ class Allocator(BaseModel):
live_size == 0 live_size == 0
): ):
order_size = min(enter_step, l_sub_pp) order_size = min(slot_size, l_sub_pp)
# an exit (removing-from or going to net-zero pp) # an exit (removing-from or going to net-zero pp)
else: else:
@ -210,10 +210,18 @@ class Allocator(BaseModel):
): ):
order_size = abs_live_size order_size = abs_live_size
slots_used = 1.0 # the default uniform policy
if order_size < slot_size:
# compute a fractional slots size to display
slots_used = self.slots_used(
Position(symbol=sym, size=order_size, avg_price=price)
)
return { return {
'size': abs(round(order_size, ndigits=ld)), 'size': abs(round(order_size, ndigits=ld)),
'size_digits': ld, 'size_digits': ld,
'fiat_size': round(order_size * price, ndigits=2), 'fiat_size': round(order_size * price, ndigits=2),
'slots_used': slots_used,
} }
def slots_used( def slots_used(
@ -221,10 +229,9 @@ class Allocator(BaseModel):
pp: Position, pp: Position,
) -> float: ) -> float:
'''Calc and return the number of slots used by this ``Position``.
# alloc = self.alloc '''
# live_pp = self.tracker.live_pp
# live_pp_size = abs(live_pp.size)
abs_pp_size = abs(pp.size) abs_pp_size = abs(pp.size)
if self.size_unit == 'currency': if self.size_unit == 'currency':
@ -564,8 +571,6 @@ class PositionTracker:
) )
pp_label.render() pp_label.render()
nsize = self.chart.linked.symbol.lot_size_digits
self.size_label = size_label = Label( self.size_label = size_label = Label(
view=view, view=view,
color=self._color, color=self._color,
@ -578,7 +583,6 @@ class PositionTracker:
fields={ fields={
'slots_used': 0, 'slots_used': 0,
'size_digits': nsize
}, },
) )
size_label.render() size_label.render()
@ -588,30 +592,6 @@ class PositionTracker:
label=self.pp_label, label=self.pp_label,
) )
# size_label.scene_anchor = lambda: (
# self.pp_label.txt.pos() + QPointF(self.pp_label.w, 0)
# )
# size_label.scene_anchor = lambda: (
# self.pp_label.scene_br().bottomRight() - QPointF(
# self.size_label.w, self.size_label.h/3)
# )
# TODO: if we want to show more position-y info?
# fmt_str='\n'.join((
# # '{entry_size}x ',
# '{percent_pnl} % PnL',
# # '{percent_of_port}% of port',
# '${base_unit_value}',
# )),
# fields={
# # 'entry_size': 0,
# 'percent_pnl': 0,
# 'percent_of_port': 2,
# 'base_unit_value': '1k',
# },
# )
@property @property
def pane(self) -> FieldsForm: def pane(self) -> FieldsForm:
'''Return handle to pp side pane form. '''Return handle to pp side pane form.
@ -657,7 +637,6 @@ class PositionTracker:
self.update_line(avg_price, size) self.update_line(avg_price, size)
# label updates # label updates
# self.size_label.fields['slots_used'] = size
self.size_label.fields['slots_used'] = round( self.size_label.fields['slots_used'] = round(
self.alloc.slots_used(pp), ndigits=1) self.alloc.slots_used(pp), ndigits=1)
self.size_label.render() self.size_label.render()

View File

@ -682,7 +682,7 @@ async def display_pnl(
for sym, quote in quotes.items(): for sym, quote in quotes.items():
for tick in iterticks(quote, types): for tick in iterticks(quote, types):
print(f'{1/period} Hz') # print(f'{1/period} Hz')
size = live.size size = live.size