Show "slots used" aka proportion "x" on order lines
parent
09fccdf8e5
commit
32f8931d79
|
@ -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})
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue