Draw flat line on every new time step

Until we get a better datum "cursor" figured out just draw the flat bar
despite the extra overhead. The reason to do this in 2 separate calls is
detailed in the comment but basic gist is that there's a race between
writer and reader of the last shm index.

Oh, and toss in some draft symbol search label code.
bar_select
Tyler Goodlet 2020-11-03 12:25:08 -05:00
parent d92e02db86
commit e65f511648
1 changed files with 67 additions and 14 deletions

View File

@ -53,18 +53,37 @@ class ChartSpace(QtGui.QWidget):
""" """
def __init__(self, parent=None): def __init__(self, parent=None):
super().__init__(parent) super().__init__(parent)
self.v_layout = QtGui.QVBoxLayout(self) self.v_layout = QtGui.QVBoxLayout(self)
self.v_layout.setContentsMargins(0, 0, 0, 0) self.v_layout.setContentsMargins(0, 0, 0, 0)
self.v_layout.setSpacing(0)
self.toolbar_layout = QtGui.QHBoxLayout() self.toolbar_layout = QtGui.QHBoxLayout()
self.toolbar_layout.setContentsMargins(5, 5, 10, 0) self.toolbar_layout.setContentsMargins(0, 0, 0, 0)
self.h_layout = QtGui.QHBoxLayout() self.h_layout = QtGui.QHBoxLayout()
self.h_layout.setContentsMargins(0, 0, 0, 0)
# self.init_timeframes_ui() # self.init_timeframes_ui()
# self.init_strategy_ui() # self.init_strategy_ui()
self.v_layout.addLayout(self.toolbar_layout) self.v_layout.addLayout(self.toolbar_layout)
self.v_layout.addLayout(self.h_layout) self.v_layout.addLayout(self.h_layout)
self._chart_cache = {} self._chart_cache = {}
self.symbol_label: Optional[QtGui.QLabel] = None
def init_search(self):
self.symbol_label = label = QtGui.QLabel()
label.setTextFormat(3) # markdown
label.setFont(_font.font)
label.setMargin(0)
# title = f'sym: {self.symbol}'
# label.setText(title)
label.setAlignment(
QtCore.Qt.AlignVCenter
| QtCore.Qt.AlignLeft
)
self.v_layout.addWidget(label)
def init_timeframes_ui(self): def init_timeframes_ui(self):
self.tf_layout = QtGui.QHBoxLayout() self.tf_layout = QtGui.QHBoxLayout()
@ -95,6 +114,15 @@ class ChartSpace(QtGui.QWidget):
""" """
# XXX: let's see if this causes mem problems # XXX: let's see if this causes mem problems
self.window.setWindowTitle(f'piker chart {symbol}') self.window.setWindowTitle(f'piker chart {symbol}')
# TODO: symbol search
# # of course this doesn't work :eyeroll:
# h = _font.boundingRect('Ag').height()
# print(f'HEIGHT {h}')
# self.symbol_label.setFixedHeight(h + 4)
# self.v_layout.update()
# self.symbol_label.setText(f'/`{symbol}`')
linkedcharts = self._chart_cache.setdefault( linkedcharts = self._chart_cache.setdefault(
symbol, symbol,
LinkedSplitCharts() LinkedSplitCharts()
@ -102,11 +130,12 @@ class ChartSpace(QtGui.QWidget):
s = Symbol(key=symbol) s = Symbol(key=symbol)
# remove any existing plots # remove any existing plots
if not self.h_layout.isEmpty(): if not self.v_layout.isEmpty():
self.h_layout.removeWidget(linkedcharts) self.v_layout.removeWidget(linkedcharts)
main_chart = linkedcharts.plot_main(s, data) main_chart = linkedcharts.plot_main(s, data)
self.h_layout.addWidget(linkedcharts) self.v_layout.addWidget(linkedcharts)
return linkedcharts, main_chart return linkedcharts, main_chart
# TODO: add signalling painter system # TODO: add signalling painter system
@ -154,7 +183,7 @@ class LinkedSplitCharts(QtGui.QWidget):
# 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(2)
self.splitter.setHandleWidth(0) self.splitter.setHandleWidth(0)
self.layout = QtGui.QVBoxLayout(self) self.layout = QtGui.QVBoxLayout(self)
@ -247,10 +276,10 @@ class LinkedSplitCharts(QtGui.QWidget):
# graphics curve managed by the subchart # graphics curve managed by the subchart
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.hideButtons() cpw.hideButtons()
# XXX: gives us outline on backside of y-axis
cpw.getPlotItem().setContentsMargins(*CHART_MARGINS)
# link chart x-axis to main quotes chart # link chart x-axis to main quotes chart
cpw.setXLink(self.chart) cpw.setXLink(self.chart)
@ -312,6 +341,7 @@ class ChartPlotWidget(pg.PlotWidget):
# antialias=True, # antialias=True,
**kwargs **kwargs
) )
# self.setViewportMargins(0, 0, 0, 0)
self._array = array # readonly view of data self._array = array # readonly view of data
self._graphics = {} # registry of underlying graphics self._graphics = {} # registry of underlying graphics
self._overlays = {} # registry of overlay curves self._overlays = {} # registry of overlay curves
@ -662,6 +692,8 @@ async def _async_main(
# attempt to configure DPI aware font size # attempt to configure DPI aware font size
_font.configure_to_dpi(current_screen()) _font.configure_to_dpi(current_screen())
# chart_app.init_search()
# from ._exec import get_screen # from ._exec import get_screen
# screen = get_screen(chart_app.geometry().bottomRight()) # screen = get_screen(chart_app.geometry().bottomRight())
@ -928,15 +960,36 @@ async def check_for_new_bars(feed, ohlcv, linked_charts):
async for index in await feed.index_stream(): async for index in await feed.index_stream():
# update chart historical bars graphics # update chart historical bars graphics by incrementing
# a time step and drawing the history and new bar
# When appending a new bar, in the time between the insert # When appending a new bar, in the time between the insert
# here and the Qt render call the underlying price data may # from the writing process and the Qt render call, here,
# have already been updated, thus make sure to also update # the index of the shm buffer may be incremented and the
# the last bar if necessary on this render cycle which is # (render) call here might read the new flat bar appended
# why we **don't** set: just_history=True # to the buffer (since -1 index read). In that case H==L and the
# body will be set as None (not drawn) on what this render call
# *thinks* is the curent bar (even though it's reading data from
# the newly inserted flat bar.
#
# HACK: We need to therefore write only the history (not the
# current bar) and then either write the current bar manually
# or place a cursor for visual cue of the current time step.
price_chart.update_ohlc_from_array( price_chart.update_ohlc_from_array(
price_chart.name, ohlcv.array, just_history=True) price_chart.name,
ohlcv.array,
just_history=True,
)
# XXX: this puts a flat bar on the current time step
# TODO: if we eventually have an x-axis time-step "cursor"
# we can get rid of this since it is extra overhead.
price_chart.update_ohlc_from_array(
price_chart.name,
ohlcv.array,
just_history=False,
)
# resize view # resize view
# price_chart._set_yrange() # price_chart._set_yrange()