Only update last datum graphic(s) on clear ticks
When a new tick comes in but no new time step / bar is yet needed (to be appended) we can simply adjust **only** the last bar datum lines-graphic(s) to avoid a redraw of the preceding `QPainterPath` on every tick. Do this by calling `Viz.draw_last()` on the fast and slow chart and adjusting the guards around calls to `Viz.update_graphics()` (which *does* update paths) to only enter when there's a `do_px_step` condition. We can stop calling `main_viz.plot.vb._set_yrange()` on view treading cases since the range should have already been adjusted by the clearing-tick processing mxmn updates. Further this changes, - the `chart_maxmin()` helper (which we should eventually just get rid of) to take bound in `Viz`s for the ohlc and vlm chart instead of the chart widget handles. - extend the guard around hist viz yranging to only enter when not in "axis mode" - the same as for the fast viz.multichartz
							parent
							
								
									84c48f17e2
								
							
						
					
					
						commit
						5ed4e5c945
					
				| 
						 | 
					@ -86,9 +86,9 @@ log = get_logger(__name__)
 | 
				
			||||||
# https://arxiv.org/abs/cs/0610046
 | 
					# https://arxiv.org/abs/cs/0610046
 | 
				
			||||||
# https://github.com/lemire/pythonmaxmin
 | 
					# https://github.com/lemire/pythonmaxmin
 | 
				
			||||||
def chart_maxmin(
 | 
					def chart_maxmin(
 | 
				
			||||||
    chart: ChartPlotWidget,
 | 
					    fast_viz: Viz,
 | 
				
			||||||
    fqsn: str,
 | 
					    fqsn: str,
 | 
				
			||||||
    vlm_chart: ChartPlotWidget | None = None,
 | 
					    vlm_viz: Viz | None = None,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
) -> tuple[
 | 
					) -> tuple[
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,8 +102,7 @@ def chart_maxmin(
 | 
				
			||||||
    Compute max and min datums "in view" for range limits.
 | 
					    Compute max and min datums "in view" for range limits.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    '''
 | 
					    '''
 | 
				
			||||||
    main_viz = chart.get_viz(chart.name)
 | 
					    out = fast_viz.maxmin()
 | 
				
			||||||
    out = main_viz.maxmin()
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if out is None:
 | 
					    if out is None:
 | 
				
			||||||
        return (0, 0, 0)
 | 
					        return (0, 0, 0)
 | 
				
			||||||
| 
						 | 
					@ -121,10 +120,15 @@ def chart_maxmin(
 | 
				
			||||||
    # TODO: we need to NOT call this to avoid a manual
 | 
					    # TODO: we need to NOT call this to avoid a manual
 | 
				
			||||||
    # np.max/min trigger and especially on the vlm_chart
 | 
					    # np.max/min trigger and especially on the vlm_chart
 | 
				
			||||||
    # vizs which aren't shown.. like vlm?
 | 
					    # vizs which aren't shown.. like vlm?
 | 
				
			||||||
    if vlm_chart:
 | 
					    if vlm_viz:
 | 
				
			||||||
        out = vlm_chart.maxmin()
 | 
					        out = vlm_viz.maxmin()
 | 
				
			||||||
        if out:
 | 
					        if out:
 | 
				
			||||||
            _, mx_vlm_in_view = out
 | 
					            (
 | 
				
			||||||
 | 
					                ixrng,
 | 
				
			||||||
 | 
					                read_slc,
 | 
				
			||||||
 | 
					                mxmn,
 | 
				
			||||||
 | 
					            ) = out
 | 
				
			||||||
 | 
					            mx_vlm_in_view = mxmn[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        mx,
 | 
					        mx,
 | 
				
			||||||
| 
						 | 
					@ -308,11 +312,13 @@ async def graphics_update_loop(
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        vlm_chart = vlm_charts[fqsn]
 | 
					        vlm_chart = vlm_charts[fqsn]
 | 
				
			||||||
 | 
					        vlm_viz = vlm_chart._vizs.get('volume') if vlm_chart else None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        maxmin = partial(
 | 
					        maxmin = partial(
 | 
				
			||||||
            chart_maxmin,
 | 
					            chart_maxmin,
 | 
				
			||||||
            fast_chart,
 | 
					            fast_viz,
 | 
				
			||||||
            fqsn,
 | 
					            fqsn,
 | 
				
			||||||
            vlm_chart,
 | 
					            vlm_viz,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        (
 | 
					        (
 | 
				
			||||||
            last_mx,
 | 
					            last_mx,
 | 
				
			||||||
| 
						 | 
					@ -375,7 +381,7 @@ async def graphics_update_loop(
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if vlm_chart:
 | 
					        if vlm_chart:
 | 
				
			||||||
            vlm_pi = vlm_chart._vizs['volume'].plot
 | 
					            vlm_pi = vlm_viz.plot
 | 
				
			||||||
            vlm_sticky = vlm_pi.getAxis('right')._stickies['volume']
 | 
					            vlm_sticky = vlm_pi.getAxis('right')._stickies['volume']
 | 
				
			||||||
            ds.vlm_chart = vlm_chart
 | 
					            ds.vlm_chart = vlm_chart
 | 
				
			||||||
            ds.vlm_sticky = vlm_sticky
 | 
					            ds.vlm_sticky = vlm_sticky
 | 
				
			||||||
| 
						 | 
					@ -517,38 +523,28 @@ def graphics_update_cycle(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # update ohlc sampled price bars
 | 
					    # update ohlc sampled price bars
 | 
				
			||||||
    if (
 | 
					    if (
 | 
				
			||||||
        do_rt_update
 | 
					        # do_rt_update
 | 
				
			||||||
        or do_px_step
 | 
					        # or do_px_step
 | 
				
			||||||
 | 
					        (liv and do_px_step)
 | 
				
			||||||
        or trigger_all
 | 
					        or trigger_all
 | 
				
			||||||
    ):
 | 
					    ):
 | 
				
			||||||
        main_viz.update_graphics(array_key=fqsn)
 | 
					        main_viz.update_graphics(array_key=fqsn)
 | 
				
			||||||
        hist_viz.draw_last(array_key=fqsn)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    else:
 | 
					        # don't real-time "shift" the curve to the
 | 
				
			||||||
        main_viz.draw_last(
 | 
					        # left unless we get one of the following:
 | 
				
			||||||
            array_key=fqsn,
 | 
					        if (
 | 
				
			||||||
            # only_last_uppx=True,
 | 
					 | 
				
			||||||
        )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # don't real-time "shift" the curve to the
 | 
					 | 
				
			||||||
    # left unless we get one of the following:
 | 
					 | 
				
			||||||
    if (
 | 
					 | 
				
			||||||
        (
 | 
					 | 
				
			||||||
            should_tread
 | 
					            should_tread
 | 
				
			||||||
            and do_px_step
 | 
					            or trigger_all
 | 
				
			||||||
            and liv
 | 
					        ):
 | 
				
			||||||
        )
 | 
					            chart.increment_view(datums=append_diff)
 | 
				
			||||||
        or trigger_all
 | 
					            # main_viz.plot.vb._set_yrange(viz=main_viz)
 | 
				
			||||||
    ):
 | 
					 | 
				
			||||||
        chart.increment_view(datums=append_diff)
 | 
					 | 
				
			||||||
        main_viz.plot.vb._set_yrange(viz=main_viz)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # NOTE: since vlm and ohlc charts are axis linked now we don't
 | 
					            # NOTE: since vlm and ohlc charts are axis linked now we don't
 | 
				
			||||||
        # need the double increment request?
 | 
					            # need the double increment request?
 | 
				
			||||||
        # if vlm_chart:
 | 
					            # if vlm_chart:
 | 
				
			||||||
        #     vlm_chart.increment_view(datums=append_diff)
 | 
					            #     vlm_chart.increment_view(datums=append_diff)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        profiler('view incremented')
 | 
					            profiler('view incremented')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 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.
 | 
				
			||||||
| 
						 | 
					@ -587,9 +583,14 @@ def graphics_update_cycle(
 | 
				
			||||||
            ds.last_price_sticky.update_from_data(*end_ic)
 | 
					            ds.last_price_sticky.update_from_data(*end_ic)
 | 
				
			||||||
            ds.hist_last_price_sticky.update_from_data(*end_ic)
 | 
					            ds.hist_last_price_sticky.update_from_data(*end_ic)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if wap_in_history:
 | 
					            # update vwap overlay line
 | 
				
			||||||
                # update vwap overlay line
 | 
					            # if wap_in_history:
 | 
				
			||||||
                chart.get_viz('bar_wap').update_graphics()
 | 
					            #     chart.get_viz('bar_wap').update_graphics()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # update OHLC chart last bars
 | 
				
			||||||
 | 
					            # TODO: fix the only last uppx stuff....
 | 
				
			||||||
 | 
					            main_viz.draw_last() # only_last_uppx=True)
 | 
				
			||||||
 | 
					            hist_viz.draw_last() # only_last_uppx=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # L1 book label-line updates
 | 
					        # L1 book label-line updates
 | 
				
			||||||
        if typ in ('last',):
 | 
					        if typ in ('last',):
 | 
				
			||||||
| 
						 | 
					@ -659,7 +660,8 @@ def graphics_update_cycle(
 | 
				
			||||||
            liv
 | 
					            liv
 | 
				
			||||||
            and not chart._static_yrange == 'axis'
 | 
					            and not chart._static_yrange == 'axis'
 | 
				
			||||||
        ):
 | 
					        ):
 | 
				
			||||||
            main_vb = chart._vizs[fqsn].plot.vb
 | 
					            main_vb = main_viz.plot.vb
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (
 | 
					            if (
 | 
				
			||||||
                main_vb._ic is None
 | 
					                main_vb._ic is None
 | 
				
			||||||
                or not main_vb._ic.is_set()
 | 
					                or not main_vb._ic.is_set()
 | 
				
			||||||
| 
						 | 
					@ -693,14 +695,23 @@ def graphics_update_cycle(
 | 
				
			||||||
            ds=ds,
 | 
					            ds=ds,
 | 
				
			||||||
            is_1m=True,
 | 
					            is_1m=True,
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
        if hist_liv:
 | 
					        if (
 | 
				
			||||||
            hist_viz.plot.vb._set_yrange(viz=hist_viz)
 | 
					            hist_liv
 | 
				
			||||||
 | 
					            and not hist_chart._static_yrange == 'axis'
 | 
				
			||||||
 | 
					        ):
 | 
				
			||||||
 | 
					            hist_viz.plot.vb._set_yrange(
 | 
				
			||||||
 | 
					                viz=hist_viz,
 | 
				
			||||||
 | 
					                # yrange=yr,  # this is the rt range, not hist.. XD
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 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_mx'], varz['last_mn'] = mx, mn
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # TODO: a similar, only-update-full-path-on-px-step approach for all
 | 
				
			||||||
 | 
					    # fsp overlays and vlm stuff..
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 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():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue