Commit Graph

2098 Commits (38be93a0093146d86214a44736358747deb135c3)

Author SHA1 Message Date
Tyler Goodlet b30b4bb555 Add `Flow` type with a real chitty mxmn cacheing method
This new type wraps a shm data flow and will eventually include things
like incremental path-graphics updates and serialization + bg downsampling
techniques. The main immediate motivation was to get a cached y-range max/min
calc going since profiling revealed the `numpy` equivalents were
actually quite slow as the data set grows large. Likely we can use all
this to drive a streaming mx/mn routine that's always launched as part
of each on-host flow.

This is our official foray into use of `msgspec.Struct` B) and I have to
say, pretty impressed; we'll likely completely ditch `pydantic` from
here on out.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 514bbb1a98 Loop for first graphic with xvec 2022-04-16 15:38:26 -04:00
Tyler Goodlet 918789d1a3 Only `.maybe_downsample_graphics()` on manual changes
We don't need update graphics on every x-range change since that's what
the display loop does. Instead, only on manual changes do we make manual
calls into `.update_graphics_from_array()` and be sure to iterate all
linked subplots and all their embedded graphics.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 127294d39c Don't return early on ds line render to avoid breaking profiling
The pg profiler seems to have trouble with early `return`s in function
calls (likely muckery with the GC/`.__delete__()`) so let's just try
to avoid it for now until we either fix it (probably by implementing as
a ctx mngr) or use diff one.
2022-04-16 15:38:26 -04:00
Tyler Goodlet d3a30a272d Use HL tracer by default, seems to be faster? 2022-04-16 15:38:26 -04:00
Tyler Goodlet 9477c7e66c Allow passing "ms slower then" value on cli to `--profile` 2022-04-16 15:38:26 -04:00
Tyler Goodlet abab8d3451 Only bail up pan updates if uppx > 16 2022-04-16 15:38:26 -04:00
Tyler Goodlet c4ad4e089e Delegate `BarItems.x_uppx()` to internal ds curve 2022-04-16 15:38:26 -04:00
Tyler Goodlet 36224eac5a Downsample curves even less frequently 2022-04-16 15:38:26 -04:00
Tyler Goodlet 1cdec55725 Only pass vr for bars, allow source vb in autorange 2022-04-16 15:38:26 -04:00
Tyler Goodlet 576263dc4d Drop the unit-volume chart once $vlm is fully drawn 2022-04-16 15:38:26 -04:00
Tyler Goodlet 3998cb70a6 Ensure we update the volume array, not graphics
Ugh, turns out the wacky `ChartView.maxmin` callback stuff we did (for
determining y-range sizings) currently requires that the volume array
has a "bars in view" result.. so let's make that keep working without
rendering the graphics for the curve (since we're disabling them once
$vlm comes up).
2022-04-16 15:38:26 -04:00
Tyler Goodlet 096d8553e6 Add `.update_graphics_from_array()` flags for setting view-range use and graphics rendering 2022-04-16 15:38:26 -04:00
Tyler Goodlet ec877f38a0 Guard against zero px width 2022-04-16 15:38:26 -04:00
Tyler Goodlet b055fc9daa Given in-view rendering, make bars downsample on uppx >= 8 2022-04-16 15:38:26 -04:00
Tyler Goodlet c0bb23adb1 Make `FastAppendCurve` optionally view range aware
As with the `BarItems` graphics, this makes it possible to pass in a "in
view" range of array data that can be *only* rendered improving
performance for large(r) data sets. All the other normal behaviour is
kept (i.e a persistent, (pre/ap)pendable path can still be maintained)
if a ``view_range`` is not provided.

Further updates,
- drop the `.should_ds_or_redraw()` and `.maybe_downsample()` predicates
 instead moving all that logic inside `.update_from_array()`.
- disable the "cache flipping", which doesn't seem to be needed to avoid
  artifacts any more?
- handle all redraw/dowsampling logic in `.update_from_array()`.
- even more profiling.
- drop path `.reserve()` stuff until we better figure out how it's
  supposed to work.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 302fadeab7 Fix view range array to include most recent (facepalm) 2022-04-16 15:38:26 -04:00
Tyler Goodlet 5a86b62a9c TOQUASH: drop display loop old .update_ohlc_.. 2022-04-16 15:38:26 -04:00
Tyler Goodlet 750e7230da Port to new `.update_graphics_from_array()`, pause quote updates on chart interaction 2022-04-16 15:38:26 -04:00
Tyler Goodlet 264328e119 Make panning pause feeds, call into update method from downsampler cb loop 2022-04-16 15:38:26 -04:00
Tyler Goodlet 242007d7f6 Attempt only rendering ohlc bars in view and ds-ing otherwise 2022-04-16 15:38:26 -04:00
Tyler Goodlet dcfe89cfa9 Unify into a single update method: `.update_graphics_from_array()` 2022-04-16 15:38:26 -04:00
Tyler Goodlet 4722232938 Remove units vlm cuve once the $vlm one comes up 2022-04-16 15:38:26 -04:00
Tyler Goodlet 156a839ee9 Index must be int bro.. 2022-04-16 15:38:26 -04:00
Tyler Goodlet b748bc2d05 Move px width log scaling into `ds_m4()` 2022-04-16 15:38:26 -04:00
Tyler Goodlet 927d37541f Add more frequent ds steps when zooming out; use profiler gt 2022-04-16 15:38:26 -04:00
Tyler Goodlet e6eea88174 Make `BarItems` use our line curve for downsampling
Drop all the logic originally in `.update_ds_line()` which is now done
internal to our `FastAppendCurve`. Add incremental update of the
flattened OHLC -> line curve (unfortunately using `np.concatenate()` for
the moment) and maintain a new `._ds_line_xy` arrays tuple which keeps
the internal state. Add `.maybe_downsample()` as per the new interaction
update method requirement. Draft out some fast path curve stuff like in
our line graphic. Short-circuit bars path updates when we downsample to
line. Oh, and add a ton more profiling in prep for getting
all this stuff faf.
2022-04-16 15:38:26 -04:00
Tyler Goodlet e1cfbc78ee Add global profile timeout var 2022-04-16 15:38:26 -04:00
Tyler Goodlet f1f7241a1e Add "native" downsampling to our `FastAppendCurve`
Build out an interface that makes it super easy to downsample curves
using the m4 algorithm while keeping our incremental `QPainterPath`
update feature. A lot of hard work and tinkering went into getting this
working all in-thread correctly and there are quite a few details..

New interface methods:
- `.x_uppx()` which returns the x-axis "view units per pixel"
- `.px_width()` which returns the total (rounded) x-axis pixels spanned
    by the curve in view.
- `.should_ds_or_redraw()` a predicate which checks internal state to
  see if either downsampling of the curve should take place, or the curve
  should have all downsampling removed and be redrawn with source array
  data.
- `.downsample()` the actual ds processing routine which delegates into
  the m4 algo impl.
- `.maybe_downsample()` a simple update method which can be called by
  the view box when the user changes the zoom level.

Implementation details/changes:

- make `.update_from_array()` check for downsample (or revert to source
  aka de-downsample) conditions exist and then downsample and re-draw
  path graphics accordingly.
- in order to even further speed up path appends (since our main
  bottleneck is measured to be `QPainter.drawPath()` calls with large
  paths which are frequently updates), add a secondary path `.fast_path`
  which is the path that is real-time updates by incremental appends and
  which is painted separately for speed in `.pain()`.
- drop all the `QPolyLine` stuff since it was tested to be much slower
  in general and especially so for append-updates.
- stop disabling the cache settings on updates since it doesn't seem to
  be required any more?
- more move toward deprecating and removing all lingering interface
  requirements from `pg.PlotCurveItem` (like `.xData`/`.yData`).
- adjust `.paint()` and `.boundingRect()` to compensate for the new
  `.fast_path`
- add a butt-load of profiling B)
2022-04-16 15:38:26 -04:00
Tyler Goodlet 6af6449e8e Add no-path guard now that we can use a poly 2022-04-16 15:38:26 -04:00
Tyler Goodlet c55c0f5d8f First try, drop `FastAppendCurve` inheritance from `pg.PlotCurveItem` 2022-04-16 15:38:26 -04:00
Tyler Goodlet 8c2d375e0e Drop commented line from pq method copy/paste 2022-04-16 15:38:26 -04:00
Tyler Goodlet 889aa10d32 Show baseline bars length on in view read < 6 2022-04-16 15:38:26 -04:00
Tyler Goodlet eba92a8f20 Bump up resolution log scaling a mag 2022-04-16 15:38:26 -04:00
Tyler Goodlet d3d19a57c9 Always clear previous downsample curve on switch
Pretty sure this was most of the cause of the stale (more downsampled)
curves showing when zooming in and out from bars mode quickly. All this
stuff needs to get factored out into a new abstraction anyway, but
i think this get's mostly correct functionality.

Only draw new ds curve on uppx steps >= 4 and stop adding/removing
graphics objects from the scene; doesn't seem to speed anything up
afaict. Add better reporting of ds scale changes.
2022-04-16 15:38:26 -04:00
Tyler Goodlet ba4a526b8b Clear ds line graphics on switch back to bars 2022-04-16 15:38:26 -04:00
Tyler Goodlet 15922f4090 More ems resiliency: discard broken client dialogs 2022-04-16 15:38:26 -04:00
Tyler Goodlet f6136245f9 Allocate m4 output arrays in `numba` code, avoid segfaults? 2022-04-16 15:38:26 -04:00
Tyler Goodlet 44482cbc1b Only clear/redraw curve on uppx diffs > 2
Only if the uppx increases by more then 2 we redraw the entire line
otherwise just ds with previous params and update the current curve.
This *should* avoid strange lower sample rate artefacts from showing on
updates.

Summary:
- stash both uppx and px width in `._dsi` (downsample info)
- use the new `ohlc_to_m4_line()` flags
- add notes about using `.reserve()` and friends
- always delete last `._array` ref prior to line updates
2022-04-16 15:38:26 -04:00
Tyler Goodlet c745c9801f Try supporting reuse of path allocation 2022-04-16 15:38:26 -04:00
Tyler Goodlet 60b1c53d20 Add optional mxmn HL tracer support to m4 sampler 2022-04-16 15:38:26 -04:00
Tyler Goodlet 68779218ff Add our own `FastAppendCurve.clear()`, try mem reso
In an effort to try and make `QPainterPath.reserve()` work, add internal
logic to use the same object without de-allocating memory from
a previous path write/creation.

Note this required the addition of a `._redraw` flag (to be used in
`.clear()` and a small patch to `pyqtgraph.functions.arrayToQPath` to
allow passing in an existing path (thus reusing the same underlying mem
alloc) which will likely be first pushed to our fork.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 9726ed1a42 Add optional uppx log scaling to m4 sampler
We were previously ad-hoc scaling up the px count/width to get more
detail at lower uppx values. Add a log scaling sigmoid that range scales
between 1 < px_width < 16.

Add in a flag to use the mxmn OH tracer in `ohlc_flatten()` if desired.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 69cb8156a2 Delegate to m4 ohlc helper for curve, only ds on uppx steps > 2 2022-04-16 15:38:26 -04:00
Tyler Goodlet 97efb865d4 Add OHLC to m4 line converters
Helpers to quickly convert ohlc struct-array sequences into lines
for consumption by the m4 downsampler. Strip trailing zero entries
from the `ds_m4()` output if found (avoids lines back to origin).
2022-04-16 15:38:26 -04:00
Tyler Goodlet 2f99fd35e5 M4 workin bishhhhh 2022-04-16 15:38:26 -04:00
Tyler Goodlet 2e25357ed0 Call default view on symbol switch 2022-04-16 15:38:26 -04:00
Tyler Goodlet c1bdf0e26d Make a derivs intrustment type table for alloc config checks 2022-04-16 15:38:26 -04:00
Tyler Goodlet d3587263db Even more correct "default view" snap-to-pp-marker
This makes the `'r'` hotkey snap the last bar to the middle of the pp
line arrow marker no matter the zoom level. Now we also boot with
approximately the most number of x units on screen that keep the bars
graphics drawn in full (just before downsampling to a line).

Moved some internals around to get this all in place,
- drop `_anchors.marker_right_points()` and move it to a chart method.
- change `.pre_l1_x()` -> `.pre_l1_xs()` and just have it return the
  two view-mapped x values from the former method.
2022-04-16 15:38:26 -04:00
Tyler Goodlet 6bf4cdaa24 Make `ChartPlotWidget.default_view()` pin to L1
Instead of using a guess about how many x-indexes to reset the last
datum in-view to, calculate and shift the latest index such that it's
just before any L1 spread labels on the y-axis. This makes the view
placement "widget aware" and gives a much more cross-display UX.

Summary:
- add `ChartPlotWidget.pre_l1_x()` which returns a `tuple` of
  x view-coord points for the absolute x-pos and length of any L1
  line/labels
- make `.default_view()` only shift to see the xlast just outside
  the l1 but keep whatever view range xfirst as the first datum in view
- drop `LevelLine.right_point()` since this is now just a
  `.pre_l1_x()` call and can be retrieved from the line's internal chart
  ref
- drop `._style.bars_from/to_..` vars since we aren't using hard coded
  offsets any more
2022-04-16 15:38:26 -04:00