Simplify L1 labels for multicharts
Instead of having the l1 lines be inside the view space, move them to be inside their respective axis (with only a 16 unit portion inside the view) such that the clear price label can overlay with them nicely without obscuring; this is much better suited to multiple adjacent y-axes and in general is simpler and less noisy. Further `L1Labels` + `LevelLabel` style tweaks: - adjust `.rect` positioning to be "right" (i.e. inside the parent y-axis) with a slight 16 unit shift toward the viewbox (using the new `._x_br_offset`) to allow seeing each level label's line even when the clearing price label is positioned at that same level. - add a newline's worth of vertical space to each of the bid/ask labels so that L1 labels' text content isn't ever obscured by the clear price label. - set a low (10) z-value to ensure l1 labels are always placed underneath the clear price label. - always fill the label rect with the chosen background color. - make labels fully opaque so as to always make them hide the parent axes' `.tickStrings()` contents. - make default color the "default" from the global scheme. - drop the "price" part from the l1 label text contents, just show the book-queue's amount (in dst asset's units, aka the potential clearing vlm).multichartz
parent
b7619e5ea4
commit
5c853395bb
|
@ -30,19 +30,20 @@ from ._pg_overrides import PlotItem
|
||||||
|
|
||||||
|
|
||||||
class LevelLabel(YAxisLabel):
|
class LevelLabel(YAxisLabel):
|
||||||
"""Y-axis (vertically) oriented, horizontal label that sticks to
|
'''
|
||||||
|
Y-axis (vertically) oriented, horizontal label that sticks to
|
||||||
where it's placed despite chart resizing and supports displaying
|
where it's placed despite chart resizing and supports displaying
|
||||||
multiple fields.
|
multiple fields.
|
||||||
|
|
||||||
|
|
||||||
TODO: replace the rectangle-text part with our new ``Label`` type.
|
TODO: replace the rectangle-text part with our new ``Label`` type.
|
||||||
|
|
||||||
"""
|
'''
|
||||||
_x_margin = 0
|
_x_br_offset: float = -16
|
||||||
_y_margin = 0
|
_x_txt_h_scaling: float = 2
|
||||||
|
|
||||||
# adjustment "further away from" anchor point
|
# adjustment "further away from" anchor point
|
||||||
_x_offset = 9
|
_x_offset = 0
|
||||||
_y_offset = 0
|
_y_offset = 0
|
||||||
|
|
||||||
# fields to be displayed in the label string
|
# fields to be displayed in the label string
|
||||||
|
@ -58,12 +59,12 @@ class LevelLabel(YAxisLabel):
|
||||||
chart,
|
chart,
|
||||||
parent,
|
parent,
|
||||||
|
|
||||||
color: str = 'bracket',
|
color: str = 'default_light',
|
||||||
|
|
||||||
orient_v: str = 'bottom',
|
orient_v: str = 'bottom',
|
||||||
orient_h: str = 'left',
|
orient_h: str = 'right',
|
||||||
|
|
||||||
opacity: float = 0,
|
opacity: float = 1,
|
||||||
|
|
||||||
# makes order line labels offset from their parent axis
|
# makes order line labels offset from their parent axis
|
||||||
# such that they don't collide with the L1/L2 lines/prices
|
# such that they don't collide with the L1/L2 lines/prices
|
||||||
|
@ -99,13 +100,15 @@ class LevelLabel(YAxisLabel):
|
||||||
|
|
||||||
self._h_shift = {
|
self._h_shift = {
|
||||||
'left': -1.,
|
'left': -1.,
|
||||||
'right': 0.
|
'right': 0.,
|
||||||
}[orient_h]
|
}[orient_h]
|
||||||
|
|
||||||
self.fields = self._fields.copy()
|
self.fields = self._fields.copy()
|
||||||
# ensure default format fields are in correct
|
# ensure default format fields are in correct
|
||||||
self.set_fmt_str(self._fmt_str, self.fields)
|
self.set_fmt_str(self._fmt_str, self.fields)
|
||||||
|
|
||||||
|
self.setZValue(10)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def color(self):
|
def color(self):
|
||||||
return self._hcolor
|
return self._hcolor
|
||||||
|
@ -113,7 +116,10 @@ class LevelLabel(YAxisLabel):
|
||||||
@color.setter
|
@color.setter
|
||||||
def color(self, color: str) -> None:
|
def color(self, color: str) -> None:
|
||||||
self._hcolor = color
|
self._hcolor = color
|
||||||
self._pen = self.pen = pg.mkPen(hcolor(color))
|
self._pen = self.pen = pg.mkPen(
|
||||||
|
hcolor(color),
|
||||||
|
width=3,
|
||||||
|
)
|
||||||
|
|
||||||
def update_on_resize(self, vr, r):
|
def update_on_resize(self, vr, r):
|
||||||
"""Tiis is a ``.sigRangeChanged()`` handler.
|
"""Tiis is a ``.sigRangeChanged()`` handler.
|
||||||
|
@ -125,10 +131,11 @@ class LevelLabel(YAxisLabel):
|
||||||
self,
|
self,
|
||||||
fields: dict = None,
|
fields: dict = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update the label's text contents **and** position from
|
'''
|
||||||
|
Update the label's text contents **and** position from
|
||||||
a view box coordinate datum.
|
a view box coordinate datum.
|
||||||
|
|
||||||
"""
|
'''
|
||||||
self.fields.update(fields)
|
self.fields.update(fields)
|
||||||
level = self.fields['level']
|
level = self.fields['level']
|
||||||
|
|
||||||
|
@ -175,7 +182,8 @@ class LevelLabel(YAxisLabel):
|
||||||
fields: dict,
|
fields: dict,
|
||||||
):
|
):
|
||||||
# use space as e3 delim
|
# use space as e3 delim
|
||||||
self.label_str = self._fmt_str.format(**fields).replace(',', ' ')
|
self.label_str = self._fmt_str.format(
|
||||||
|
**fields).replace(',', ' ')
|
||||||
|
|
||||||
br = self.boundingRect()
|
br = self.boundingRect()
|
||||||
h, w = br.height(), br.width()
|
h, w = br.height(), br.width()
|
||||||
|
@ -188,14 +196,14 @@ class LevelLabel(YAxisLabel):
|
||||||
self,
|
self,
|
||||||
p: QtGui.QPainter,
|
p: QtGui.QPainter,
|
||||||
rect: QtCore.QRectF
|
rect: QtCore.QRectF
|
||||||
) -> None:
|
|
||||||
p.setPen(self._pen)
|
|
||||||
|
|
||||||
|
) -> None:
|
||||||
|
|
||||||
|
p.setPen(self._pen)
|
||||||
rect = self.rect
|
rect = self.rect
|
||||||
|
|
||||||
if self._orient_v == 'bottom':
|
if self._orient_v == 'bottom':
|
||||||
lp, rp = rect.topLeft(), rect.topRight()
|
lp, rp = rect.topLeft(), rect.topRight()
|
||||||
# p.drawLine(rect.topLeft(), rect.topRight())
|
|
||||||
|
|
||||||
elif self._orient_v == 'top':
|
elif self._orient_v == 'top':
|
||||||
lp, rp = rect.bottomLeft(), rect.bottomRight()
|
lp, rp = rect.bottomLeft(), rect.bottomRight()
|
||||||
|
@ -209,6 +217,11 @@ class LevelLabel(YAxisLabel):
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
|
|
||||||
|
p.fillRect(
|
||||||
|
self.rect,
|
||||||
|
self.bg_color,
|
||||||
|
)
|
||||||
|
|
||||||
def highlight(self, pen) -> None:
|
def highlight(self, pen) -> None:
|
||||||
self._pen = pen
|
self._pen = pen
|
||||||
self.update()
|
self.update()
|
||||||
|
@ -247,9 +260,10 @@ class L1Label(LevelLabel):
|
||||||
|
|
||||||
|
|
||||||
class L1Labels:
|
class L1Labels:
|
||||||
"""Level 1 bid ask labels for dynamic update on price-axis.
|
'''
|
||||||
|
Level 1 bid ask labels for dynamic update on price-axis.
|
||||||
|
|
||||||
"""
|
'''
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
plotitem: PlotItem,
|
plotitem: PlotItem,
|
||||||
|
@ -265,15 +279,17 @@ class L1Labels:
|
||||||
'chart': plotitem,
|
'chart': plotitem,
|
||||||
'parent': raxis,
|
'parent': raxis,
|
||||||
|
|
||||||
'opacity': 1,
|
'opacity': .9,
|
||||||
'font_size': font_size,
|
'font_size': font_size,
|
||||||
'fg_color': chart.pen_color,
|
'fg_color': 'default_light',
|
||||||
'bg_color': chart.view_color,
|
'bg_color': chart.view_color, # normally 'papas_special'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TODO: add humanized source-asset
|
||||||
|
# info format.
|
||||||
fmt_str = (
|
fmt_str = (
|
||||||
' {size:.{size_digits}f} x '
|
' {size:.{size_digits}f} u'
|
||||||
'{level:,.{level_digits}f} '
|
# '{level:,.{level_digits}f} '
|
||||||
)
|
)
|
||||||
fields = {
|
fields = {
|
||||||
'level': 0,
|
'level': 0,
|
||||||
|
@ -286,12 +302,17 @@ class L1Labels:
|
||||||
orient_v='bottom',
|
orient_v='bottom',
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
bid.set_fmt_str(fmt_str=fmt_str, fields=fields)
|
bid.set_fmt_str(
|
||||||
|
fmt_str='\n' + fmt_str,
|
||||||
|
fields=fields,
|
||||||
|
)
|
||||||
bid.show()
|
bid.show()
|
||||||
|
|
||||||
ask = self.ask_label = L1Label(
|
ask = self.ask_label = L1Label(
|
||||||
orient_v='top',
|
orient_v='top',
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
ask.set_fmt_str(fmt_str=fmt_str, fields=fields)
|
ask.set_fmt_str(
|
||||||
|
fmt_str=fmt_str,
|
||||||
|
fields=fields)
|
||||||
ask.show()
|
ask.show()
|
||||||
|
|
Loading…
Reference in New Issue