From 32f8931d794703bcf7368197fe796b95620c0824 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Sun, 29 Aug 2021 16:01:25 -0400 Subject: [PATCH] Show "slots used" aka proportion "x" on order lines --- piker/ui/_lines.py | 58 ++++++++++++++++++++++++++++++++---------- piker/ui/_position.py | 47 ++++++++++------------------------ piker/ui/order_mode.py | 2 +- 3 files changed, 59 insertions(+), 48 deletions(-) diff --git a/piker/ui/_lines.py b/piker/ui/_lines.py index 688abf10..4cdb5363 100644 --- a/piker/ui/_lines.py +++ b/piker/ui/_lines.py @@ -18,6 +18,7 @@ Lines for orders, alerts, L2. """ +from functools import partial from math import floor from typing import Tuple, Optional, List, Callable @@ -31,7 +32,8 @@ from ._anchors import ( marker_right_points, vbr_left, right_axis, - # gpath_pin, + # pp_tight_and_right, # wanna keep it straight in the long run + gpath_pin, ) from ..calc import humanize from ._label import Label @@ -166,16 +168,13 @@ class LevelLine(pg.InfiniteLine): for label in self._labels: label.color = self.color - # print(f'color is {self.color}') - label.fields.update(fields_data) + label.render() level = fields_data.get('level') if level: label.set_view_pos(y=level) - label.render() - self.update() def hide_labels(self) -> None: @@ -658,16 +657,30 @@ def order_line( marker_size = marker_size * 0.666 else: + view = line.getViewBox() - # pp_label.scene_anchor = partial( - # gpath_pin, - # location_description='right-of-path-centered', - # gpath=marker, - # label=label, - # ) + pp_size_label = Label( + view=view, + color=line.color, + # 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( - view=line.getViewBox(), + view=view, # display the order pos size, which is some multiple # of the user defined base unit size fmt_str=( @@ -738,7 +751,26 @@ def order_line( # testing to figure out why tf that's true. # 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 line.update_labels({'level': level}) diff --git a/piker/ui/_position.py b/piker/ui/_position.py index 0099cbd7..2cf6bbf3 100644 --- a/piker/ui/_position.py +++ b/piker/ui/_position.py @@ -155,12 +155,12 @@ class Allocator(BaseModel): u_per_slot, currency_per_slot = self.step_sizes() if size_unit == 'units': - enter_step = u_per_slot + slot_size = u_per_slot l_sub_pp = self.units_limit - abs_live_size elif size_unit == 'currency': 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 # an entry (adding-to or starting a pp) @@ -170,7 +170,7 @@ class Allocator(BaseModel): 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) else: @@ -210,10 +210,18 @@ class Allocator(BaseModel): ): 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 { 'size': abs(round(order_size, ndigits=ld)), 'size_digits': ld, 'fiat_size': round(order_size * price, ndigits=2), + 'slots_used': slots_used, } def slots_used( @@ -221,10 +229,9 @@ class Allocator(BaseModel): pp: Position, ) -> 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) if self.size_unit == 'currency': @@ -564,8 +571,6 @@ class PositionTracker: ) pp_label.render() - nsize = self.chart.linked.symbol.lot_size_digits - self.size_label = size_label = Label( view=view, color=self._color, @@ -578,7 +583,6 @@ class PositionTracker: fields={ 'slots_used': 0, - 'size_digits': nsize }, ) size_label.render() @@ -588,30 +592,6 @@ class PositionTracker: 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 def pane(self) -> FieldsForm: '''Return handle to pp side pane form. @@ -657,7 +637,6 @@ class PositionTracker: self.update_line(avg_price, size) # label updates - # self.size_label.fields['slots_used'] = size self.size_label.fields['slots_used'] = round( self.alloc.slots_used(pp), ndigits=1) self.size_label.render() diff --git a/piker/ui/order_mode.py b/piker/ui/order_mode.py index 6a10ae45..f81b52de 100644 --- a/piker/ui/order_mode.py +++ b/piker/ui/order_mode.py @@ -682,7 +682,7 @@ async def display_pnl( for sym, quote in quotes.items(): for tick in iterticks(quote, types): - print(f'{1/period} Hz') + # print(f'{1/period} Hz') size = live.size