Commit Graph

1752 Commits (9c88b26d85c46ca6016886c7cd2bcd7b65819400)

Author SHA1 Message Date
Tyler Goodlet 9c88b26d85 Add global profile timeout var 2022-04-01 13:27:07 -04:00
Tyler Goodlet 8686cf99fe 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-03-31 19:28:35 -04:00
Tyler Goodlet f9ec00e1ae First try, drop `FastAppendCurve` inheritance from `pg.PlotCurveItem` 2022-03-30 15:43:14 -04:00
Tyler Goodlet 25a3a123ec Get sync-to-marketstore-tsdb history retrieval workinnn 2022-03-30 14:11:21 -04:00
Tyler Goodlet 54466db554 Handle "fatal" level log msgs in docker super 2022-03-30 14:10:15 -04:00
Tyler Goodlet 6f06f646cf Get ib data feed hackzorz workin
ib has a throttle limit for "hft" bars but contained in here is some
hackery using ``xdotool`` to reset data farms auto-magically B)

This copies the working script into the ib backend mod as a routine and
now uses `trio.run_process()` and calls into it from the `get_bars()`
history retriever and then waits for "data re-established" events to be
received from the client before making more history queries.

TL;DR summary of changes:
- relay ib's "system status" events (like for data farm statuses)
  as a new "event" msg that can be processed by registers of
  `Client.inline_errors()` (though we should probably make a new
  method for this).
- add `MethodProxy.status_event()` which allows a proxy user to register
  for a particular "system event" (as mentioned above), which puts
  a `trio.Event` entry in a small table can be set by an relay task if
  there are any detected waiters.
- start a "msg relay task" when opening the method proxy which does
  the event setting mentioned above in the background.
- drop the request error handling around the proxy creation, doesn't
  seem necessary any more now that we have better error propagation from
  `asyncio`.
- add event waiting logic around the data feed reset hackzorin.
- change the order relay task to only log system events for now (though
  we need to do some better parsing/logic to get tws-external order
  updates to work again..
2022-03-30 13:49:19 -04:00
Tyler Goodlet 65d4c317c6 Drop commented line from pq method copy/paste 2022-03-29 14:11:31 -04:00
Tyler Goodlet 97439e882c Add basic tsdb history loading
If `marketstore` is detected try to only load most recent missing data
from the data provider (broker) and the rest from the tsdb and push it
all to shm for display in the UI. If the provider/broker doesn't have
the history client endpoint, just use the old one for now so we can
start to incrementally add support. Don't start the ohlc step
incrementer task until the backend signals that the feed is live.
2022-03-29 14:06:28 -04:00
Tyler Goodlet b5d566fed5 Drop `ms-shell`, add `piker storesh` cmd 2022-03-29 13:33:43 -04:00
Tyler Goodlet d3adb6dff7 Add diffing logic to `tsdb_history_update()`
Add some basic `numpy` epoch slice logic to generate append and prepend
arrays to write to the db.

Mooar cool things,
- add a `Storage.delete_ts()` method to wipe a column series from the db
  easily.
- don't attempt to read in any OHLC series by default on client load
- add some `pyqtgraph` profiling and drop manual latency measures
- if no db series for the fqsn exists write the entire shm array
2022-03-29 13:31:31 -04:00
Tyler Goodlet 22c81eb5bf Show baseline bars length on in view read < 6 2022-03-29 13:17:06 -04:00
Tyler Goodlet 41a8c23e44 Bump up resolution log scaling a mag 2022-03-29 13:15:59 -04:00
Tyler Goodlet 6bb1f06813 Drop `pandas` to `numpy` converter 2022-03-29 13:15:23 -04:00
Tyler Goodlet 72de184c08 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-03-29 13:13:51 -04:00
Tyler Goodlet 319a6fb66a Fix missing f-str prefix 2022-03-29 12:37:58 -04:00
Tyler Goodlet e7b1d77b08 Drop `pandas` use in ib backend for history
Found an issue (that was predictably brushed aside XD) where the
`ib_insync.util.df()` helper was changing the timestamps on bars data to
be way off (probably a `pandas.Timestamp` timezone thing?).

Anyway, dropped all that (which will hopefully let us drop `pandas` as
a hard dep) and added a buncha timestamp checking as well as start/end
datetime return values using `pendulum` so that consumer code can know
which "slice" is output.

Also added some WIP code to work around "no history found" request
errors where instead now we try to increment backward another 200
seconds - not sure if this actually correct yet.
2022-03-29 10:36:40 -04:00
Tyler Goodlet 3c5a799e97 More IB repairs..
Make the throttle error propagate through to `trio` again by adding
`dict`-msg support between the two loops such that errors can be
re-raised on the `trio` side. This is all integrated into the
`MethoProxy` and accompanying result relay task.

Further fix a longer standing issue where sometimes the `ib_insync`
order entry method will raise a weird assertion error because it detects
some internal order-id state issue.. Just ignore those and make relay
back an error to the ems in such cases.

Add a bunch of notes for todos surrounding data feed reset hackery.
2022-03-25 16:11:59 -04:00
Tyler Goodlet 544c6c3180 Start tinkering with `tractor.trionics.ipython_embed()`
In effort to get back to a usable REPL around the mkts client
this adds usage of the new `tractor` integration api as well as logic
for skipping backfilling if existing tsdb arrays are found.
2022-03-24 13:44:12 -04:00
Tyler Goodlet 4d2b5f9196 Clear ds line graphics on switch back to bars 2022-03-24 13:29:45 -04:00
Tyler Goodlet 4aaf5a1f8b Drop sampler consumers that overrun 6x 2022-03-24 13:29:07 -04:00
Tyler Goodlet 0cb05ef868 Strip broker name from symbol on pp msg updates 2022-03-24 13:28:06 -04:00
Tyler Goodlet 0676f3271c Add `Symbol.tokens()` for grabbing separate strs 2022-03-24 13:25:48 -04:00
Tyler Goodlet 34635c21a9 More ems resiliency: discard broken client dialogs 2022-03-24 13:23:34 -04:00
Tyler Goodlet 129ec9fc19 Allocate m4 output arrays in `numba` code, avoid segfaults? 2022-03-24 13:22:30 -04:00
Tyler Goodlet d2b42a46e6 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-03-24 09:21:44 -04:00
Tyler Goodlet fac1f86891 Try supporting reuse of path allocation 2022-03-23 17:29:56 -04:00
Tyler Goodlet 36b13012b4 Add optional mxmn oh tracer support to m4 sampler 2022-03-23 17:29:28 -04:00
Tyler Goodlet 9fcb1d3501 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-03-23 12:32:55 -04:00
Tyler Goodlet 96182c37f1 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-03-23 12:29:57 -04:00
Tyler Goodlet 7f350569df Attempt to better handle history throttles using flag 2022-03-22 13:14:22 -04:00
Tyler Goodlet 48ed07aa99 Delegate to m4 ohlc helper for curve, only ds on uppx steps > 2 2022-03-22 09:59:11 -04:00
Tyler Goodlet 7e5c8f4417 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-03-22 09:54:59 -04:00
Tyler Goodlet 01f06976ed M4 workin bishhhhh 2022-03-21 18:51:59 -04:00
Tyler Goodlet 8b89ba6111 Call default view on symbol switch 2022-03-21 15:27:46 -04:00
Tyler Goodlet ba797fcbee Make a derivs intrustment type table for alloc config checks 2022-03-21 15:25:45 -04:00
Tyler Goodlet 3b96b52474 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-03-21 09:25:37 -04:00
Tyler Goodlet 4af941566a 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-03-20 12:53:44 -04:00
Tyler Goodlet 01b594e828 Crypto$ backend updates
- move to 3.9+ type annots
- add initial draft `open_history_client()` endpoints
- deliver `'fqsn'` keys in quote-stream init msgs
2022-03-19 14:28:11 -04:00
Tyler Goodlet 197cad17a2 IB: Comment on lowercase for the fqsn key 2022-03-19 14:27:41 -04:00
Tyler Goodlet fb2f1fa488 Pass concatted pre-fqsn directly to feed api 2022-03-19 14:27:04 -04:00
Tyler Goodlet 532da9c590 Ensure we lower case the fqsn received from all backends before delivery 2022-03-19 14:26:28 -04:00
Tyler Goodlet e8c261279d Expect fqsn input to paper clearing engine 2022-03-19 13:48:04 -04:00
Tyler Goodlet e9e76e0626 Support no venue or suffix symbols (normally crypto$) 2022-03-19 13:47:25 -04:00
Tyler Goodlet df6f9b1c17 Comment exception debug in ib request error block 2022-03-18 17:53:21 -04:00
Tyler Goodlet 8e8c1c14ce Expect fqsn in ems and order mode
Use fqsn as input to the client-side EMS apis but strip broker-name
stuff before generating and sending `Brokerd*` msgs to each backend for
live order requests (since it's weird for a backend to expect it's own
name, though maybe that could be a sanity check?).

Summary of fqsn use vs. broker native keys:
- client side pps, order requests and general UX for order management
  use an fqsn for tracking
- brokerd side order dialogs use the broker-specific symbol which is
  usually nearly the same key minus the broker name
- internal dark book and quote feed lookups use the fqsn where possible
2022-03-18 17:52:23 -04:00
Tyler Goodlet 4c6e5598f2 Pass in fqsn from chart UI components 2022-03-18 15:07:48 -04:00
Tyler Goodlet 7a959e756d Pass in fqsn from fsp admin apis 2022-03-18 15:06:14 -04:00
Tyler Goodlet c0d1facf3b Append broker name to symbols before quotes broadcast in sampler task 2022-03-18 15:05:32 -04:00
Tyler Goodlet d03cd23571 Expect fqsns through fsp machinery 2022-03-18 15:04:15 -04:00
Tyler Goodlet a8cb6c2056 Make the data feed layer "fqsn" aware
In order to support instruments with lifetimes (aka derivatives) we need
generally need special symbol annotations which detail such meta data
(such as `MNQ.GLOBEX.20220717` for daq futes). Further there is really
no reason for the public api for this feed layer to care about getting
a special "brokername" field since generally the data is coming directly
from UIs (eg. search selection) so we might as well accept a fqsn (fully
qualified symbol name) which includes the broker name; for now a suffix
like `'.ib'`. We may change this schema (soon) but this at least gets us
to a point where we expect the full name including broker/provider.

An additional detail: for certain "generic" symbol names (like for
futes) we will pull a so called "front contract" and map this to
a specific fqsn underneath, so there is a double (cached) entry for that
entry such that other consumers can use it the same way if desired.

Some other machinery changes:
- expect the `stream_quotes()` endpoint to deliver it's `.started()` msg
  almost immediately since we now need it deliver any fqsn asap (yes
  this means the ep should no longer wait on a "live" first quote and
  instead deliver what quote data it can right away.
- expect the quotes ohlc sampler task to add in the broker name before
  broadcast to remote (actor) consumers since the backend isn't (yet)
  expected to do that add in itself.
- obviously we start using all the new fqsn related `Symbol` apis
2022-03-18 14:47:28 -04:00