Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi symbol input (support) #449

Merged
merged 13 commits into from
Feb 9, 2023
5 changes: 2 additions & 3 deletions piker/data/feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -1037,12 +1037,11 @@ async def allocate_persistent_feed(

flume = Flume(
symbol=symbol,
_hist_shm_token=hist_shm.token,
_rt_shm_token=rt_shm.token,
first_quote=first_quote,
_rt_shm_token=rt_shm.token,
_hist_shm_token=hist_shm.token,
izero_hist=izero_hist,
izero_rt=izero_rt,
# throttle_rate=tick_throttle,
)

# for ambiguous names we simply apply the retreived
Expand Down
120 changes: 51 additions & 69 deletions piker/ui/_chart.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
QVBoxLayout,
QSplitter,
)
import numpy as np
import pyqtgraph as pg
import trio

Expand All @@ -63,7 +62,10 @@
_xaxis_at,
_min_points_to_show,
)
from ..data.feed import Feed
from ..data.feed import (
Feed,
Flume,
)
from ..data._source import Symbol
from ..log import get_logger
from ._interaction import ChartView
Expand Down Expand Up @@ -538,6 +540,7 @@ def plot_ohlc_main(

symbol: Symbol,
shm: ShmArray,
flume: Flume,
sidepane: FieldsForm,

style: str = 'ohlc_bar',
Expand All @@ -562,6 +565,7 @@ def plot_ohlc_main(
self.chart = self.add_plot(
name=symbol.fqsn,
shm=shm,
flume=flume,
style=style,
_is_main=True,
sidepane=sidepane,
Expand All @@ -582,6 +586,7 @@ def add_plot(

name: str,
shm: ShmArray,
flume: Flume,

array_key: Optional[str] = None,
style: str = 'line',
Expand Down Expand Up @@ -705,9 +710,11 @@ def add_plot(
# draw curve graphics
if style == 'ohlc_bar':

graphics, data_key = cpw.draw_ohlc(
# graphics, data_key = cpw.draw_ohlc(
flow = cpw.draw_ohlc(
name,
shm,
flume=flume,
array_key=array_key
)
self.cursor.contents_labels.add_label(
Expand All @@ -719,18 +726,22 @@ def add_plot(

elif style == 'line':
add_label = True
graphics, data_key = cpw.draw_curve(
# graphics, data_key = cpw.draw_curve(
flow = cpw.draw_curve(
name,
shm,
flume,
array_key=array_key,
color='default_light',
)

elif style == 'step':
add_label = True
graphics, data_key = cpw.draw_curve(
# graphics, data_key = cpw.draw_curve(
flow = cpw.draw_curve(
name,
shm,
flume,
array_key=array_key,
step_mode=True,
color='davies',
Expand All @@ -740,6 +751,9 @@ def add_plot(
else:
raise ValueError(f"Chart style {style} is currently unsupported")

graphics = flow.graphics
data_key = flow.name

if _is_main:
assert style == 'ohlc_bar', 'main chart must be OHLC'
else:
Expand Down Expand Up @@ -896,7 +910,7 @@ def __init__(
# registry of overlay curve names
self._flows: dict[str, Flow] = {}

self._feeds: dict[Symbol, Feed] = {}
self.feed: Feed | None = None

self._labels = {} # registry of underlying graphics
self._ysticks = {} # registry of underlying graphics
Expand All @@ -917,20 +931,18 @@ def __init__(
self._on_screen: bool = False

def resume_all_feeds(self):
...
# try:
# for feed in self._feeds.values():
# for flume in feed.flumes.values():
# self.linked.godwidget._root_n.start_soon(flume.resume)
# except RuntimeError:
# # TODO: cancel the qtractor runtime here?
# raise
feed = self.feed
if feed:
try:
self.linked.godwidget._root_n.start_soon(feed.resume)
except RuntimeError:
# TODO: cancel the qtractor runtime here?
raise

def pause_all_feeds(self):
...
# for feed in self._feeds.values():
# for flume in feed.flumes.values():
# self.linked.godwidget._root_n.start_soon(flume.pause)
feed = self.feed
if feed:
self.linked.godwidget._root_n.start_soon(feed.pause)

@property
def view(self) -> ChartView:
Expand All @@ -939,12 +951,6 @@ def view(self) -> ChartView:
def focus(self) -> None:
self.view.setFocus()

def last_bar_in_view(self) -> int:
self._arrays[self.name][-1]['index']

def is_valid_index(self, index: int) -> bool:
return index >= 0 and index < self._arrays[self.name][-1]['index']

def _set_xlimits(
self,
xfirst: int,
Expand Down Expand Up @@ -1037,9 +1043,14 @@ def default_view(
log.warning(f'`Flow` for {self.name} not loaded yet?')
return

index = flow.shm.array['index']
arr = flow.shm.array
index = arr['index']
# times = arr['time']

# these will be epoch time floats
xfirst, xlast = index[0], index[-1]
l, lbar, rbar, r = self.bars_range()

view = self.view

if (
Expand Down Expand Up @@ -1196,6 +1207,7 @@ def draw_curve(

name: str,
shm: ShmArray,
flume: Flume,

array_key: Optional[str] = None,
overlay: bool = False,
Expand All @@ -1208,10 +1220,7 @@ def draw_curve(

**graphics_kwargs,

) -> tuple[
pg.GraphicsObject,
str,
]:
) -> Flow:
'''
Draw a "curve" (line plot graphics) for the provided data in
the input shm array ``shm``.
Expand All @@ -1226,7 +1235,6 @@ def draw_curve(
graphics = BarItems(
linked=self.linked,
plotitem=pi,
# pen_color=self.pen_color,
color=color,
name=name,
**graphics_kwargs,
Expand All @@ -1246,14 +1254,17 @@ def draw_curve(
**graphics_kwargs,
)

self._flows[data_key] = Flow(
name=name,
plot=pi,
_shm=shm,
flow = self._flows[data_key] = Flow(
data_key,
pi,
shm,
flume,

is_ohlc=is_ohlc,
# register curve graphics with this flow
graphics=graphics,
)
assert isinstance(flow.shm, ShmArray)

# TODO: this probably needs its own method?
if overlay:
Expand Down Expand Up @@ -1310,24 +1321,26 @@ def draw_curve(
# understand.
pi.addItem(graphics)

return graphics, data_key
return flow

def draw_ohlc(
self,
name: str,
shm: ShmArray,
flume: Flume,

array_key: Optional[str] = None,
**draw_curve_kwargs,

) -> (pg.GraphicsObject, str):
) -> Flow:
'''
Draw OHLC datums to chart.

'''
return self.draw_curve(
name=name,
shm=shm,
name,
shm,
flume,
array_key=array_key,
is_ohlc=True,
**draw_curve_kwargs,
Expand Down Expand Up @@ -1392,37 +1405,6 @@ def leaveEvent(self, ev): # noqa
self.sig_mouse_leave.emit(self)
self.scene().leaveEvent(ev)

def get_index(self, time: float) -> int:

# TODO: this should go onto some sort of
# data-view thinger..right?
ohlc = self._flows[self.name].shm.array

# XXX: not sure why the time is so off here
# looks like we're gonna have to do some fixing..
indexes = ohlc['time'] >= time

if any(indexes):
return ohlc['index'][indexes][-1]
else:
return ohlc['index'][-1]

def in_view(
self,
array: np.ndarray,

) -> np.ndarray:
'''
Slice an input struct array providing only datums
"in view" of this chart.

'''
l, lbar, rbar, r = self.bars_range()
ifirst = array[0]['index']
# slice data by offset from the first index
# available in the passed datum set.
return array[lbar - ifirst:(rbar - ifirst) + 1]

def maxmin(
self,
name: Optional[str] = None,
Expand Down
Loading