Add a naive maxmin calc to avoid frequent resizes

If we know the max and min in view then on datum updates we can avoid
resizing the y-range when a new max/min has not yet arrived.

This adds a very naive numpy calc in the drawing thread which we can
likely improve with a more efficient streaming alternative which can
also likely be run in a fsp subactor. Also, since this same calc is
essentially done inside `._set_yrange()` we will likely want to allow
passing the result into the method to avoid duplicate work.
bar_select
Tyler Goodlet 2020-09-29 16:18:21 -04:00
parent 6d5ccc6c3f
commit 8d9a6845c6
1 changed files with 31 additions and 12 deletions

View File

@ -137,10 +137,10 @@ class LinkedSplitCharts(QtGui.QWidget):
# if _xaxis_at == 'bottom': # if _xaxis_at == 'bottom':
# self.xaxis.setStyle(showValues=False) # self.xaxis.setStyle(showValues=False)
# # self.xaxis.hide() # self.xaxis.hide()
# else: # else:
# self.xaxis_ind.setStyle(showValues=False) # self.xaxis_ind.setStyle(showValues=False)
# self.xaxis.hide() # self.xaxis.hide()
self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical) self.splitter = QtGui.QSplitter(QtCore.Qt.Vertical)
self.splitter.setMidLineWidth(3) self.splitter.setMidLineWidth(3)
@ -231,7 +231,7 @@ class LinkedSplitCharts(QtGui.QWidget):
cpw.name = name cpw.name = name
cpw.plotItem.vb.linked_charts = self cpw.plotItem.vb.linked_charts = self
cpw.setFrameStyle(QtGui.QFrame.StyledPanel) # | QtGui.QFrame.Plain) cpw.setFrameStyle(QtGui.QFrame.StyledPanel) # | QtGui.QFrame.Plain)
cpw.getPlotItem().setContentsMargins(*CHART_MARGINS) cpw.getPlotItem().setContentsMargins(*CHART_MARGINS)
cpw.hideButtons() cpw.hideButtons()
@ -705,15 +705,19 @@ async def chart_from_quotes(
# - 5 sec bar lookback-autocorrection like tws does? # - 5 sec bar lookback-autocorrection like tws does?
last_price_sticky = chart._ysticks[chart.name] last_price_sticky = chart._ysticks[chart.name]
def maxmin():
array = chart._array
last_bars_range = chart.bars_range()
l, lbar, rbar, r = last_bars_range
in_view = array[lbar:rbar]
mx, mn = np.nanmax(in_view['high']), np.nanmin(in_view['low'])
return last_bars_range, mx, mn
last_bars_range, last_mx, last_mn = maxmin()
async for quotes in stream: async for quotes in stream:
for sym, quote in quotes.items(): for sym, quote in quotes.items():
for tick in iterticks(quote, type='trade'): for tick in iterticks(quote, type='trade'):
# TODO:
# - eventually we'll want to update bid/ask labels and
# other data as subscribed by underlying UI consumers.
# - in theory we should be able to read buffer data
# faster then msgs arrive.. needs some tinkering and
# testing
array = ohlcv.array array = ohlcv.array
chart.update_from_array( chart.update_from_array(
chart.name, chart.name,
@ -722,12 +726,27 @@ async def chart_from_quotes(
# update sticky(s) # update sticky(s)
last = array[-1] last = array[-1]
last_price_sticky.update_from_data(*last[['index', 'close']]) last_price_sticky.update_from_data(*last[['index', 'close']])
chart._set_yrange()
# TODO: we need a streaming minmax algorithm here to
brange, mx, mn = maxmin()
if brange != last_bars_range:
if mx > last_mx or mn < last_mn:
# avoid running this every cycle.
chart._set_yrange()
# save for next cycle
last_mx, last_mn = mx, mn
if vwap_in_history: if vwap_in_history:
# update vwap overlay line # update vwap overlay line
chart.update_from_array('vwap', ohlcv.array['vwap']) chart.update_from_array('vwap', ohlcv.array['vwap'])
# TODO:
# - eventually we'll want to update bid/ask labels and
# other data as subscribed by underlying UI consumers.
# - in theory we should be able to read buffer data
# faster then msgs arrive.. needs some tinkering and testing
async def chart_from_fsp( async def chart_from_fsp(
linked_charts, linked_charts,
@ -830,7 +849,7 @@ async def check_for_new_bars(feed, ohlcv, linked_charts):
# just_history=True # just_history=True
) )
# resize view # resize view
price_chart._set_yrange() # price_chart._set_yrange()
for name, curve in price_chart._overlays.items(): for name, curve in price_chart._overlays.items():
# TODO: standard api for signal lookups per plot # TODO: standard api for signal lookups per plot
@ -843,7 +862,7 @@ async def check_for_new_bars(feed, ohlcv, linked_charts):
for name, chart in linked_charts.subplots.items(): for name, chart in linked_charts.subplots.items():
chart.update_from_array(chart.name, chart._shm.array[chart.name]) chart.update_from_array(chart.name, chart._shm.array[chart.name])
chart._set_yrange() # chart._set_yrange()
def _main( def _main(