Commit Graph

3227 Commits (5ed4e5c945446fbeff0f0d81b8561eaee6d4f219)

Author SHA1 Message Date
Tyler Goodlet e1af087626 Use uniform step arithmetic in `slice_from_time()`
If we presume that time indexing using a uniform step we can calculate
the exact index (using `//`) for the input time presuming the data
set has zero gaps. This gives a massive speedup over `numpy` fancy
indexing and (naive) `numba` iteration. Further in the case where time
gaps are detected, we can use `numpy.searchsorted()` to binary search
for the nearest expected index at lower latency.

Deatz,
- comment-disable the call to the naive `numba` scan impl.
- add a optional `step: int` input (calced if not provided).
- add todos for caching binary search results in the gap detection
  cases.
- drop returning the "absolute buffer indexing" slice since the caller
  can always just use the read-relative slice to acquire it.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 029dee994f Make `.default_view()` time step aware
When we use an epoch index and any sample rate > 1s we need to scale the
"number of bars" to that step in order to place the view correctly in
x-domain terms. For now we're calcing the step in-method but likely,
longer run, we'll pull this from elsewhere (like a ``Viz`` attr).
2023-02-02 15:06:32 -05:00
Tyler Goodlet 1ab9acf075 Flip over to epoch-time based x-domain indexing 2023-02-02 15:06:32 -05:00
Tyler Goodlet 02cef3ed6d Adjust all `slice_from_time()` calls to not expect mask 2023-02-02 15:06:32 -05:00
Tyler Goodlet 12307e5757 Rewrite `slice_from_time()` using `numba`
Gives approx a 3-4x speedup using plain old iterate-with-for-loop style
though still not really happy with this .5 to 1 ms latency..

Move the core `@njit` part to a `_slice_from_time()` with a pure python
func with orig name around it. Also, drop the output `mask` array since
we can generally just use the slices in the caller to accomplish the
same input array slicing, duh..
2023-02-02 15:06:32 -05:00
Tyler Goodlet e1e04d3215 Use index (time) step to calc OHLC bar/line uppx threshold 2023-02-02 15:06:32 -05:00
Tyler Goodlet 8dfa080fd1 Use step size to determine bar gaps 2023-02-02 15:06:32 -05:00
Tyler Goodlet 993a42e88f Use step size to determine last datum bar gap 2023-02-02 15:06:32 -05:00
Tyler Goodlet 51e6ca21fa Move `Flume.slice_from_time()` to `.data._pathops` mod func 2023-02-02 15:06:32 -05:00
Tyler Goodlet 3da84387c3 Drop `index_field` input to renders, add `.read()` profiling 2023-02-02 15:06:32 -05:00
Tyler Goodlet 363820ddc0 Delegate formatter `.index_field` to the parent `Viz` 2023-02-02 15:06:32 -05:00
Tyler Goodlet 101c2fd865 Facepalm**2: fix array-read-slice, like actually..
We need to subtract the first index in the array segment read, not the
first index value in the time-sliced output, to get the correct offset
into the non-absolute (`ShmArray.array` read) array..

Further we **do** need the `&` between the advance indexing conditions
and this adds profiling to see that it is indeed real slow (like 20ms
ish even when using `np.where()`).
2023-02-02 15:06:32 -05:00
Tyler Goodlet d739cf15b8 Markup OHLC->path gen with `numba` issue # 2023-02-02 15:06:32 -05:00
Tyler Goodlet b0e31990d3 Facepalm: put graphics cycle in `do_ds: bool` block.. 2023-02-02 15:06:32 -05:00
Tyler Goodlet f850959a39 Facepalm: actually return latest index on time slice fail.. 2023-02-02 15:06:32 -05:00
Tyler Goodlet f2179dc6f8 Go with explicit `.data._m4` mod name
Since it's a notable and self-contained graphics compression algo, might
as well give it a dedicated module B)
2023-02-02 15:06:32 -05:00
Tyler Goodlet 4a9896a29d Move (unused) path gen routines to `.ui._pathops` 2023-02-02 15:06:32 -05:00
Tyler Goodlet 9c69636388 Move qpath-ops routines back to separate mod 2023-02-02 15:06:32 -05:00
Tyler Goodlet d7edcc30c4 Rename `.ui._pathops.py` -> `.ui._formatters.py 2023-02-02 15:06:32 -05:00
Tyler Goodlet d717096d82 Look up "index field" in display cycles
Again, to make epoch indexing a flip-of-switch for testing look up the
`Viz.index_field: str` value when updating labels.

Also, drops the legacy tick-type set tracking which we no longer use
thanks to the new throttler subsys and it's framing msgs.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 6e74f52049 Fix from-time index slicing?
Apparently we want an `|` for the advanced indexing logic?
Also, fix `read_slc` start to not always be 0 XD
2023-02-02 15:06:32 -05:00
Tyler Goodlet 92257995a6 Move path ops routines to top of mod
Planning to put the formatters into a new mod and aggregate all path
gen/op helpers into this module.

Further tweak include:
- moving `path_arrays_from_ohlc()` back to module level
- slice out the last xy datum for `OHLCBarsAsCurveFmtr` 1d formatting
- always copy the new x-value from the source to `.x_nd`
2023-02-02 15:06:32 -05:00
Tyler Goodlet fbcd410ebe Drop diff state tracking in formatter
This was a major cause of error (particularly trying to get epoch
indexing working) and really isn't necessary; instead just have
`.diff()` always read from the underlying source array for current
index-step diffing and append/prepend slice construction.

Allows us to,
- drop `._last_read` state management and thus usage.
- better handle startup indexing by setting `.xy_nd_start/stop` to
  `None` initially so that the first update can be done in one large
  prepend.
- better understand and document the step curve "slice back to previous
  level" logic which is now heavily commented B)
- drop all the `slice_to_head` stuff from and instead allow each
  formatter to choose it's 1d segmenting.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 560782ebc0 Explicitly enable chart widget yranging in display init 2023-02-02 15:06:32 -05:00
Tyler Goodlet fcbdfb4e7a Enable/disable vlm chart yranging (TO SQUASH) 2023-02-02 15:06:32 -05:00
Tyler Goodlet e7ee0b343f Don't disable non-enabled vlm chart y-autoranging 2023-02-02 15:06:32 -05:00
Tyler Goodlet 43086029a2 Comment out bps for time indexing 2023-02-02 15:06:32 -05:00
Tyler Goodlet e4eb568b97 Call `Viz.bars_range()` from display loop 2023-02-02 15:06:32 -05:00
Tyler Goodlet d06f7ef679 Fix `.default_view()` to view-left-of-data 2023-02-02 15:06:32 -05:00
Tyler Goodlet 3633acb3c5 Add `Viz.index_field: str`, pass to graphics objs
In an effort to make it easy to override the indexing scheme.

Further, this repairs the `.datums_range()` special case to handle when
the view box is to-the-right-of the data set (i.e. l > datum_start).
2023-02-02 15:06:32 -05:00
Tyler Goodlet 2368ddadf2 Expect `index_field: str` in all graphics objects 2023-02-02 15:06:32 -05:00
Tyler Goodlet 87ffb23cb8 Facepalm: pass correct flume to each FSP chart group.. 2023-02-02 15:06:32 -05:00
Tyler Goodlet 99311b4f46 Attempt to make `.default_view()` time-index ready
As in make the call to `Flume.slice_from_time()` to try and convert any
time index values from the view range to array-indices; all untested
atm.

Also drop some old/unused/moved methods:
- `._set_xlimits()`
- `.bars_range()`
- `.curve_width_pxs()`

and fix some `flow` -> `viz` var naming.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 6252469ecc Simplify formatter update methodology
Don't expect values (array + slice) to be returned and applied by
`.incr_update_xy_nd()` and instead presume this will implemented
internally in each (sub)formatter.

Attempt to simplify some incr-update routines, (particularly in the step
curve formatter, though most of it was reverted to just a simpler form
of the original implementation XD) including:
- dropping the need for the `slice_to_head: int` control.
- using the `xy_nd_start/stop` index counters over custom lookups.
2023-02-02 15:06:32 -05:00
Tyler Goodlet a1dd0fb997 First attempt, field-index agnostic formatting
Remove harcoded `'index'` field refs from all formatters in a first
attempt at moving towards epoch-time alignment (though don't actually
use it it yet).

Adjustments to the formatter interface:
- property for `.xy_nd` the x/y nd arrays.
- property for and `.xy_slice` the nd format array(s) start->stop index
  slice.

Internal routine tweaks:
- drop `read_src_from_key` and always pass full source array on updates
  and adjust handlers to expect to have to index the data field of
  interest.
- set `.last_read` right after update calls instead of after 1d
  conversion.
- drop `slice_to_head` array read slicing.
- add some debug points for testing 'time' indexing (though not used
  here yet).
- add `.x_nd` array update logic for when the `.index_field` is not
  'index' - i.e. when we begin to try and support epoch time.
- simplify some new y_nd updates to not require use of `np.broadcast()`
  where possible.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 772d1f0f4e Pepper render routines with time-slice calls 2023-02-02 15:06:32 -05:00
Tyler Goodlet 440ff047e8 Add `Viz.bars_range()` (moved from chart API)
Call it from view kb loop.
2023-02-02 15:06:32 -05:00
Tyler Goodlet b72658e243 Make `Viz.slice_from_time()` take input array
Probably means it doesn't need to be a `Flume` method but it's
convenient to expect the caller to pass in the `np.ndarray` with
a `'time'` field instead of a `timeframe: str` arg; also, return the
slice mask instead of the sliced array as output (again allowing the
caller to do any slicing). Also, handle the slice-outside-time-range
case by just returning the entire index range with a `None` mask.

Adjust `Viz.view_data()` to instead do timeframe (for rt vs. hist shm
array) lookup and equiv array slicing with the returned mask.
2023-02-02 15:06:32 -05:00
Tyler Goodlet ee57f5c09f Add breakpoint on -ve range for now 2023-02-02 15:06:32 -05:00
Tyler Goodlet 1e586e7c85 Go back to hard-coded index field
Turns out https://github.com/numba/numba/issues/8622 is real
and the suggested `numba.literally` hack doesn't seem to work..
2023-02-02 15:06:32 -05:00
Tyler Goodlet e4a5dc55de Move `ui._compression`/`._pathops` to `.data` subpkg
Since these modules no longer contain Qt specific code we might
as well include them in the data sub-package.

Also, add `IncrementalFormatter.index_field` as single point to def the
indexing field that should be used for all x-domain graphics-data
rendering.
2023-02-02 15:06:32 -05:00
Tyler Goodlet 44c8c30327 Rename `.ui._flows.py` -> `.ui._render.py` 2023-02-02 15:06:32 -05:00
Tyler Goodlet 190c792515 Rename `Flow` -> `Viz`
The type is better described as a "data visualization":
https://en.wikipedia.org/wiki/Data_and_information_visualization

Add `ChartPlotWidget.get_viz()` to start working towards not accessing
the private table directly XD

We'll probably end up using the name `Flow` for a type that tracks
a collection of composed/cascaded `Flume`s:
https://en.wikipedia.org/wiki/Two-port_network#Cascade_connection
2023-02-02 15:06:32 -05:00
Tyler Goodlet d3a40678ff Copy timestamps from source to FSP dest buffer 2023-02-02 15:06:32 -05:00
Tyler Goodlet 07ab853d3d `Order.symbol` is a `str`.. 2023-02-02 15:05:26 -05:00
Tyler Goodlet 414866fc6b Assign pnl calc output for use when debugging 2023-02-02 15:05:26 -05:00
Tyler Goodlet bc7fe6114d Adjust order mode to use `Flume.get_index()` 2023-02-02 15:05:23 -05:00
Tyler Goodlet 8d592886fa Pass `Flume`s throughout FSP-ui and charting APIs
Since higher level charting and fsp management need access to the
new `Flume` indexing apis this adjusts some func sigs to pass through
(and/or create) flume instances:
- `LinkedSplits.add_plot()` and dependents.
- `ChartPlotWidget.draw_curve()` and deps, and it now returns a `Flow`.
- `.ui._fsp.open_fsp_admin()` and `FspAdmin.open_fsp_ui()` related
  methods => now we wrap the destination fsp shm in a flume on the admin
  side and is returned from `.start_engine_method()`.

Drop a bunch of (unused) chart widget methods including some already
moved to flume methods: `.get_index()`, `.in_view()`,
`.last_bar_in_view()`, `.is_valid_index()`.
2023-02-02 13:32:30 -05:00
Tyler Goodlet 69ea296a9b Max out per symbol throttle @ 22Hz 2023-02-02 13:32:30 -05:00
Tyler Goodlet 03821fdf6f Expect and update from by-type tick frames
Move to expect and process new by-tick-event frames where the display
loop can now just iterate the most recent tick events by type instead of
the entire tick history sequence - thus we reduce iterations inside the
update loop.

Also, go back to use using the detected display's refresh rate (minus 6)
as the default feed requested throttle rate since we can now handle
much more bursty-ness in display updates thanks to the new framing
format B)
2023-02-02 13:32:30 -05:00