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
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
# 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
# received this ack, in which case we relay that cancel
# 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
entry.reqid = reqid
@ -966,10 +967,10 @@ async def _emsd_main(
):
# 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.lasts[(broker, symbol)] = first_quote[symbol]['last']
book.lasts[(broker, symbol)] = first_quote['last']
# open a stream with the brokerd backend for order
# flow dialogue

View File

@ -1,5 +1,5 @@
# 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
# 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
# ``stream_quotes()`` is a required backend func
init_msg, first_quote = await bus.nursery.start(
init_msg, first_quotes = await bus.nursery.start(
partial(
mod.stream_quotes,
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.
# lower case).
bus.feeds[symbol.lower()] = (cs, init_msg, first_quote)
bus.feeds[symbol.lower()] = (cs, init_msg, first_quotes)
if opened:
# start history backfill task ``backfill_bars()`` is
@ -227,7 +227,7 @@ async def allocate_persistent_feed(
init_msg[symbol]['sample_rate'] = int(delay_s)
# 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()
@ -277,7 +277,7 @@ async def attach_feed_bus(
# service nursery
async with bus.task_lock:
if entry is None:
init_msg, first_quote = await bus.nursery.start(
init_msg, first_quotes = await bus.nursery.start(
partial(
allocate_persistent_feed,
@ -294,13 +294,13 @@ async def attach_feed_bus(
)
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
cs, init_msg, first_quote = bus.feeds[symbol]
cs, init_msg, first_quotes = bus.feeds[symbol]
# send this even to subscribers to existing feed?
# deliver initial info message a first quote asap
await ctx.started((init_msg, first_quote))
await ctx.started((init_msg, first_quotes))
async with (
ctx.open_stream() as stream,
@ -392,7 +392,7 @@ class Feed:
name: str
shm: ShmArray
mod: ModuleType
first_quote: dict
first_quotes: dict # symbol names to first quote dicts
stream: trio.abc.ReceiveChannel[dict[str, Any]]
_brokerd_portal: tractor._portal.Portal
@ -509,7 +509,7 @@ async def open_feed(
tick_throttle=tick_throttle,
) as (ctx, (init_msg, first_quote)),
) as (ctx, (init_msg, first_quotes)),
ctx.open_stream() as stream,
@ -524,7 +524,7 @@ async def open_feed(
name=brokername,
shm=shm,
mod=mod,
first_quote=first_quote,
first_quotes=first_quotes,
stream=stream,
_brokerd_portal=portal,
)

View File

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

View File

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

View File

@ -115,7 +115,7 @@ async def handle_viewmode_inputs(
Qt.Key_Space,
}
):
view._chart._lc.godwidget.search.focus()
view._chart.linked.godwidget.search.focus()
# esc and ctrl-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()
def orient_on(self, h: str, v: str) -> None:
pass
@property
def fmt_str(self) -> 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_end = lambda l: None
self._y_incr_mult = 1 / chart._lc._symbol.tick_size
self._last_scene_y: float = 0
self._y_incr_mult = 1 / chart.linked.symbol.tick_size
self._right_end_sc: float = 0
def txt_offsets(self) -> Tuple[int, int]:

View File

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

View File

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

View File

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