react-native-vroom-chart 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cpp/VroomChartHostObject.cpp +289 -2
- package/cpp/_core_include/vroom/vroom_chart.h +221 -4
- package/cpp/_core_src/atr.cpp +67 -0
- package/cpp/_core_src/atr.h +44 -0
- package/cpp/_core_src/atr_pane.cpp +162 -0
- package/cpp/_core_src/atr_pane.h +48 -0
- package/cpp/_core_src/chart.cpp +477 -172
- package/cpp/_core_src/chart.h +173 -1
- package/cpp/_core_src/chart_facade.cpp +317 -23
- package/cpp/_core_src/fair_value_gaps.cpp +76 -0
- package/cpp/_core_src/fair_value_gaps.h +54 -0
- package/cpp/_core_src/footprints.cpp +226 -0
- package/cpp/_core_src/footprints.h +45 -0
- package/cpp/_core_src/footprints_layout.cpp +140 -0
- package/cpp/_core_src/footprints_layout.h +94 -0
- package/cpp/_core_src/fvg_overlay.cpp +262 -0
- package/cpp/_core_src/fvg_overlay.h +43 -0
- package/cpp/_core_src/ichimoku.cpp +65 -0
- package/cpp/_core_src/ichimoku.h +45 -0
- package/cpp/_core_src/labels.cpp +3 -0
- package/cpp/_core_src/line_morph.h +159 -0
- package/cpp/_core_src/ma_overlay.cpp +259 -36
- package/cpp/_core_src/ma_overlay.h +57 -2
- package/cpp/_core_src/macd.cpp +24 -1
- package/cpp/_core_src/macd.h +16 -0
- package/cpp/_core_src/macd_pane.cpp +71 -62
- package/cpp/_core_src/macd_pane.h +13 -1
- package/cpp/_core_src/pane_series.h +169 -0
- package/cpp/_core_src/rsi.cpp +4 -0
- package/cpp/_core_src/rsi.h +7 -0
- package/cpp/_core_src/rsi_pane.cpp +85 -29
- package/cpp/_core_src/rsi_pane.h +11 -1
- package/cpp/_core_src/tip_pulse.h +4 -4
- package/cpp/_core_src/viewport.h +35 -0
- package/lib/index.d.mts +385 -3
- package/lib/index.d.ts +385 -3
- package/lib/index.js +305 -7
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +305 -7
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/VroomChart.tsx +108 -7
- package/src/dataTransitions.ts +47 -0
- package/src/index.ts +10 -0
- package/src/jsi.d.ts +136 -1
- package/src/types.ts +10 -0
- package/src/useChartCore.ts +330 -5
package/cpp/_core_src/chart.h
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
#pragma once
|
|
10
10
|
|
|
11
11
|
#include <chrono>
|
|
12
|
+
#include <cstddef>
|
|
12
13
|
#include <string>
|
|
13
14
|
#include <vector>
|
|
14
15
|
|
|
@@ -22,13 +23,33 @@
|
|
|
22
23
|
#include "include/core/SkRefCnt.h"
|
|
23
24
|
#pragma clang diagnostic pop
|
|
24
25
|
|
|
26
|
+
#include "fair_value_gaps.h"
|
|
27
|
+
#include "footprints_layout.h"
|
|
25
28
|
#include "labels.h"
|
|
29
|
+
#include "line_morph.h"
|
|
26
30
|
#include "price_format.h"
|
|
27
31
|
#include "theme.h"
|
|
28
32
|
#include "viewport.h"
|
|
29
33
|
|
|
30
34
|
class SkCanvas;
|
|
31
35
|
|
|
36
|
+
namespace vroom {
|
|
37
|
+
|
|
38
|
+
// Which indicator owns a below-chart pane. Panes are otherwise
|
|
39
|
+
// interchangeable: they are all the same height and stack in enable order.
|
|
40
|
+
enum class PaneKind { Rsi, Macd, Atr };
|
|
41
|
+
|
|
42
|
+
// Count of PaneKind values — the most panes that can be stacked at once.
|
|
43
|
+
constexpr int kMaxPanes = 3;
|
|
44
|
+
|
|
45
|
+
// One enabled pane and the sequence number it claimed when it was turned on.
|
|
46
|
+
struct IndicatorPane {
|
|
47
|
+
int order;
|
|
48
|
+
PaneKind kind;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
} // namespace vroom
|
|
52
|
+
|
|
32
53
|
struct VroomChart {
|
|
33
54
|
// --- bridge / lifecycle -------------------------------------------------
|
|
34
55
|
VroomCallbacks cb{};
|
|
@@ -81,6 +102,19 @@ struct VroomChart {
|
|
|
81
102
|
std::vector<vroom::CandleSnapshot> morph_from;
|
|
82
103
|
float interval_morph_t = 1.f; // 1 = not morphing
|
|
83
104
|
bool interval_morph_fade = false;
|
|
105
|
+
// Set when the capture came from a live update rather than a timeframe
|
|
106
|
+
// switch. Same slot machinery, but the axis holds still: a stream morph
|
|
107
|
+
// only reshapes the last bar, and the ticks it sits between don't move, so
|
|
108
|
+
// running them through the interval envelope would flash the whole axis on
|
|
109
|
+
// every tick (see labels::interval_phase).
|
|
110
|
+
bool morph_is_stream = false;
|
|
111
|
+
// The outgoing shape of every indicator series that was on screen, captured
|
|
112
|
+
// alongside the candles and keyed by identity so a toggle landing in the
|
|
113
|
+
// same commit as the switch can't pair two different lines (see
|
|
114
|
+
// line_morph.h). A timeframe switch invalidates every indicator cache at
|
|
115
|
+
// once, so without this the lines would pop to their new values while the
|
|
116
|
+
// candles under them reshape.
|
|
117
|
+
std::vector<vroom::LineMorph> morph_lines;
|
|
84
118
|
// The pre-switch price scale and time window. The candle capture above is
|
|
85
119
|
// normalized against these, and the axes keep rendering their old ticks from
|
|
86
120
|
// them while fading out (see labels::interval_phase), so a label is never
|
|
@@ -122,7 +156,8 @@ struct VroomChart {
|
|
|
122
156
|
VroomRSI rsi{0, 14, 70.0, 30.0, 14, 0, 1,
|
|
123
157
|
0u, -1.f, 1, // RSI line
|
|
124
158
|
0u, -1.f, // trendline
|
|
125
|
-
0u, 1
|
|
159
|
+
0u, 1, // band rules
|
|
160
|
+
1}; // extreme shading
|
|
126
161
|
std::vector<double> rsi_cache; // RSI per candle (NaN where undefined)
|
|
127
162
|
std::vector<double> rsi_ma_cache; // MA of rsi_cache (empty if MA off)
|
|
128
163
|
bool rsi_dirty = true;
|
|
@@ -146,11 +181,23 @@ struct VroomChart {
|
|
|
146
181
|
// default auto-fit amplitude; >1 zooms in, <1 zooms out. Anchored at zero.
|
|
147
182
|
double macd_y_scale = 1.0;
|
|
148
183
|
|
|
184
|
+
// ATR, drawn in its own pane. atr_cache is aligned to `candles` (NaN
|
|
185
|
+
// warmup), recomputed lazily by ensure_atr() when atr_dirty.
|
|
186
|
+
// Defaults: 14-period true range under Wilder smoothing, style fields on
|
|
187
|
+
// their inherit sentinel.
|
|
188
|
+
VroomATR atr{0, 14, 0, 0u, -1.f};
|
|
189
|
+
std::vector<double> atr_cache;
|
|
190
|
+
bool atr_dirty = true;
|
|
191
|
+
// User y-axis zoom for the ATR pane (drag on its y-axis strip). 1.0 = the
|
|
192
|
+
// default 0..peak fit; >1 zooms in, <1 zooms out. Anchored at the baseline.
|
|
193
|
+
double atr_y_scale = 1.0;
|
|
194
|
+
|
|
149
195
|
// Stacking order for the indicator panes: each indicator gets the next
|
|
150
196
|
// sequence number on its off->on transition, so the most recently enabled
|
|
151
197
|
// pane sorts last (bottom). -1 = not currently enabled.
|
|
152
198
|
int rsi_order = -1;
|
|
153
199
|
int macd_order = -1;
|
|
200
|
+
int atr_order = -1;
|
|
154
201
|
int pane_seq = 0;
|
|
155
202
|
|
|
156
203
|
// Moving-average overlay lines (SMA/EMA) drawn on the price pane. Not panes
|
|
@@ -182,6 +229,46 @@ struct VroomChart {
|
|
|
182
229
|
std::vector<double> bb_lower_cache;
|
|
183
230
|
bool bollinger_dirty = true;
|
|
184
231
|
|
|
232
|
+
// Ichimoku overlay (price pane; no pane reserved). Caches aligned to
|
|
233
|
+
// `candles` (NaN warmup) and indexed by the bar each value was computed
|
|
234
|
+
// from — displacement is applied when drawing, so the caches survive a
|
|
235
|
+
// change to it. Recomputed lazily by ensure_ichimoku() when ichimoku_dirty.
|
|
236
|
+
// Defaults: the standard 9/26/52/26, blue tenkan / red kijun, green span A
|
|
237
|
+
// over orange span B, teal chikou, 15% cloud.
|
|
238
|
+
VroomIchimoku ichimoku{0, 9, 26, 52, 26,
|
|
239
|
+
0xff2962ff, 1.f, 1, // tenkan: blue
|
|
240
|
+
0xffef5350, 1.f, 1, // kijun: red
|
|
241
|
+
0xff26a69a, 1.f, 1, // senkou A: green
|
|
242
|
+
0xffff6d00, 1.f, 1, // senkou B: orange
|
|
243
|
+
0xff00bcd4, 1.f, 1, // chikou: teal
|
|
244
|
+
1, 0xff26a69a, 0xffef5350, 0.15f};
|
|
245
|
+
std::vector<double> ich_tenkan_cache;
|
|
246
|
+
std::vector<double> ich_kijun_cache;
|
|
247
|
+
std::vector<double> ich_senkou_a_cache;
|
|
248
|
+
std::vector<double> ich_senkou_b_cache;
|
|
249
|
+
std::vector<double> ich_chikou_cache;
|
|
250
|
+
bool ichimoku_dirty = true;
|
|
251
|
+
|
|
252
|
+
// Fair Value Gap overlay (price pane; no pane reserved). The cache holds the
|
|
253
|
+
// detected imbalances in absolute time/price, oldest first, so box geometry
|
|
254
|
+
// and style are free to change without re-scanning — only the detection
|
|
255
|
+
// inputs below dirty it. Recomputed lazily by ensure_fvg() when fvg_dirty.
|
|
256
|
+
//
|
|
257
|
+
// Defaults: 300 bars back, close-settled fills, deleted once filled, 20-slot
|
|
258
|
+
// boxes in green/red at 15%, solid 1px border, labels on.
|
|
259
|
+
VroomFairValueGaps fvg{0, 300, 0, 0, 1, 0, 20,
|
|
260
|
+
0xff26a69a, 0xffef5350, 0.15f,
|
|
261
|
+
1, 0, 1.f, 0xff26a69a, 0xffef5350,
|
|
262
|
+
1, nullptr, 10, 0u, 0.f,
|
|
263
|
+
0, 0xff26a69a, 0xffef5350, nullptr};
|
|
264
|
+
// Owns the label texts, so the caller may free theirs as soon as the setter
|
|
265
|
+
// returns. `fvg.label` and `fvg.inverse_label` are left null and these are
|
|
266
|
+
// what the renderer reads.
|
|
267
|
+
std::string fvg_label = "FVG";
|
|
268
|
+
std::string fvg_inverse_label = "iFVG";
|
|
269
|
+
std::vector<vroom::fvg::Gap> fvg_cache;
|
|
270
|
+
bool fvg_dirty = true;
|
|
271
|
+
|
|
185
272
|
// Volume bars (price pane, under the candles). On by default with every
|
|
186
273
|
// style field left on its inherit sentinel, so an untouched chart looks
|
|
187
274
|
// exactly as it did before the config existed. No cache — bar heights come
|
|
@@ -280,6 +367,28 @@ struct VroomChart {
|
|
|
280
367
|
int32_t dragged_price_line = -1;
|
|
281
368
|
double dragged_price_line_price = 0.0;
|
|
282
369
|
|
|
370
|
+
// --- footprints (executed-trade badges) ---------------------------------
|
|
371
|
+
// Kept in the *host's* order so the indices reported by
|
|
372
|
+
// vroom_chart_footprints_at map straight back to its own trade objects.
|
|
373
|
+
std::vector<VroomFootprint> footprints;
|
|
374
|
+
VroomFootprintStyle footprint_style{};
|
|
375
|
+
|
|
376
|
+
// Footprints grouped onto candles, which is what the renderer and hit-test
|
|
377
|
+
// actually walk. Derived from `footprints` + `candles`, so it is rebuilt
|
|
378
|
+
// lazily (see ensure_footprint_buckets) whenever either changes — that
|
|
379
|
+
// rebuild is what re-groups badges onto the right bars after an interval
|
|
380
|
+
// switch, with no involvement from the host.
|
|
381
|
+
std::vector<vroom::footprints::Bucket> footprint_buckets;
|
|
382
|
+
bool footprint_buckets_dirty = true;
|
|
383
|
+
|
|
384
|
+
// Which badge renders highlighted, keyed the way the hit-test reports it.
|
|
385
|
+
// side -1 = none.
|
|
386
|
+
int64_t hovered_footprint_time_ms = 0;
|
|
387
|
+
int32_t hovered_footprint_side = -1;
|
|
388
|
+
|
|
389
|
+
// Rebuilds footprint_buckets if either input changed since the last call.
|
|
390
|
+
void ensure_footprint_buckets();
|
|
391
|
+
|
|
283
392
|
// --- theme --------------------------------------------------------------
|
|
284
393
|
vroom::Theme theme;
|
|
285
394
|
|
|
@@ -325,6 +434,69 @@ struct VroomChart {
|
|
|
325
434
|
// indicator is enabled.
|
|
326
435
|
void ensure_bollinger();
|
|
327
436
|
|
|
437
|
+
// Recomputes the Ichimoku caches when ichimoku_dirty and the indicator is
|
|
438
|
+
// enabled.
|
|
439
|
+
void ensure_ichimoku();
|
|
440
|
+
|
|
441
|
+
// Redetects the Fair Value Gaps when fvg_dirty and the indicator is enabled.
|
|
442
|
+
void ensure_fvg();
|
|
443
|
+
|
|
444
|
+
// Recomputes the ATR cache when atr_dirty and the indicator is enabled.
|
|
445
|
+
void ensure_atr();
|
|
446
|
+
|
|
447
|
+
// Fills morph_lines with the outgoing shape of every enabled indicator,
|
|
448
|
+
// normalized the way morph_from is. Called by begin_interval_morph while
|
|
449
|
+
// the pre-switch candles and caches are still resident — after the swap
|
|
450
|
+
// there is nothing left to capture. `range` is the visible slice and
|
|
451
|
+
// `bounds` the price band the capture is taken against, both shared with
|
|
452
|
+
// the candle capture so the two land on the same pixels.
|
|
453
|
+
void capture_morph_lines(const vroom::Layout& lay,
|
|
454
|
+
const vroom::PriceBounds& bounds,
|
|
455
|
+
vroom::IndexRange range, int64_t window_ms);
|
|
456
|
+
|
|
457
|
+
// Source indices whose *displaced* plot time lands in the visible window,
|
|
458
|
+
// for an Ichimoku span drawn at `time_ms + shift_ms`. A bar of padding
|
|
459
|
+
// either side keeps a run reaching the pane edge instead of stopping at the
|
|
460
|
+
// last bar strictly inside it. Shared by the cloud, the lines and the
|
|
461
|
+
// interval-morph capture so all three slice the same bars.
|
|
462
|
+
vroom::IndexRange ichimoku_source_range(int64_t shift_ms) const;
|
|
463
|
+
|
|
464
|
+
// The enabled panes written to `out` top to bottom, returning how many.
|
|
465
|
+
// Both the draw pass and the y-axis hit test read this, so the stack they
|
|
466
|
+
// see can't drift apart.
|
|
467
|
+
int indicator_panes(vroom::IndicatorPane out[vroom::kMaxPanes]) const;
|
|
468
|
+
|
|
469
|
+
// Draws the pane stack into the band below the candles, starting at
|
|
470
|
+
// `pane_top`. Shared by the settled draw and the interval-morph fade, which
|
|
471
|
+
// paint the panes at different points in the z-order.
|
|
472
|
+
void draw_indicator_panes(SkCanvas* canvas, const vroom::Layout& lay,
|
|
473
|
+
const VroomCandle* visible, std::size_t n,
|
|
474
|
+
std::size_t first, int64_t window_ms,
|
|
475
|
+
float candle_right, float pane_top,
|
|
476
|
+
bool use_capture, float morph_t);
|
|
477
|
+
|
|
478
|
+
// The price-pane indicator overlays, split where the candles sit in the
|
|
479
|
+
// z-order: the Bollinger band and Ichimoku cloud go behind them, the moving
|
|
480
|
+
// averages, VWAP, Bollinger and Ichimoku lines over them.
|
|
481
|
+
//
|
|
482
|
+
// `use_capture` and `morph_t` carry the interval morph, on the same terms
|
|
483
|
+
// the candles take it. A transform pairs each series with its capture (see
|
|
484
|
+
// morph_lines) and eases toward the new shape. A fade's outgoing half
|
|
485
|
+
// passes n = 0 with morph_t = 0, replaying the capture alone. A settled
|
|
486
|
+
// frame passes no capture at all.
|
|
487
|
+
void draw_overlay_fills(SkCanvas* canvas, const vroom::Layout& lay,
|
|
488
|
+
const vroom::PriceBounds& bounds,
|
|
489
|
+
const VroomCandle* visible, std::size_t n,
|
|
490
|
+
std::size_t first, int64_t window_ms,
|
|
491
|
+
float candle_right, float candle_area_h,
|
|
492
|
+
bool use_capture, float morph_t);
|
|
493
|
+
void draw_overlay_lines(SkCanvas* canvas, const vroom::Layout& lay,
|
|
494
|
+
const vroom::PriceBounds& bounds,
|
|
495
|
+
const VroomCandle* visible, std::size_t n,
|
|
496
|
+
std::size_t first, int64_t window_ms,
|
|
497
|
+
float candle_right, float candle_area_h,
|
|
498
|
+
bool use_capture, float morph_t);
|
|
499
|
+
|
|
328
500
|
// The main drawing pass. Calls into the labels and candles modules, and owns
|
|
329
501
|
// the per-frame animation clock (see begin_frame) so every host gets it —
|
|
330
502
|
// the web build draws straight through vroom_chart_draw rather than the
|