diff --git a/piker/ui/_chart.py b/piker/ui/_chart.py index 91f8332f..6696622d 100644 --- a/piker/ui/_chart.py +++ b/piker/ui/_chart.py @@ -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) diff --git a/piker/ui/_graphics/_cursor.py b/piker/ui/_graphics/_cursor.py index 5d312f39..791ffccc 100644 --- a/piker/ui/_graphics/_cursor.py +++ b/piker/ui/_graphics/_cursor.py @@ -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: