Compare commits

...

7 Commits

Author SHA1 Message Date
Tyler Goodlet 73f1a58038 TOSQUASH `._lc` renamings 2021-09-06 10:07:42 -04:00
Tyler Goodlet 5698ac9a78 It's a map of symbols to first quote dicts 2021-09-06 09:51:56 -04:00
Tyler Goodlet 5dc2f93a7e Handle race with order-request-ack msg 2021-09-06 09:50:49 -04:00
Tyler Goodlet 1d1b13bce0 No longer feed specific 2021-09-06 09:49:31 -04:00
Tyler Goodlet 24c3f84496 Assign unique shm keys for duplicate fsps to avoid array clobbering 2021-09-06 09:48:20 -04:00
Tyler Goodlet 829820060f Move DPI / screen get logging to debug; reduce cli noise 2021-09-06 09:38:14 -04:00
Tyler Goodlet 9fc46fd40d Drop all `ChartPlotWidget._lc` remap to `.linked 2021-09-06 09:37:32 -04:00
12 changed files with 37 additions and 40 deletions

View File

@ -140,7 +140,7 @@ async def maybe_open_ctx(
yield True, value yield True, value
except KeyError: except KeyError:
log.info(f'Allocating new feed for {key}') log.info(f'Allocating new resource for {key}')
# **critical section** that should prevent other tasks from # **critical section** that should prevent other tasks from
# checking the cache until complete otherwise the scheduler # checking the cache until complete otherwise the scheduler

View File

@ -576,7 +576,8 @@ async def translate_and_relay_brokerd_events(
# cancelled by the ems controlling client before we # cancelled by the ems controlling client before we
# received this ack, in which case we relay that cancel # received this ack, in which case we relay that cancel
# signal **asap** to the backend broker # signal **asap** to the backend broker
if entry.action == 'cancel': action = getattr(entry, 'action', None)
if action and action == 'cancel':
# assign newly providerd broker backend request id # assign newly providerd broker backend request id
entry.reqid = reqid entry.reqid = reqid
@ -966,10 +967,10 @@ async def _emsd_main(
): ):
# XXX: this should be initial price quote from target provider # XXX: this should be initial price quote from target provider
first_quote = feed.first_quote first_quote = feed.first_quotes[symbol]
book = _router.get_dark_book(broker) book = _router.get_dark_book(broker)
book.lasts[(broker, symbol)] = first_quote[symbol]['last'] book.lasts[(broker, symbol)] = first_quote['last']
# open a stream with the brokerd backend for order # open a stream with the brokerd backend for order
# flow dialogue # flow dialogue

View File

@ -1,5 +1,5 @@
# piker: trading gear for hackers # piker: trading gear for hackers
# Copyright (C) 2018-present Tyler Goodlet (in stewardship of piker0) # Copyright (C) 2018-present Tyler Goodlet (in stewardship for piker0)
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by # it under the terms of the GNU Affero General Public License as published by

View File

@ -192,7 +192,7 @@ async def allocate_persistent_feed(
# establish broker backend quote stream # establish broker backend quote stream
# ``stream_quotes()`` is a required backend func # ``stream_quotes()`` is a required backend func
init_msg, first_quote = await bus.nursery.start( init_msg, first_quotes = await bus.nursery.start(
partial( partial(
mod.stream_quotes, mod.stream_quotes,
send_chan=send, send_chan=send,
@ -212,7 +212,7 @@ async def allocate_persistent_feed(
# XXX: the ``symbol`` here is put into our native piker format (i.e. # XXX: the ``symbol`` here is put into our native piker format (i.e.
# lower case). # lower case).
bus.feeds[symbol.lower()] = (cs, init_msg, first_quote) bus.feeds[symbol.lower()] = (cs, init_msg, first_quotes)
if opened: if opened:
# start history backfill task ``backfill_bars()`` is # start history backfill task ``backfill_bars()`` is
@ -227,7 +227,7 @@ async def allocate_persistent_feed(
init_msg[symbol]['sample_rate'] = int(delay_s) init_msg[symbol]['sample_rate'] = int(delay_s)
# yield back control to starting nursery # yield back control to starting nursery
task_status.started((init_msg, first_quote)) task_status.started((init_msg, first_quotes))
await feed_is_live.wait() await feed_is_live.wait()
@ -277,7 +277,7 @@ async def attach_feed_bus(
# service nursery # service nursery
async with bus.task_lock: async with bus.task_lock:
if entry is None: if entry is None:
init_msg, first_quote = await bus.nursery.start( init_msg, first_quotes = await bus.nursery.start(
partial( partial(
allocate_persistent_feed, allocate_persistent_feed,
@ -294,13 +294,13 @@ async def attach_feed_bus(
) )
assert isinstance(bus.feeds[symbol], tuple) assert isinstance(bus.feeds[symbol], tuple)
# XXX: ``first_quote`` may be outdated here if this is secondary # XXX: ``first_quotes`` may be outdated here if this is secondary
# subscriber # subscriber
cs, init_msg, first_quote = bus.feeds[symbol] cs, init_msg, first_quotes = bus.feeds[symbol]
# send this even to subscribers to existing feed? # send this even to subscribers to existing feed?
# deliver initial info message a first quote asap # deliver initial info message a first quote asap
await ctx.started((init_msg, first_quote)) await ctx.started((init_msg, first_quotes))
async with ( async with (
ctx.open_stream() as stream, ctx.open_stream() as stream,
@ -392,7 +392,7 @@ class Feed:
name: str name: str
shm: ShmArray shm: ShmArray
mod: ModuleType mod: ModuleType
first_quote: dict first_quotes: dict # symbol names to first quote dicts
stream: trio.abc.ReceiveChannel[dict[str, Any]] stream: trio.abc.ReceiveChannel[dict[str, Any]]
_brokerd_portal: tractor._portal.Portal _brokerd_portal: tractor._portal.Portal
@ -509,7 +509,7 @@ async def open_feed(
tick_throttle=tick_throttle, tick_throttle=tick_throttle,
) as (ctx, (init_msg, first_quote)), ) as (ctx, (init_msg, first_quotes)),
ctx.open_stream() as stream, ctx.open_stream() as stream,
@ -524,7 +524,7 @@ async def open_feed(
name=brokername, name=brokername,
shm=shm, shm=shm,
mod=mod, mod=mod,
first_quote=first_quote, first_quotes=first_quotes,
stream=stream, stream=stream,
_brokerd_portal=portal, _brokerd_portal=portal,
) )

View File

@ -280,14 +280,13 @@ class LinkedSplits(QtWidgets.QWidget):
# self.xaxis.hide() # self.xaxis.hide()
self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical) self.splitter = QtWidgets.QSplitter(QtCore.Qt.Vertical)
self.splitter.setMidLineWidth(2) self.splitter.setMidLineWidth(1)
self.splitter.setHandleWidth(0) self.splitter.setHandleWidth(0)
self.layout = QtWidgets.QVBoxLayout(self) self.layout = QtWidgets.QVBoxLayout(self)
self.layout.setContentsMargins(0, 0, 0, 0) self.layout.setContentsMargins(0, 0, 0, 0)
self.layout.addWidget(self.splitter) self.layout.addWidget(self.splitter)
# state tracker?
self._symbol: Symbol = None self._symbol: Symbol = None
@property @property
@ -491,7 +490,6 @@ class ChartPlotWidget(pg.PlotWidget):
**kwargs **kwargs
) )
self.name = name self.name = name
self._lc = linkedsplits
self.linked = linkedsplits self.linked = linkedsplits
# scene-local placeholder for book graphics # scene-local placeholder for book graphics
@ -733,7 +731,7 @@ class ChartPlotWidget(pg.PlotWidget):
# if the sticky is for our symbol # if the sticky is for our symbol
# use the tick size precision for display # use the tick size precision for display
sym = self._lc.symbol sym = self.linked.symbol
if name == sym.key: if name == sym.key:
digits = sym.digits() digits = sym.digits()
else: else:
@ -983,7 +981,7 @@ async def chart_from_quotes(
last, volume = ohlcv.array[-1][['close', 'volume']] last, volume = ohlcv.array[-1][['close', 'volume']]
symbol = chart._lc.symbol symbol = chart.linked.symbol
l1 = L1Labels( l1 = L1Labels(
chart, chart,
@ -1001,7 +999,7 @@ async def chart_from_quotes(
# levels this might be dark volume we need to # levels this might be dark volume we need to
# present differently? # present differently?
tick_size = chart._lc.symbol.tick_size tick_size = chart.linked.symbol.tick_size
tick_margin = 2 * tick_size tick_margin = 2 * tick_size
last_ask = last_bid = last_clear = time.time() last_ask = last_bid = last_clear = time.time()
@ -1010,7 +1008,7 @@ async def chart_from_quotes(
async for quotes in stream: async for quotes in stream:
# chart isn't actively shown so just skip render cycle # chart isn't actively shown so just skip render cycle
if chart._lc.isHidden(): if chart.linked.isHidden():
continue continue
for sym, quote in quotes.items(): for sym, quote in quotes.items():
@ -1154,6 +1152,8 @@ async def spawn_fsps(
linkedsplits.focus() linkedsplits.focus()
uid = tractor.current_actor().uid
# spawns sub-processes which execute cpu bound FSP code # spawns sub-processes which execute cpu bound FSP code
async with tractor.open_nursery(loglevel=loglevel) as n: async with tractor.open_nursery(loglevel=loglevel) as n:
@ -1174,7 +1174,7 @@ async def spawn_fsps(
# TODO: should `index` be a required internal field? # TODO: should `index` be a required internal field?
fsp_dtype = np.dtype([('index', int), (fsp_func_name, float)]) fsp_dtype = np.dtype([('index', int), (fsp_func_name, float)])
key = f'{sym}.' + display_name key = f'{sym}.fsp.{display_name}.{".".join(uid)}'
# this is all sync currently # this is all sync currently
shm, opened = maybe_open_shm_array( shm, opened = maybe_open_shm_array(
@ -1184,9 +1184,10 @@ async def spawn_fsps(
readonly=True, readonly=True,
) )
# XXX: fsp may have been opened by a duplicate chart. Error for # XXX: fsp may have been opened by a duplicate chart.
# now until we figure out how to wrap fsps as "feeds". # Error for now until we figure out how to wrap fsps as
# assert opened, f"A chart for {key} likely already exists?" # "feeds". assert opened, f"A chart for {key} likely
# already exists?"
conf['shm'] = shm conf['shm'] = shm
@ -1300,7 +1301,7 @@ async def run_fsp(
value = array[fsp_func_name][-1] value = array[fsp_func_name][-1]
last_val_sticky.update_from_data(-1, value) last_val_sticky.update_from_data(-1, value)
chart._lc.focus() chart.linked.focus()
# works also for overlays in which case data is looked up from # works also for overlays in which case data is looked up from
# internal chart array set.... # internal chart array set....
@ -1335,7 +1336,7 @@ async def run_fsp(
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._lc.isHidden(): if chart.linked.isHidden():
continue continue
now = time.time() now = time.time()

View File

@ -118,7 +118,7 @@ class LineEditor:
chart = cursor.active_plot chart = cursor.active_plot
y = cursor._datum_xy[1] y = cursor._datum_xy[1]
symbol = chart._lc.symbol symbol = chart.linked.symbol
# add a "staged" cursor-tracking line to view # add a "staged" cursor-tracking line to view
# and cash it in a a var # and cash it in a a var
@ -194,7 +194,7 @@ class LineEditor:
if not line: if not line:
raise RuntimeError("No line is currently staged!?") raise RuntimeError("No line is currently staged!?")
sym = chart._lc.symbol sym = chart.linked.symbol
line = order_line( line = order_line(
chart, chart,

View File

@ -115,7 +115,7 @@ async def handle_viewmode_inputs(
Qt.Key_Space, Qt.Key_Space,
} }
): ):
view._chart._lc.godwidget.search.focus() view._chart.linked.godwidget.search.focus()
# esc and ctrl-c # esc and ctrl-c
if key == Qt.Key_Escape or (ctrl and key == Qt.Key_C): if key == Qt.Key_Escape or (ctrl and key == Qt.Key_C):

View File

@ -210,9 +210,6 @@ class Label:
assert s_xy == self.txt.pos() assert s_xy == self.txt.pos()
def orient_on(self, h: str, v: str) -> None:
pass
@property @property
def fmt_str(self) -> str: def fmt_str(self) -> str:
return self._fmt_str return self._fmt_str

View File

@ -114,9 +114,7 @@ class LevelLine(pg.InfiniteLine):
self._on_drag_start = lambda l: None self._on_drag_start = lambda l: None
self._on_drag_end = lambda l: None self._on_drag_end = lambda l: None
self._y_incr_mult = 1 / chart._lc._symbol.tick_size self._y_incr_mult = 1 / chart.linked.symbol.tick_size
self._last_scene_y: float = 0
self._right_end_sc: float = 0 self._right_end_sc: float = 0
def txt_offsets(self) -> Tuple[int, int]: def txt_offsets(self) -> Tuple[int, int]:

View File

@ -121,7 +121,7 @@ class DpiAwareFont:
self._font_inches = inches self._font_inches = inches
font_size = math.floor(inches * dpi) font_size = math.floor(inches * dpi)
log.info( log.debug(
f"\nscreen:{screen.name()} with pDPI: {pdpi}, lDPI: {ldpi}" f"\nscreen:{screen.name()} with pDPI: {pdpi}, lDPI: {ldpi}"
f"\nOur best guess font size is {font_size}\n" f"\nOur best guess font size is {font_size}\n"
) )

View File

@ -230,7 +230,7 @@ class MainWindow(QtGui.QMainWindow):
for _ in range(3): for _ in range(3):
screen = app.screenAt(self.pos()) screen = app.screenAt(self.pos())
print('trying to access QScreen...') log.debug('trying to access QScreen...')
if screen is None: if screen is None:
time.sleep(0.5) time.sleep(0.5)
continue continue

View File

@ -112,7 +112,7 @@ class OrderMode:
) -> None: ) -> None:
print(f'Position update {msg}') print(f'Position update {msg}')
sym = self.chart._lc._symbol sym = self.chart.linked.symbol
if msg['symbol'].lower() not in sym.key: if msg['symbol'].lower() not in sym.key:
return return