view_mode: handle duplicate overlay dispersions
Discovered due to originally having a history loading bug between btcusdt futes display where the same time series was being loaded into the graphics system, this avoids the issue where 2 (or more) curves are measured to have the same dispersion and thus do not get added as unique entries to the `overlay_table: dict[float, tuple]` during the scaling phase.. Practically speaking this should never really be a problem if the curves (and their backing timeseries) are indeed unique but keying the overlay table by the dispersion and the `Viz` is a minimal performance hit when looping the sorted table and is a lot nicer then you **do want to show** duplicate curves then having one overlay just not be ranged correctly at all XDbasic_buy_bot
parent
0f8c685735
commit
6a1c49be4e
|
@ -19,6 +19,7 @@ Overlay (aka multi-chart) UX machinery.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
from operator import itemgetter
|
||||||
from typing import (
|
from typing import (
|
||||||
Any,
|
Any,
|
||||||
Literal,
|
Literal,
|
||||||
|
@ -197,15 +198,17 @@ def overlay_viewlists(
|
||||||
|
|
||||||
) -> None:
|
) -> None:
|
||||||
'''
|
'''
|
||||||
Calculate and apply y-domain (axis y-range) multi-curve overlay adjustments
|
Calculate and apply y-domain (axis y-range) multi-curve overlay
|
||||||
a set of ``plots`` based on the requested ``method``.
|
adjustments a set of ``plots`` based on the requested
|
||||||
|
``method``.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
chart_name: str
|
chart_name: str
|
||||||
chart: ChartPlotWidget
|
chart: ChartPlotWidget
|
||||||
|
|
||||||
for chart_name, chart in plots.items():
|
for chart_name, chart in plots.items():
|
||||||
|
|
||||||
overlay_viz_items = chart._vizs.items()
|
overlay_viz_items: dict = chart._vizs
|
||||||
|
|
||||||
# Common `PlotItem` maxmin table; presumes that some path
|
# Common `PlotItem` maxmin table; presumes that some path
|
||||||
# graphics (and thus their backing data sets) are in the
|
# graphics (and thus their backing data sets) are in the
|
||||||
|
@ -271,6 +274,7 @@ def overlay_viewlists(
|
||||||
# determine auto-ranging input for `._set_yrange()`.
|
# determine auto-ranging input for `._set_yrange()`.
|
||||||
# this is primarly used for our so called "log-linearized
|
# this is primarly used for our so called "log-linearized
|
||||||
# multi-plot" overlay technique.
|
# multi-plot" overlay technique.
|
||||||
|
# vizs_by_disp: list[tuple[float, Viz]] = []
|
||||||
overlay_table: dict[
|
overlay_table: dict[
|
||||||
float,
|
float,
|
||||||
tuple[
|
tuple[
|
||||||
|
@ -288,7 +292,7 @@ def overlay_viewlists(
|
||||||
] = {}
|
] = {}
|
||||||
|
|
||||||
# multi-curve overlay processing stage
|
# multi-curve overlay processing stage
|
||||||
for name, viz in overlay_viz_items:
|
for name, viz in overlay_viz_items.items():
|
||||||
|
|
||||||
out = _maybe_calc_yrange(
|
out = _maybe_calc_yrange(
|
||||||
viz,
|
viz,
|
||||||
|
@ -356,7 +360,7 @@ def overlay_viewlists(
|
||||||
# returns scalars
|
# returns scalars
|
||||||
r_up = (ymx - y_ref) / y_ref
|
r_up = (ymx - y_ref) / y_ref
|
||||||
r_down = (ymn - y_ref) / y_ref
|
r_down = (ymn - y_ref) / y_ref
|
||||||
disp = r_up - r_down
|
disp = round(r_up - r_down, ndigits=16)
|
||||||
|
|
||||||
msg = (
|
msg = (
|
||||||
f'Viz[{viz.name}][{key}]: @{chart_name}\n'
|
f'Viz[{viz.name}][{key}]: @{chart_name}\n'
|
||||||
|
@ -489,7 +493,15 @@ def overlay_viewlists(
|
||||||
# register curves by a "full" dispersion metric for
|
# register curves by a "full" dispersion metric for
|
||||||
# later sort order in the overlay (technique
|
# later sort order in the overlay (technique
|
||||||
# ) application loop below.
|
# ) application loop below.
|
||||||
overlay_table[disp] = (
|
pair: tuple[float, Viz] = (disp, viz)
|
||||||
|
|
||||||
|
# time series are so similar they have same
|
||||||
|
# dispersion with `float` precision..
|
||||||
|
if entry := overlay_table.get(pair):
|
||||||
|
raise RuntimeError('Duplicate entry!? -> {entry}')
|
||||||
|
|
||||||
|
# vizs_by_disp.append(pair)
|
||||||
|
overlay_table[pair] = (
|
||||||
viz.plot.vb,
|
viz.plot.vb,
|
||||||
viz,
|
viz,
|
||||||
y_ref,
|
y_ref,
|
||||||
|
@ -540,6 +552,7 @@ def overlay_viewlists(
|
||||||
mxmns_by_common_pi
|
mxmns_by_common_pi
|
||||||
and not overlay_table
|
and not overlay_table
|
||||||
):
|
):
|
||||||
|
print("WAATT THE FUCK")
|
||||||
# move to next chart in linked set since
|
# move to next chart in linked set since
|
||||||
# no overlay transforming is needed.
|
# no overlay transforming is needed.
|
||||||
continue
|
continue
|
||||||
|
@ -548,7 +561,7 @@ def overlay_viewlists(
|
||||||
|
|
||||||
r_up_mx: float
|
r_up_mx: float
|
||||||
r_dn_mn: float
|
r_dn_mn: float
|
||||||
mx_disp = max(overlay_table)
|
mx_pair: tuple = max(overlay_table, key=itemgetter(0))
|
||||||
|
|
||||||
if debug_print:
|
if debug_print:
|
||||||
# print overlay table in descending dispersion order
|
# print overlay table in descending dispersion order
|
||||||
|
@ -564,11 +577,11 @@ def overlay_viewlists(
|
||||||
)
|
)
|
||||||
|
|
||||||
if method == 'loglin_ref_to_curve':
|
if method == 'loglin_ref_to_curve':
|
||||||
mx_entry = overlay_table.pop(mx_disp)
|
mx_entry = overlay_table.pop(mx_pair)
|
||||||
else:
|
else:
|
||||||
# TODO: for pin to first-in-view we need to no pop this from the
|
# TODO: for pin to first-in-view we need to NOT pop this from the
|
||||||
# table, but can we simplify below code even more?
|
# table, but can we simplify below code even more?
|
||||||
mx_entry = overlay_table[mx_disp]
|
mx_entry = overlay_table[mx_pair]
|
||||||
|
|
||||||
(
|
(
|
||||||
mx_view, # viewbox
|
mx_view, # viewbox
|
||||||
|
@ -599,7 +612,11 @@ def overlay_viewlists(
|
||||||
tuple[Viz, float, float, float, float]
|
tuple[Viz, float, float, float, float]
|
||||||
] = {}
|
] = {}
|
||||||
|
|
||||||
for full_disp in reversed(overlay_table):
|
for pair in sorted(
|
||||||
|
overlay_table,
|
||||||
|
key=itemgetter(0),
|
||||||
|
reverse=True,
|
||||||
|
):
|
||||||
(
|
(
|
||||||
view,
|
view,
|
||||||
viz,
|
viz,
|
||||||
|
@ -610,7 +627,7 @@ def overlay_viewlists(
|
||||||
minor_in_view,
|
minor_in_view,
|
||||||
r_up,
|
r_up,
|
||||||
r_dn,
|
r_dn,
|
||||||
) = overlay_table[full_disp]
|
) = overlay_table[pair]
|
||||||
|
|
||||||
key = 'open' if viz.is_ohlc else viz.name
|
key = 'open' if viz.is_ohlc else viz.name
|
||||||
xref = minor_in_view[0]['time']
|
xref = minor_in_view[0]['time']
|
||||||
|
@ -839,7 +856,7 @@ def overlay_viewlists(
|
||||||
print(
|
print(
|
||||||
'SCALING PHASE' + '-'*100 + '\n\n'
|
'SCALING PHASE' + '-'*100 + '\n\n'
|
||||||
'_________MAJOR INFO___________\n'
|
'_________MAJOR INFO___________\n'
|
||||||
f'SIGMA MAJOR C: {mx_viz.name} -> {mx_disp}\n'
|
f'SIGMA MAJOR C: {mx_viz.name} -> {mx_pair[0]}\n'
|
||||||
f'UP MAJOR C: {upt.viz.name} with disp: {upt.rng}\n'
|
f'UP MAJOR C: {upt.viz.name} with disp: {upt.rng}\n'
|
||||||
f'DOWN MAJOR C: {dnt.viz.name} with disp: {dnt.rng}\n'
|
f'DOWN MAJOR C: {dnt.viz.name} with disp: {dnt.rng}\n'
|
||||||
f'xref: {mx_xref}\n'
|
f'xref: {mx_xref}\n'
|
||||||
|
|
Loading…
Reference in New Issue