Snap y-axis crosshair to min tick(s)

basic_orders
Tyler Goodlet 2021-01-22 22:59:00 -05:00
parent 50d2d8517b
commit f072e2551b
2 changed files with 35 additions and 21 deletions

View File

@ -1,5 +1,5 @@
# piker: trading gear for hackers
# Copyright (C) 2018-present Tyler Goodlet (in stewardship of piker0)
# Copyright (C) Tyler Goodlet (in stewardship for piker0)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -138,7 +138,10 @@ class ChartSpace(QtGui.QWidget):
Expects a ``numpy`` structured array containing all the ohlcv fields.
"""
# XXX: let's see if this causes mem problems
self.window.setWindowTitle(f'piker chart {symbol}')
self.window.setWindowTitle(
f'piker chart {symbol.key}@{symbol.brokers} '
f'tick:{symbol.min_tick}'
)
# TODO: symbol search
# # of course this doesn't work :eyeroll:
@ -192,6 +195,7 @@ class LinkedSplitCharts(QtGui.QWidget):
self._cursor: Cursor = None # crosshair graphics
self.chart: ChartPlotWidget = None # main (ohlc) chart
self.subplots: Dict[Tuple[str, ...], ChartPlotWidget] = {}
self.digits: int = 2
self.xaxis = DynamicDateAxis(
orientation='bottom',
@ -241,6 +245,7 @@ class LinkedSplitCharts(QtGui.QWidget):
The data input struct array must include OHLC fields.
"""
self.min_tick = symbol.min_tick
self.digits = symbol.digits()
# add crosshairs
@ -652,7 +657,7 @@ class ChartPlotWidget(pg.PlotWidget):
chart=self,
parent=self.getAxis('right'),
# TODO: pass this from symbol data
# digits=0,
digits=self._lc._symbol.digits(),
opacity=1,
bg_color=bg_color,
)
@ -854,8 +859,6 @@ async def _async_main(
# historical data fetch
brokermod = brokers.get_brokermod(brokername)
symbol = Symbol(sym, [brokername])
async with data.open_feed(
brokername,
[sym],
@ -864,6 +867,7 @@ async def _async_main(
ohlcv = feed.shm
bars = ohlcv.array
symbol = feed.symbols[sym]
# load in symbol's ohlc data
linked_charts, chart = chart_app.load_symbol(symbol, bars)

View File

@ -1,5 +1,5 @@
# piker: trading gear for hackers
# Copyright (C) 2018-present Tyler Goodlet (in stewardship of piker0)
# Copyright (C) Tyler Goodlet (in stewardship for piker0)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@ -226,6 +226,10 @@ class Cursor(pg.GraphicsObject):
self._hovered: Set[pg.GraphicsObject] = set()
self._trackers: Set[pg.GraphicsObject] = set()
# value used for rounding y-axis discreet tick steps
# computing once, up front, here cuz why not
self._y_incr_mult = 1 / self.lsc._symbol.min_tick
def add_hovered(
self,
item: pg.GraphicsObject,
@ -347,25 +351,31 @@ class Cursor(pg.GraphicsObject):
x, y = mouse_point.x(), mouse_point.y()
plot = self.active_plot
# update y-range items
self.graphics[plot]['hl'].setY(y)
self.graphics[self.active_plot]['yl'].update_label(
abs_pos=pos, value=y
)
# Update x if cursor changed after discretization calc
# (this saves draw cycles on small mouse moves)
lastx, lasty = self._datum_xy
last_ix, last_iy = self._datum_xy
ix = round(x) # since bars are centered around index
# update all trackers
for item in self._trackers:
# print(f'setting {item} with {(ix, y)}')
item.on_tracked_source(ix, y)
# round y value to nearest tick step
m = self._y_incr_mult
iy = round(y * m) / m
if ix != lastx:
if iy != last_iy:
# update y-range items
self.graphics[plot]['hl'].setY(iy)
self.graphics[self.active_plot]['yl'].update_label(
abs_pos=pos, value=iy
)
# update all trackers
for item in self._trackers:
# print(f'setting {item} with {(ix, y)}')
item.on_tracked_source(ix, iy)
if ix != last_ix:
for plot, opts in self.graphics.items():
# move the vertical line to the current "center of bar"
@ -390,7 +400,7 @@ class Cursor(pg.GraphicsObject):
value=x,
)
self._datum_xy = ix, y
self._datum_xy = ix, iy
def boundingRect(self):
try: