Add a `ChartnPane` composite for every symbol
parent
206af0d575
commit
c4d5ca008e
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue