Pass windowed y-mxmn to `.interact_graphics_cycle()` calls in display loop
parent
91d41ebf76
commit
25cf8df367
|
@ -146,12 +146,11 @@ def multi_maxmin(
|
||||||
profiler(f'vlm_viz.maxmin({read_slc})')
|
profiler(f'vlm_viz.maxmin({read_slc})')
|
||||||
|
|
||||||
return (
|
return (
|
||||||
mx,
|
|
||||||
|
|
||||||
# enforcing price can't be negative?
|
# enforcing price can't be negative?
|
||||||
# TODO: do we even need this?
|
# TODO: do we even need this?
|
||||||
max(mn, 0),
|
max(mn, 0),
|
||||||
|
|
||||||
|
mx,
|
||||||
mx_vlm_in_view, # vlm max
|
mx_vlm_in_view, # vlm max
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -354,8 +353,8 @@ async def graphics_update_loop(
|
||||||
vlm_viz = vlm_chart._vizs.get('volume') if vlm_chart else None
|
vlm_viz = vlm_chart._vizs.get('volume') if vlm_chart else None
|
||||||
|
|
||||||
(
|
(
|
||||||
last_mx,
|
|
||||||
last_mn,
|
last_mn,
|
||||||
|
last_mx,
|
||||||
last_mx_vlm,
|
last_mx_vlm,
|
||||||
) = multi_maxmin(
|
) = multi_maxmin(
|
||||||
None,
|
None,
|
||||||
|
@ -383,7 +382,7 @@ async def graphics_update_loop(
|
||||||
# present differently -> likely dark vlm
|
# present differently -> likely dark vlm
|
||||||
|
|
||||||
tick_size = symbol.tick_size
|
tick_size = symbol.tick_size
|
||||||
tick_margin = 3 * tick_size
|
tick_margin = 4 * tick_size
|
||||||
|
|
||||||
fast_chart.show()
|
fast_chart.show()
|
||||||
last_quote_s = time.time()
|
last_quote_s = time.time()
|
||||||
|
@ -550,8 +549,14 @@ def graphics_update_cycle(
|
||||||
# them as an additional graphic.
|
# them as an additional graphic.
|
||||||
clear_types = _tick_groups['clears']
|
clear_types = _tick_groups['clears']
|
||||||
|
|
||||||
mx = varz['last_mx']
|
# TODO: fancier y-range sorting..
|
||||||
mn = varz['last_mn']
|
# https://github.com/pikers/piker/issues/325
|
||||||
|
# - a proper streaming mxmn algo as per above issue.
|
||||||
|
# - we should probably scale the view margin based on the size of
|
||||||
|
# the true range? This way you can slap in orders outside the
|
||||||
|
# current L1 (only) book range.
|
||||||
|
mx = lmx = varz['last_mx']
|
||||||
|
mn = lmn = varz['last_mn']
|
||||||
mx_vlm_in_view = varz['last_mx_vlm']
|
mx_vlm_in_view = varz['last_mx_vlm']
|
||||||
|
|
||||||
# update ohlc sampled price bars
|
# update ohlc sampled price bars
|
||||||
|
@ -561,24 +566,12 @@ def graphics_update_cycle(
|
||||||
(liv and do_px_step)
|
(liv and do_px_step)
|
||||||
or trigger_all
|
or trigger_all
|
||||||
):
|
):
|
||||||
|
# TODO: i think we're double calling this right now
|
||||||
|
# since .interact_graphics_cycle() also calls it?
|
||||||
|
# I guess we can add a guard in there?
|
||||||
_, i_read_range, _ = main_viz.update_graphics()
|
_, i_read_range, _ = main_viz.update_graphics()
|
||||||
profiler('`Viz.update_graphics()` call')
|
profiler('`Viz.update_graphics()` call')
|
||||||
|
|
||||||
(
|
|
||||||
mx_in_view,
|
|
||||||
mn_in_view,
|
|
||||||
mx_vlm_in_view,
|
|
||||||
) = multi_maxmin(
|
|
||||||
i_read_range,
|
|
||||||
main_viz,
|
|
||||||
ds.vlm_viz,
|
|
||||||
profiler,
|
|
||||||
)
|
|
||||||
|
|
||||||
mx = mx_in_view + tick_margin
|
|
||||||
mn = mn_in_view - tick_margin
|
|
||||||
profiler(f'{fqsn} `multi_maxmin()` call')
|
|
||||||
|
|
||||||
# don't real-time "shift" the curve to the
|
# don't real-time "shift" the curve to the
|
||||||
# left unless we get one of the following:
|
# left unless we get one of the following:
|
||||||
if (
|
if (
|
||||||
|
@ -594,6 +587,23 @@ def graphics_update_cycle(
|
||||||
|
|
||||||
profiler('view incremented')
|
profiler('view incremented')
|
||||||
|
|
||||||
|
# NOTE: do this **after** the tread to ensure we take the yrange
|
||||||
|
# from the most current view x-domain.
|
||||||
|
(
|
||||||
|
mn_in_view,
|
||||||
|
mx_in_view,
|
||||||
|
mx_vlm_in_view,
|
||||||
|
) = multi_maxmin(
|
||||||
|
i_read_range,
|
||||||
|
main_viz,
|
||||||
|
ds.vlm_viz,
|
||||||
|
profiler,
|
||||||
|
)
|
||||||
|
|
||||||
|
mx = mx_in_view + tick_margin
|
||||||
|
mn = mn_in_view - tick_margin
|
||||||
|
profiler(f'{fqsn} `multi_maxmin()` call')
|
||||||
|
|
||||||
# iterate frames of ticks-by-type such that we only update graphics
|
# iterate frames of ticks-by-type such that we only update graphics
|
||||||
# using the last update per type where possible.
|
# using the last update per type where possible.
|
||||||
ticks_by_type = quote.get('tbt', {})
|
ticks_by_type = quote.get('tbt', {})
|
||||||
|
@ -679,14 +689,10 @@ def graphics_update_cycle(
|
||||||
|
|
||||||
# Y-autoranging: adjust y-axis limits based on state tracking
|
# Y-autoranging: adjust y-axis limits based on state tracking
|
||||||
# of previous "last" L1 values which are in view.
|
# of previous "last" L1 values which are in view.
|
||||||
lmx = varz['last_mx']
|
|
||||||
lmn = varz['last_mn']
|
|
||||||
mx_diff = mx - lmx
|
|
||||||
mn_diff = mn - lmn
|
mn_diff = mn - lmn
|
||||||
|
mx_diff = mx - lmx
|
||||||
if (
|
if (
|
||||||
mx_diff
|
mx_diff or mn_diff
|
||||||
or mn_diff
|
|
||||||
):
|
):
|
||||||
# complain about out-of-range outliers which can show up
|
# complain about out-of-range outliers which can show up
|
||||||
# in certain annoying feeds (like ib)..
|
# in certain annoying feeds (like ib)..
|
||||||
|
@ -705,7 +711,12 @@ def graphics_update_cycle(
|
||||||
f'mn_diff: {mn_diff}\n'
|
f'mn_diff: {mn_diff}\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
# FAST CHART resize case
|
# TODO: track local liv maxmin without doing a recompute all the
|
||||||
|
# time..plus, just generally the user is more likely to be
|
||||||
|
# zoomed out enough on the slow chart that this is never an
|
||||||
|
# issue (the last datum going out of y-range).
|
||||||
|
|
||||||
|
# FAST CHART y-auto-range resize case
|
||||||
elif (
|
elif (
|
||||||
liv
|
liv
|
||||||
and not chart._static_yrange == 'axis'
|
and not chart._static_yrange == 'axis'
|
||||||
|
@ -716,22 +727,15 @@ def graphics_update_cycle(
|
||||||
main_vb._ic is None
|
main_vb._ic is None
|
||||||
or not main_vb._ic.is_set()
|
or not main_vb._ic.is_set()
|
||||||
):
|
):
|
||||||
# TODO: incremenal update of the median
|
# print(f'SETTING Y-mxmx -> {main_viz.name}: {(mn, mx)}')
|
||||||
# and maxmin driving the y-autoranging.
|
|
||||||
# yr = (mn, mx)
|
|
||||||
main_vb.interact_graphics_cycle(
|
main_vb.interact_graphics_cycle(
|
||||||
# do_overlay_scaling=False,
|
# do_overlay_scaling=False,
|
||||||
do_linked_charts=False,
|
do_linked_charts=False,
|
||||||
|
yranges={main_viz: (mn, mx)},
|
||||||
)
|
)
|
||||||
# TODO: we should probably scale
|
|
||||||
# the view margin based on the size
|
|
||||||
# of the true range? This way you can
|
|
||||||
# slap in orders outside the current
|
|
||||||
# L1 (only) book range.
|
|
||||||
|
|
||||||
profiler('main vb y-autorange')
|
profiler('main vb y-autorange')
|
||||||
|
|
||||||
# SLOW CHART resize case
|
# SLOW CHART y-auto-range resize case
|
||||||
(
|
(
|
||||||
_,
|
_,
|
||||||
hist_liv,
|
hist_liv,
|
||||||
|
@ -746,10 +750,6 @@ def graphics_update_cycle(
|
||||||
)
|
)
|
||||||
profiler('hist `Viz.incr_info()`')
|
profiler('hist `Viz.incr_info()`')
|
||||||
|
|
||||||
# TODO: track local liv maxmin without doing a recompute all the
|
|
||||||
# time..plut, just generally the user is more likely to be
|
|
||||||
# zoomed out enough on the slow chart that this is never an
|
|
||||||
# issue (the last datum going out of y-range).
|
|
||||||
# hist_chart = ds.hist_chart
|
# hist_chart = ds.hist_chart
|
||||||
# if (
|
# if (
|
||||||
# hist_liv
|
# hist_liv
|
||||||
|
@ -764,7 +764,8 @@ def graphics_update_cycle(
|
||||||
# XXX: update this every draw cycle to ensure y-axis auto-ranging
|
# XXX: update this every draw cycle to ensure y-axis auto-ranging
|
||||||
# only adjusts when the in-view data co-domain actually expands or
|
# only adjusts when the in-view data co-domain actually expands or
|
||||||
# contracts.
|
# contracts.
|
||||||
varz['last_mx'], varz['last_mn'] = mx, mn
|
varz['last_mn'] = mn
|
||||||
|
varz['last_mx'] = mx
|
||||||
|
|
||||||
# TODO: a similar, only-update-full-path-on-px-step approach for all
|
# TODO: a similar, only-update-full-path-on-px-step approach for all
|
||||||
# fsp overlays and vlm stuff..
|
# fsp overlays and vlm stuff..
|
||||||
|
@ -772,10 +773,12 @@ def graphics_update_cycle(
|
||||||
# run synchronous update on all `Viz` overlays
|
# run synchronous update on all `Viz` overlays
|
||||||
for curve_name, viz in chart._vizs.items():
|
for curve_name, viz in chart._vizs.items():
|
||||||
|
|
||||||
|
if viz.is_ohlc:
|
||||||
|
continue
|
||||||
|
|
||||||
# update any overlayed fsp flows
|
# update any overlayed fsp flows
|
||||||
if (
|
if (
|
||||||
curve_name != fqsn
|
curve_name != fqsn
|
||||||
and not viz.is_ohlc
|
|
||||||
):
|
):
|
||||||
update_fsp_chart(
|
update_fsp_chart(
|
||||||
viz,
|
viz,
|
||||||
|
@ -788,8 +791,7 @@ def graphics_update_cycle(
|
||||||
# px column to give the user the mx/mn
|
# px column to give the user the mx/mn
|
||||||
# range of that set.
|
# range of that set.
|
||||||
if (
|
if (
|
||||||
curve_name != fqsn
|
liv
|
||||||
and liv
|
|
||||||
# and not do_px_step
|
# and not do_px_step
|
||||||
# and not do_rt_update
|
# and not do_rt_update
|
||||||
):
|
):
|
||||||
|
|
Loading…
Reference in New Issue