Change over the UI layer to use `MktPair`
Including changing to `LinkedSplits.mkt: MktPair` and adding an explicit setter method for setting it and being sure that nothing breaks in the display system init! For this commit we leave in warning access to `LinkedSplits.symbol` but will remove in following commit.master
parent
39af215d61
commit
1b577eebf6
|
@ -907,7 +907,7 @@ async def open_feed(
|
||||||
|
|
||||||
for fqme, flume_msg in flumes_msg_dict.items():
|
for fqme, flume_msg in flumes_msg_dict.items():
|
||||||
flume = Flume.from_msg(flume_msg)
|
flume = Flume.from_msg(flume_msg)
|
||||||
# assert flume.symbol.fqme == fqme
|
# assert flume.mkt.fqme == fqme
|
||||||
feed.flumes[fqme] = flume
|
feed.flumes[fqme] = flume
|
||||||
|
|
||||||
# TODO: do we need this?
|
# TODO: do we need this?
|
||||||
|
|
|
@ -68,7 +68,10 @@ from ..data.feed import (
|
||||||
Feed,
|
Feed,
|
||||||
Flume,
|
Flume,
|
||||||
)
|
)
|
||||||
from ..accounting._mktinfo import Symbol
|
from ..accounting import (
|
||||||
|
MktPair,
|
||||||
|
Symbol,
|
||||||
|
)
|
||||||
from ..log import get_logger
|
from ..log import get_logger
|
||||||
from ._interaction import ChartView
|
from ._interaction import ChartView
|
||||||
from ._forms import FieldsForm
|
from ._forms import FieldsForm
|
||||||
|
@ -287,7 +290,7 @@ class GodWidget(QWidget):
|
||||||
pp_nav.hide()
|
pp_nav.hide()
|
||||||
|
|
||||||
# set window titlebar info
|
# set window titlebar info
|
||||||
symbol = self.rt_linked.symbol
|
symbol = self.rt_linked.mkt
|
||||||
if symbol is not None:
|
if symbol is not None:
|
||||||
self.window.setWindowTitle(
|
self.window.setWindowTitle(
|
||||||
f'{symbol.fqme} '
|
f'{symbol.fqme} '
|
||||||
|
@ -452,7 +455,7 @@ class LinkedSplits(QWidget):
|
||||||
# update the UI for a given "chart instance".
|
# update the UI for a given "chart instance".
|
||||||
self.display_state: DisplayState | None = None
|
self.display_state: DisplayState | None = None
|
||||||
|
|
||||||
self._symbol: Symbol = None
|
self._mkt: MktPair | Symbol = None
|
||||||
|
|
||||||
def on_splitter_adjust(
|
def on_splitter_adjust(
|
||||||
self,
|
self,
|
||||||
|
@ -474,9 +477,20 @@ class LinkedSplits(QWidget):
|
||||||
**kwargs,
|
**kwargs,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def set_mkt_info(
|
||||||
|
self,
|
||||||
|
mkt: MktPair,
|
||||||
|
) -> None:
|
||||||
|
self._mkt = mkt
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def symbol(self) -> Symbol:
|
def mkt(self) -> MktPair:
|
||||||
return self._symbol
|
return self._mkt
|
||||||
|
|
||||||
|
@property
|
||||||
|
def symbol(self) -> Symbol | MktPair:
|
||||||
|
log.warning(f'{type(self)}.symbol is now deprecated use .mkt!')
|
||||||
|
return self.mkt
|
||||||
|
|
||||||
def set_split_sizes(
|
def set_split_sizes(
|
||||||
self,
|
self,
|
||||||
|
@ -521,7 +535,7 @@ class LinkedSplits(QWidget):
|
||||||
def plot_ohlc_main(
|
def plot_ohlc_main(
|
||||||
self,
|
self,
|
||||||
|
|
||||||
symbol: Symbol,
|
mkt: MktPair,
|
||||||
shm: ShmArray,
|
shm: ShmArray,
|
||||||
flume: Flume,
|
flume: Flume,
|
||||||
sidepane: FieldsForm,
|
sidepane: FieldsForm,
|
||||||
|
@ -540,7 +554,7 @@ class LinkedSplits(QWidget):
|
||||||
# add crosshairs
|
# add crosshairs
|
||||||
self.cursor = Cursor(
|
self.cursor = Cursor(
|
||||||
linkedsplits=self,
|
linkedsplits=self,
|
||||||
digits=symbol.tick_size_digits,
|
digits=mkt.price_tick_digits,
|
||||||
)
|
)
|
||||||
|
|
||||||
# NOTE: atm the first (and only) OHLC price chart for the symbol
|
# NOTE: atm the first (and only) OHLC price chart for the symbol
|
||||||
|
@ -548,7 +562,7 @@ class LinkedSplits(QWidget):
|
||||||
# be no distinction since we will have multiple symbols per
|
# be no distinction since we will have multiple symbols per
|
||||||
# view as part of "aggregate feeds".
|
# view as part of "aggregate feeds".
|
||||||
self.chart = self.add_plot(
|
self.chart = self.add_plot(
|
||||||
name=symbol.fqme,
|
name=mkt.fqme,
|
||||||
shm=shm,
|
shm=shm,
|
||||||
flume=flume,
|
flume=flume,
|
||||||
style=style,
|
style=style,
|
||||||
|
@ -1030,7 +1044,7 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
'''
|
'''
|
||||||
view = vb or self.view
|
view = vb or self.view
|
||||||
viz = self.main_viz
|
viz = self.main_viz
|
||||||
l, r = viz.view_range()
|
left, right = viz.view_range()
|
||||||
x_shift = viz.index_step() * datums
|
x_shift = viz.index_step() * datums
|
||||||
|
|
||||||
if datums >= 300:
|
if datums >= 300:
|
||||||
|
@ -1040,8 +1054,8 @@ class ChartPlotWidget(pg.PlotWidget):
|
||||||
|
|
||||||
# should trigger broadcast on all overlays right?
|
# should trigger broadcast on all overlays right?
|
||||||
view.setXRange(
|
view.setXRange(
|
||||||
min=l + x_shift,
|
min=left + x_shift,
|
||||||
max=r + x_shift,
|
max=right + x_shift,
|
||||||
|
|
||||||
# TODO: holy shit, wtf dude... why tf would this not be 0 by
|
# TODO: holy shit, wtf dude... why tf would this not be 0 by
|
||||||
# default... speechless.
|
# default... speechless.
|
||||||
|
@ -1227,7 +1241,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
|
||||||
name = name or pi.name
|
name = name or pi.name
|
||||||
sym = self.linked.symbol
|
sym = self.linked.mkt
|
||||||
digits = None
|
digits = None
|
||||||
if name == sym.key:
|
if name == sym.key:
|
||||||
digits = sym.tick_size_digits
|
digits = sym.tick_size_digits
|
||||||
|
|
|
@ -228,7 +228,7 @@ class ContentsLabel(pg.LabelItem):
|
||||||
'bar_wap',
|
'bar_wap',
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
name=name,
|
# name=name,
|
||||||
index=ix,
|
index=ix,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -363,7 +363,7 @@ class Cursor(pg.GraphicsObject):
|
||||||
|
|
||||||
# value used for rounding y-axis discreet tick steps
|
# value used for rounding y-axis discreet tick steps
|
||||||
# computing once, up front, here cuz why not
|
# computing once, up front, here cuz why not
|
||||||
mkt = self.linked._symbol
|
mkt = self.linked.mkt
|
||||||
self._y_tick_mult = 1/float(mkt.price_tick)
|
self._y_tick_mult = 1/float(mkt.price_tick)
|
||||||
|
|
||||||
# line width in view coordinates
|
# line width in view coordinates
|
||||||
|
|
|
@ -436,12 +436,12 @@ class Viz(Struct):
|
||||||
else:
|
else:
|
||||||
if x_range is None:
|
if x_range is None:
|
||||||
(
|
(
|
||||||
l,
|
xl,
|
||||||
_,
|
_,
|
||||||
lbar,
|
lbar,
|
||||||
rbar,
|
rbar,
|
||||||
_,
|
_,
|
||||||
r,
|
xr,
|
||||||
) = self.datums_range()
|
) = self.datums_range()
|
||||||
|
|
||||||
profiler(f'{self.name} got bars range')
|
profiler(f'{self.name} got bars range')
|
||||||
|
@ -585,12 +585,12 @@ class Viz(Struct):
|
||||||
Return a range tuple for the datums present in view.
|
Return a range tuple for the datums present in view.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
l, r = view_range or self.view_range()
|
xl, xr = view_range or self.view_range()
|
||||||
|
|
||||||
index_field: str = index_field or self.index_field
|
index_field: str = index_field or self.index_field
|
||||||
if index_field == 'index':
|
if index_field == 'index':
|
||||||
l: int = round(l)
|
xl: int = round(xl)
|
||||||
r: int = round(r)
|
xr: int = round(xr)
|
||||||
|
|
||||||
if array is None:
|
if array is None:
|
||||||
array = self.shm.array
|
array = self.shm.array
|
||||||
|
@ -601,12 +601,12 @@ class Viz(Struct):
|
||||||
|
|
||||||
# invalid view state
|
# invalid view state
|
||||||
if (
|
if (
|
||||||
r < l
|
xr < xl
|
||||||
or l < 0
|
or xl < 0
|
||||||
or r < 0
|
or xr < 0
|
||||||
or (
|
or (
|
||||||
l > last
|
xl > last
|
||||||
and r > last
|
and xr > last
|
||||||
)
|
)
|
||||||
):
|
):
|
||||||
leftmost: int = first
|
leftmost: int = first
|
||||||
|
@ -616,12 +616,12 @@ class Viz(Struct):
|
||||||
# determine first and last datums in view determined by
|
# determine first and last datums in view determined by
|
||||||
# l -> r view range.
|
# l -> r view range.
|
||||||
rightmost = max(
|
rightmost = max(
|
||||||
min(last, ceil(r)),
|
min(last, ceil(xr)),
|
||||||
first,
|
first,
|
||||||
)
|
)
|
||||||
|
|
||||||
leftmost = min(
|
leftmost = min(
|
||||||
max(first, floor(l)),
|
max(first, floor(xl)),
|
||||||
last,
|
last,
|
||||||
rightmost - 1,
|
rightmost - 1,
|
||||||
)
|
)
|
||||||
|
@ -632,12 +632,12 @@ class Viz(Struct):
|
||||||
self.vs.xrange = leftmost, rightmost
|
self.vs.xrange = leftmost, rightmost
|
||||||
|
|
||||||
return (
|
return (
|
||||||
l, # left x-in-view
|
xl, # left x-in-view
|
||||||
first, # first datum
|
first, # first datum
|
||||||
leftmost,
|
leftmost,
|
||||||
rightmost,
|
rightmost,
|
||||||
last, # last_datum
|
last, # last_datum
|
||||||
r, # right-x-in-view
|
xr, # right-x-in-view
|
||||||
)
|
)
|
||||||
|
|
||||||
def read(
|
def read(
|
||||||
|
@ -665,12 +665,12 @@ class Viz(Struct):
|
||||||
profiler('self.shm.array READ')
|
profiler('self.shm.array READ')
|
||||||
|
|
||||||
(
|
(
|
||||||
l,
|
xl,
|
||||||
ifirst,
|
ifirst,
|
||||||
lbar,
|
lbar,
|
||||||
rbar,
|
rbar,
|
||||||
ilast,
|
ilast,
|
||||||
r,
|
xr,
|
||||||
) = self.datums_range(
|
) = self.datums_range(
|
||||||
index_field=index_field,
|
index_field=index_field,
|
||||||
array=array,
|
array=array,
|
||||||
|
@ -715,8 +715,8 @@ class Viz(Struct):
|
||||||
# a uniform time stamp step size?
|
# a uniform time stamp step size?
|
||||||
else:
|
else:
|
||||||
# get read-relative indices adjusting for master shm index.
|
# get read-relative indices adjusting for master shm index.
|
||||||
lbar_i = max(l, ifirst) - ifirst
|
lbar_i = max(xl, ifirst) - ifirst
|
||||||
rbar_i = min(r, ilast) - ifirst
|
rbar_i = min(xr, ilast) - ifirst
|
||||||
|
|
||||||
# NOTE: the slice here does NOT include the extra ``+ 1``
|
# NOTE: the slice here does NOT include the extra ``+ 1``
|
||||||
# BUT the ``in_view`` slice DOES..
|
# BUT the ``in_view`` slice DOES..
|
||||||
|
@ -1244,18 +1244,25 @@ class Viz(Struct):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
# get most recent right datum index in-view
|
# get most recent right datum index in-view
|
||||||
l, start, datum_start, datum_stop, stop, r = self.datums_range()
|
(
|
||||||
|
xl,
|
||||||
|
start,
|
||||||
|
datum_start,
|
||||||
|
datum_stop,
|
||||||
|
stop,
|
||||||
|
xr,
|
||||||
|
) = self.datums_range()
|
||||||
lasts = self.shm.array[-1]
|
lasts = self.shm.array[-1]
|
||||||
i_step = lasts['index'] # last index-specific step.
|
i_step = lasts['index'] # last index-specific step.
|
||||||
i_step_t = lasts['time'] # last time step.
|
i_step_t = lasts['time'] # last time step.
|
||||||
|
|
||||||
# fqme = self.flume.symbol.fqme
|
# fqme = self.flume.mkt.fqme
|
||||||
|
|
||||||
# check if "last (is) in view" -> is a real-time update necessary?
|
# check if "last (is) in view" -> is a real-time update necessary?
|
||||||
if self.index_field == 'index':
|
if self.index_field == 'index':
|
||||||
liv = (r >= i_step)
|
liv = (xr >= i_step)
|
||||||
else:
|
else:
|
||||||
liv = (r >= i_step_t)
|
liv = (xr >= i_step_t)
|
||||||
|
|
||||||
# compute the first available graphic obj's x-units-per-pixel
|
# compute the first available graphic obj's x-units-per-pixel
|
||||||
# TODO: make this not loop through all vizs each time!
|
# TODO: make this not loop through all vizs each time!
|
||||||
|
|
|
@ -37,6 +37,9 @@ import pyqtgraph as pg
|
||||||
from msgspec import field
|
from msgspec import field
|
||||||
|
|
||||||
# from .. import brokers
|
# from .. import brokers
|
||||||
|
from ..accounting import (
|
||||||
|
MktPair,
|
||||||
|
)
|
||||||
from ..data.feed import (
|
from ..data.feed import (
|
||||||
open_feed,
|
open_feed,
|
||||||
Feed,
|
Feed,
|
||||||
|
@ -319,8 +322,8 @@ async def graphics_update_loop(
|
||||||
for fqme, flume in feed.flumes.items():
|
for fqme, flume in feed.flumes.items():
|
||||||
ohlcv = flume.rt_shm
|
ohlcv = flume.rt_shm
|
||||||
hist_ohlcv = flume.hist_shm
|
hist_ohlcv = flume.hist_shm
|
||||||
symbol = flume.mkt
|
mkt = flume.mkt
|
||||||
fqme = symbol.fqme
|
fqme = mkt.fqme
|
||||||
|
|
||||||
# update last price sticky
|
# update last price sticky
|
||||||
fast_viz = fast_chart._vizs[fqme]
|
fast_viz = fast_chart._vizs[fqme]
|
||||||
|
@ -360,13 +363,13 @@ async def graphics_update_loop(
|
||||||
|
|
||||||
last, volume = ohlcv.array[-1][['close', 'volume']]
|
last, volume = ohlcv.array[-1][['close', 'volume']]
|
||||||
|
|
||||||
symbol = flume.mkt
|
mkt = flume.mkt
|
||||||
|
|
||||||
l1 = L1Labels(
|
l1 = L1Labels(
|
||||||
fast_pi,
|
fast_pi,
|
||||||
# determine precision/decimal lengths
|
# determine precision/decimal lengths
|
||||||
digits=symbol.tick_size_digits,
|
digits=mkt.price_tick_digits,
|
||||||
size_digits=symbol.lot_size_digits,
|
size_digits=mkt.size_tick_digits,
|
||||||
)
|
)
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
|
@ -449,7 +452,7 @@ async def graphics_update_loop(
|
||||||
and quote_rate >= display_rate
|
and quote_rate >= display_rate
|
||||||
):
|
):
|
||||||
pass
|
pass
|
||||||
# log.warning(f'High quote rate {symbol.key}: {quote_rate}')
|
# log.warning(f'High quote rate {mkt.fqme}: {quote_rate}')
|
||||||
|
|
||||||
last_quote_s = time.time()
|
last_quote_s = time.time()
|
||||||
|
|
||||||
|
@ -1224,7 +1227,7 @@ async def display_symbol_data(
|
||||||
# tf_key = tf_in_1s[step_size_s]
|
# tf_key = tf_in_1s[step_size_s]
|
||||||
godwidget.window.setWindowTitle(
|
godwidget.window.setWindowTitle(
|
||||||
f'{fqmes} '
|
f'{fqmes} '
|
||||||
# f'tick:{symbol.tick_size} '
|
# f'tick:{mkt.tick_size} '
|
||||||
# f'step:{tf_key} '
|
# f'step:{tf_key} '
|
||||||
)
|
)
|
||||||
# generate order mode side-pane UI
|
# generate order mode side-pane UI
|
||||||
|
@ -1234,8 +1237,8 @@ async def display_symbol_data(
|
||||||
godwidget.pp_pane = pp_pane
|
godwidget.pp_pane = pp_pane
|
||||||
|
|
||||||
# create top history view chart above the "main rt chart".
|
# create top history view chart above the "main rt chart".
|
||||||
rt_linked = godwidget.rt_linked
|
rt_linked: LinkedSplits = godwidget.rt_linked
|
||||||
hist_linked = godwidget.hist_linked
|
hist_linked: LinkedSplits = godwidget.hist_linked
|
||||||
|
|
||||||
# NOTE: here we insert the slow-history chart set into
|
# NOTE: here we insert the slow-history chart set into
|
||||||
# the fast chart's splitter -> so it's a splitter of charts
|
# the fast chart's splitter -> so it's a splitter of charts
|
||||||
|
@ -1279,17 +1282,17 @@ async def display_symbol_data(
|
||||||
|
|
||||||
# TODO NOTE: THIS CONTROLS WHAT SYMBOL IS USED FOR ORDER MODE
|
# TODO NOTE: THIS CONTROLS WHAT SYMBOL IS USED FOR ORDER MODE
|
||||||
# SUBMISSIONS, we need to make this switch based on selection.
|
# SUBMISSIONS, we need to make this switch based on selection.
|
||||||
rt_linked._symbol = flume.mkt
|
rt_linked.set_mkt_info(flume.mkt)
|
||||||
hist_linked._symbol = flume.mkt
|
hist_linked.set_mkt_info(flume.mkt)
|
||||||
|
|
||||||
ohlcv: ShmArray = flume.rt_shm
|
ohlcv: ShmArray = flume.rt_shm
|
||||||
hist_ohlcv: ShmArray = flume.hist_shm
|
hist_ohlcv: ShmArray = flume.hist_shm
|
||||||
|
|
||||||
symbol = flume.mkt
|
mkt: MktPair = flume.mkt
|
||||||
fqme = symbol.fqme
|
fqme = mkt.fqme
|
||||||
|
|
||||||
hist_chart = hist_linked.plot_ohlc_main(
|
hist_chart = hist_linked.plot_ohlc_main(
|
||||||
symbol,
|
mkt,
|
||||||
hist_ohlcv,
|
hist_ohlcv,
|
||||||
flume,
|
flume,
|
||||||
# in the case of history chart we explicitly set `False`
|
# in the case of history chart we explicitly set `False`
|
||||||
|
@ -1311,7 +1314,7 @@ async def display_symbol_data(
|
||||||
hist_linked.cursor.always_show_xlabel = False
|
hist_linked.cursor.always_show_xlabel = False
|
||||||
|
|
||||||
rt_chart = rt_linked.plot_ohlc_main(
|
rt_chart = rt_linked.plot_ohlc_main(
|
||||||
symbol,
|
mkt,
|
||||||
ohlcv,
|
ohlcv,
|
||||||
flume,
|
flume,
|
||||||
# in the case of history chart we explicitly set `False`
|
# in the case of history chart we explicitly set `False`
|
||||||
|
@ -1378,8 +1381,8 @@ async def display_symbol_data(
|
||||||
ohlcv: ShmArray = flume.rt_shm
|
ohlcv: ShmArray = flume.rt_shm
|
||||||
hist_ohlcv: ShmArray = flume.hist_shm
|
hist_ohlcv: ShmArray = flume.hist_shm
|
||||||
|
|
||||||
symbol = flume.mkt
|
mkt = flume.mkt
|
||||||
fqme = symbol.fqme
|
fqme = mkt.fqme
|
||||||
|
|
||||||
hist_pi = hist_chart.overlay_plotitem(
|
hist_pi = hist_chart.overlay_plotitem(
|
||||||
name=fqme,
|
name=fqme,
|
||||||
|
|
|
@ -29,7 +29,6 @@ from typing import (
|
||||||
Any,
|
Any,
|
||||||
)
|
)
|
||||||
|
|
||||||
import numpy as np
|
|
||||||
import msgspec
|
import msgspec
|
||||||
import tractor
|
import tractor
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
|
@ -428,7 +427,7 @@ class FspAdmin:
|
||||||
in self._flow_registry.items()
|
in self._flow_registry.items()
|
||||||
],
|
],
|
||||||
|
|
||||||
) as (ctx, last_index),
|
) as (ctx, _),
|
||||||
ctx.open_stream() as stream,
|
ctx.open_stream() as stream,
|
||||||
):
|
):
|
||||||
|
|
||||||
|
@ -486,8 +485,10 @@ class FspAdmin:
|
||||||
readonly=True,
|
readonly=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
portal = self.cluster.get(worker_name) or self.rr_next_portal()
|
portal: tractor.Portal = (
|
||||||
provider_tag = portal.channel.uid
|
self.cluster.get(worker_name)
|
||||||
|
or self.rr_next_portal()
|
||||||
|
)
|
||||||
|
|
||||||
# TODO: this should probably be turned into a
|
# TODO: this should probably be turned into a
|
||||||
# ``Cascade`` type which describes the routing
|
# ``Cascade`` type which describes the routing
|
||||||
|
|
|
@ -45,7 +45,10 @@ from ..calc import (
|
||||||
pnl,
|
pnl,
|
||||||
puterize,
|
puterize,
|
||||||
)
|
)
|
||||||
from ..accounting._allocate import Allocator
|
from ..accounting import (
|
||||||
|
Allocator,
|
||||||
|
MktPair,
|
||||||
|
)
|
||||||
from ..accounting import (
|
from ..accounting import (
|
||||||
Position,
|
Position,
|
||||||
)
|
)
|
||||||
|
@ -244,7 +247,7 @@ class SettingsPane:
|
||||||
# a ``brokerd`) then error and switch back to the last
|
# a ``brokerd`) then error and switch back to the last
|
||||||
# selection.
|
# selection.
|
||||||
if tracker is None:
|
if tracker is None:
|
||||||
sym = old_tracker.charts[0].linked.symbol.key
|
sym: str = old_tracker.charts[0].linked.mkt.fqme
|
||||||
log.error(
|
log.error(
|
||||||
f'Account `{account_name}` can not be set for {sym}'
|
f'Account `{account_name}` can not be set for {sym}'
|
||||||
)
|
)
|
||||||
|
@ -415,9 +418,10 @@ class SettingsPane:
|
||||||
|
|
||||||
'''
|
'''
|
||||||
mode = self.order_mode
|
mode = self.order_mode
|
||||||
sym = mode.chart.linked.symbol
|
mkt: MktPair = mode.chart.linked.mkt
|
||||||
size = tracker.live_pp.size
|
size = tracker.live_pp.size
|
||||||
flume: Feed = mode.feed.flumes[sym.fqme]
|
fqme: str = mkt.fqme
|
||||||
|
flume: Feed = mode.feed.flumes[fqme]
|
||||||
pnl_value = 0
|
pnl_value = 0
|
||||||
|
|
||||||
if size:
|
if size:
|
||||||
|
@ -430,7 +434,6 @@ class SettingsPane:
|
||||||
|
|
||||||
# maybe start update task
|
# maybe start update task
|
||||||
global _pnl_tasks
|
global _pnl_tasks
|
||||||
fqme = sym.fqme
|
|
||||||
if fqme not in _pnl_tasks:
|
if fqme not in _pnl_tasks:
|
||||||
_pnl_tasks[fqme] = True
|
_pnl_tasks[fqme] = True
|
||||||
self.order_mode.nursery.start_soon(
|
self.order_mode.nursery.start_soon(
|
||||||
|
@ -555,7 +558,7 @@ class Nav(Struct):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
for key, chart in self.charts.items():
|
for key, chart in self.charts.items():
|
||||||
size_digits = size_digits or chart.linked.symbol.lot_size_digits
|
size_digits = size_digits or chart.linked.mkt.size_tick_digits
|
||||||
line = self.lines.get(key)
|
line = self.lines.get(key)
|
||||||
level_marker = self.level_markers[key]
|
level_marker = self.level_markers[key]
|
||||||
pp_label = self.pp_labels[key]
|
pp_label = self.pp_labels[key]
|
||||||
|
|
|
@ -23,7 +23,10 @@ WARNING: this code likely doesn't work at all (yet)
|
||||||
"""
|
"""
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pyqtgraph as pg
|
import pyqtgraph as pg
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import (
|
||||||
|
QtCore,
|
||||||
|
QtWidgets,
|
||||||
|
)
|
||||||
|
|
||||||
from .quantdom.charts import CenteredTextItem
|
from .quantdom.charts import CenteredTextItem
|
||||||
from .quantdom.base import Quotes
|
from .quantdom.base import Quotes
|
||||||
|
|
|
@ -36,17 +36,18 @@ import trio
|
||||||
from PyQt5.QtCore import Qt
|
from PyQt5.QtCore import Qt
|
||||||
|
|
||||||
from .. import config
|
from .. import config
|
||||||
from ..accounting import Position
|
from ..accounting import (
|
||||||
from ..accounting._allocate import (
|
Allocator,
|
||||||
|
Position,
|
||||||
mk_allocator,
|
mk_allocator,
|
||||||
|
MktPair,
|
||||||
|
Symbol,
|
||||||
)
|
)
|
||||||
from ..clearing._client import (
|
from ..clearing._client import (
|
||||||
open_ems,
|
open_ems,
|
||||||
OrderClient,
|
OrderClient,
|
||||||
)
|
)
|
||||||
from ._style import _font
|
from ._style import _font
|
||||||
from ..accounting._mktinfo import Symbol
|
|
||||||
from ..accounting import MktPair
|
|
||||||
from ..data.feed import (
|
from ..data.feed import (
|
||||||
Feed,
|
Feed,
|
||||||
Flume,
|
Flume,
|
||||||
|
@ -93,7 +94,7 @@ class Dialog(Struct):
|
||||||
order: Order
|
order: Order
|
||||||
symbol: str
|
symbol: str
|
||||||
lines: list[LevelLine]
|
lines: list[LevelLine]
|
||||||
last_status_close: Callable = lambda: None
|
last_status_close: Callable | None = None
|
||||||
msgs: dict[str, dict] = {}
|
msgs: dict[str, dict] = {}
|
||||||
fills: dict[str, Any] = {}
|
fills: dict[str, Any] = {}
|
||||||
|
|
||||||
|
@ -288,10 +289,10 @@ class OrderMode:
|
||||||
# since that's illogical / a no-op.
|
# since that's illogical / a no-op.
|
||||||
return
|
return
|
||||||
|
|
||||||
symbol = self.chart.linked.symbol
|
mkt: MktPair = self.chart.linked.mkt
|
||||||
|
|
||||||
# NOTE : we could also use instead,
|
# NOTE : we could also use instead,
|
||||||
# symbol.quantize(price, quantity_type='price')
|
# mkt.quantize(price, quantity_type='price')
|
||||||
# but it returns a Decimal and it's probably gonna
|
# but it returns a Decimal and it's probably gonna
|
||||||
# be slower?
|
# be slower?
|
||||||
# TODO: should we be enforcing this precision
|
# TODO: should we be enforcing this precision
|
||||||
|
@ -301,7 +302,7 @@ class OrderMode:
|
||||||
|
|
||||||
price = round(
|
price = round(
|
||||||
price,
|
price,
|
||||||
ndigits=symbol.tick_size_digits,
|
ndigits=mkt.size_tick_digits,
|
||||||
)
|
)
|
||||||
|
|
||||||
order = self._staged_order = Order(
|
order = self._staged_order = Order(
|
||||||
|
@ -309,8 +310,8 @@ class OrderMode:
|
||||||
price=price,
|
price=price,
|
||||||
account=self.current_pp.alloc.account,
|
account=self.current_pp.alloc.account,
|
||||||
size=0,
|
size=0,
|
||||||
symbol=symbol,
|
symbol=mkt.fqme,
|
||||||
brokers=[symbol.broker],
|
brokers=[mkt.broker],
|
||||||
oid='', # filled in on submit
|
oid='', # filled in on submit
|
||||||
exec_mode=trigger_type, # dark or live
|
exec_mode=trigger_type, # dark or live
|
||||||
)
|
)
|
||||||
|
@ -457,10 +458,10 @@ class OrderMode:
|
||||||
the EMS, adjust mirrored level line on secondary chart.
|
the EMS, adjust mirrored level line on secondary chart.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
mktinfo = self.chart.linked.symbol
|
mktinfo: MktPair = self.chart.linked.mkt
|
||||||
level = round(
|
level = round(
|
||||||
line.value(),
|
line.value(),
|
||||||
ndigits=mktinfo.tick_size_digits,
|
ndigits=mktinfo.size_tick_digits,
|
||||||
)
|
)
|
||||||
# updated by level change callback set in ``.new_line_from_order()``
|
# updated by level change callback set in ``.new_line_from_order()``
|
||||||
dialog = line.dialog
|
dialog = line.dialog
|
||||||
|
@ -497,7 +498,9 @@ class OrderMode:
|
||||||
# a submission is the start of a new order dialog
|
# a submission is the start of a new order dialog
|
||||||
dialog = self.dialogs[uuid]
|
dialog = self.dialogs[uuid]
|
||||||
dialog.lines = lines
|
dialog.lines = lines
|
||||||
dialog.last_status_close()
|
cls: Callable | None = dialog.last_status_close
|
||||||
|
if cls:
|
||||||
|
cls()
|
||||||
|
|
||||||
for line in lines:
|
for line in lines:
|
||||||
|
|
||||||
|
@ -549,7 +552,7 @@ class OrderMode:
|
||||||
# XXX: seems to fail on certain types of races?
|
# XXX: seems to fail on certain types of races?
|
||||||
# assert len(lines) == 2
|
# assert len(lines) == 2
|
||||||
if lines:
|
if lines:
|
||||||
flume: Flume = self.feed.flumes[chart.linked.symbol.fqme]
|
flume: Flume = self.feed.flumes[chart.linked.mkt.fqme]
|
||||||
_, _, ratio = flume.get_ds_info()
|
_, _, ratio = flume.get_ds_info()
|
||||||
|
|
||||||
for chart, shm in [
|
for chart, shm in [
|
||||||
|
@ -740,15 +743,15 @@ async def open_order_mode(
|
||||||
lines = LineEditor(godw=godw)
|
lines = LineEditor(godw=godw)
|
||||||
arrows = ArrowEditor(godw=godw)
|
arrows = ArrowEditor(godw=godw)
|
||||||
|
|
||||||
# symbol id
|
# market endpoint info
|
||||||
symbol = chart.linked.symbol
|
mkt: MktPair = chart.linked.mkt
|
||||||
|
|
||||||
# map of per-provider account keys to position tracker instances
|
# map of per-provider account keys to position tracker instances
|
||||||
trackers: dict[str, PositionTracker] = {}
|
trackers: dict[str, PositionTracker] = {}
|
||||||
|
|
||||||
# load account names from ``brokers.toml``
|
# load account names from ``brokers.toml``
|
||||||
accounts_def = config.load_accounts(
|
accounts_def = config.load_accounts(
|
||||||
providers=[symbol.broker],
|
providers=[mkt.broker],
|
||||||
)
|
)
|
||||||
|
|
||||||
# XXX: ``brokerd`` delivers a set of account names that it
|
# XXX: ``brokerd`` delivers a set of account names that it
|
||||||
|
@ -771,17 +774,17 @@ async def open_order_mode(
|
||||||
|
|
||||||
# net-zero pp
|
# net-zero pp
|
||||||
startup_pp = Position(
|
startup_pp = Position(
|
||||||
mkt=symbol,
|
mkt=mkt,
|
||||||
size=0,
|
size=0,
|
||||||
ppu=0,
|
ppu=0,
|
||||||
|
|
||||||
# XXX: BLEH, do we care about this on the client side?
|
# XXX: BLEH, do we care about this on the client side?
|
||||||
bs_mktid=symbol.key,
|
bs_mktid=mkt.key,
|
||||||
)
|
)
|
||||||
|
|
||||||
# allocator config
|
# allocator config
|
||||||
alloc = mk_allocator(
|
alloc: Allocator = mk_allocator(
|
||||||
symbol=symbol,
|
mkt=mkt,
|
||||||
account=account_name,
|
account=account_name,
|
||||||
|
|
||||||
# if this startup size is greater the allocator limit,
|
# if this startup size is greater the allocator limit,
|
||||||
|
|
Loading…
Reference in New Issue