Add a `ChartnPane` composite for every symbol

fsp_feeds
Tyler Goodlet 2021-08-23 14:48:53 -04:00
parent 206af0d575
commit c4d5ca008e
1 changed files with 79 additions and 59 deletions

View File

@ -201,7 +201,7 @@ class GodWidget(QWidget):
# XXX: pretty sure we don't need this # XXX: pretty sure we don't need this
# remove any existing plots? # remove any existing plots?
# XXX: ahh we might want to support cache unloading.. # XXX: ahh we might want to support cache unloading..
self.vbox.removeWidget(self.linkedsplits) # self.vbox.removeWidget(self.linkedsplits)
# switching to a new viewable chart # switching to a new viewable chart
if linkedsplits is None or reset: if linkedsplits is None or reset:
@ -231,13 +231,13 @@ class GodWidget(QWidget):
# XXX: since the pp config is a singleton widget we have to # XXX: since the pp config is a singleton widget we have to
# also switch it over to the new chart's interal-layout # also switch it over to the new chart's interal-layout
self.linkedsplits.chart.qframe.hbox.removeWidget(self.pp_pane) # self.linkedsplits.chart.qframe.hbox.removeWidget(self.pp_pane)
chart = linkedsplits.chart chart = linkedsplits.chart
await chart.resume_all_feeds() await chart.resume_all_feeds()
chart.qframe.hbox.addWidget( # chart.qframe.hbox.addWidget(
self.pp_pane, # self.pp_pane,
alignment=Qt.AlignTop # alignment=Qt.AlignTop
) # )
# chart is already in memory so just focus it # chart is already in memory so just focus it
if self.linkedsplits: if self.linkedsplits:
@ -271,6 +271,39 @@ class GodWidget(QWidget):
self.linkedsplits.chart.setFocus() self.linkedsplits.chart.setFocus()
class ChartnPane(QFrame):
'''One-off ``QFrame`` composite which pairs a chart
+ sidepane (often a ``FieldsForm`` + other widgets if
provided) forming a, sort of, "chart row" with a side panel
for configuration and display of off-chart data.
See composite widgets docs for deats:
https://doc.qt.io/qt-5/qwidget.html#composite-widgets
'''
sidepane: FieldsForm
hbox: QtGui.QHBoxLayout
chart: Optional['ChartPlotWidget'] = None
def __init__(
self,
sidepane: FieldsForm,
parent=None,
) -> None:
super().__init__(parent)
self.sidepane = sidepane
self.chart = None
hbox = self.hbox = QtGui.QHBoxLayout(self)
hbox.setAlignment(Qt.AlignTop | Qt.AlignLeft)
hbox.setContentsMargins(0, 0, 0, 0)
hbox.setSpacing(3)
class LinkedSplits(QWidget): class LinkedSplits(QWidget):
''' '''
Widget that holds a central chart plus derived Widget that holds a central chart plus derived
@ -333,7 +366,7 @@ class LinkedSplits(QWidget):
def set_split_sizes( def set_split_sizes(
self, self,
prop: float = 0.625 # proportion allocated to consumer subcharts prop: float = 0.375 # proportion allocated to consumer subcharts
) -> None: ) -> None:
'''Set the proportion of space allocated for linked subcharts. '''Set the proportion of space allocated for linked subcharts.
@ -360,6 +393,7 @@ class LinkedSplits(QWidget):
symbol: Symbol, symbol: Symbol,
array: np.ndarray, array: np.ndarray,
sidepane: FieldsForm,
style: str = 'bar', style: str = 'bar',
@ -382,7 +416,7 @@ class LinkedSplits(QWidget):
style=style, style=style,
_is_main=True, _is_main=True,
sidepane=self.godwidget.pp_pane, sidepane=sidepane,
) )
# add crosshair graphic # add crosshair graphic
self.chart.addItem(self.cursor) self.chart.addItem(self.cursor)
@ -442,35 +476,7 @@ class LinkedSplits(QWidget):
self.xaxis.hide() self.xaxis.hide()
self.xaxis = xaxis self.xaxis = xaxis
# TODO: probably should formalize and call this something else? qframe = ChartnPane(sidepane=sidepane, parent=self.splitter)
class ChartnPane(QFrame):
'''One-off ``QFrame`` composite which pairs a chart + sidepane
``FieldsForm`` (if provided).
See composite widgets docs for deats:
https://doc.qt.io/qt-5/qwidget.html#composite-widgets
'''
sidepane: FieldsForm
hbox: QtGui.QHBoxLayout
chart: Optional['ChartPlotWidget'] = None
def __init__(
self,
parent=None,
) -> None:
super().__init__(parent)
self.sidepane = sidepane
hbox = self.hbox = QtGui.QHBoxLayout(self)
hbox.setAlignment(Qt.AlignTop | Qt.AlignLeft)
hbox.setContentsMargins(0, 0, 0, 0)
hbox.setSpacing(3)
qframe = ChartnPane(self.splitter)
cpw = ChartPlotWidget( cpw = ChartPlotWidget(
@ -500,7 +506,6 @@ class LinkedSplits(QWidget):
assert cpw.parent() == qframe assert cpw.parent() == qframe
# add sidepane **after** chart; place it on axis side # add sidepane **after** chart; place it on axis side
if sidepane:
qframe.hbox.addWidget( qframe.hbox.addWidget(
sidepane, sidepane,
alignment=Qt.AlignTop alignment=Qt.AlignTop
@ -1401,10 +1406,6 @@ async def run_fsp(
period: int period: int
sidepane: FieldsForm = mk_form( sidepane: FieldsForm = mk_form(
model=FspConfig(
name=display_name,
period=14,
),
parent=linkedsplits.godwidget, parent=linkedsplits.godwidget,
fields_schema={ fields_schema={
'name': { 'name': {
@ -1421,6 +1422,10 @@ async def run_fsp(
}, },
}, },
) )
sidepane.model = FspConfig(
name=display_name,
period=14,
)
async with ( async with (
portal.open_stream_from( portal.open_stream_from(
@ -1533,11 +1538,14 @@ async def run_fsp(
done() done()
i = 0
# update chart graphics # update chart graphics
async for value in stream: async for value in stream:
# chart isn't actively shown so just skip render cycle # chart isn't actively shown so just skip render cycle
if chart.linked.isHidden(): if chart.linked.isHidden():
print(f'{i} unseen fsp cyclce')
i += 1
continue continue
now = time.time() now = time.time()
@ -1709,7 +1717,18 @@ async def display_symbol_data(
linkedsplits = godwidget.linkedsplits linkedsplits = godwidget.linkedsplits
linkedsplits._symbol = symbol linkedsplits._symbol = symbol
chart = linkedsplits.plot_ohlc_main(symbol, bars) # generate order mode side-pane UI
# A ``FieldsForm`` form to configure order entry
pp_pane: FieldsForm = mk_order_pane_layout(godwidget)
# add as next-to-y-axis singleton pane
godwidget.pp_pane = pp_pane
chart = linkedsplits.plot_ohlc_main(
symbol,
bars,
sidepane=pp_pane,
)
chart._feeds[symbol.key] = feed chart._feeds[symbol.key] = feed
chart.setFocus() chart.setFocus()
@ -1771,7 +1790,11 @@ async def display_symbol_data(
}, },
}) })
async with trio.open_nursery() as n: async with (
trio.open_nursery() as n,
):
# load initial fsp chain (otherwise known as "indicators") # load initial fsp chain (otherwise known as "indicators")
n.start_soon( n.start_soon(
spawn_fsps, spawn_fsps,
@ -1876,12 +1899,6 @@ async def _async_main(
sbar = godwidget.window.status_bar sbar = godwidget.window.status_bar
starting_done = sbar.open_status('starting ze sexy chartz') starting_done = sbar.open_status('starting ze sexy chartz')
# generate order mode side-pane UI
# A ``FieldsForm`` form to configure order entry
pp_pane: FieldsForm = mk_order_pane_layout(godwidget)
# add as next-to-y-axis singleton pane
godwidget.pp_pane = pp_pane
async with ( async with (
trio.open_nursery() as root_n, trio.open_nursery() as root_n,
): ):
@ -1925,6 +1942,9 @@ async def _async_main(
await order_mode_ready.wait() await order_mode_ready.wait()
# load account names from ``brokers.toml``
# accounts = brokers.config.load_accounts()
# start handling peripherals input for top level widgets # start handling peripherals input for top level widgets
async with ( async with (
@ -1945,10 +1965,10 @@ async def _async_main(
), ),
# pp pane kb inputs # pp pane kb inputs
open_form_input_handling( # open_form_input_handling(
pp_pane, # pp_pane,
focus_next=godwidget, # focus_next=godwidget,
) # )
): ):
# remove startup status text # remove startup status text
starting_done() starting_done()