Snap y-axis crosshair to min tick(s)
parent
50d2d8517b
commit
f072e2551b
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
# round y value to nearest tick step
|
||||
m = self._y_incr_mult
|
||||
iy = round(y * m) / m
|
||||
|
||||
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, y)
|
||||
item.on_tracked_source(ix, iy)
|
||||
|
||||
if ix != lastx:
|
||||
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:
|
||||
|
|
Loading…
Reference in New Issue