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.
Files changed (47) hide show
  1. package/cpp/VroomChartHostObject.cpp +289 -2
  2. package/cpp/_core_include/vroom/vroom_chart.h +221 -4
  3. package/cpp/_core_src/atr.cpp +67 -0
  4. package/cpp/_core_src/atr.h +44 -0
  5. package/cpp/_core_src/atr_pane.cpp +162 -0
  6. package/cpp/_core_src/atr_pane.h +48 -0
  7. package/cpp/_core_src/chart.cpp +477 -172
  8. package/cpp/_core_src/chart.h +173 -1
  9. package/cpp/_core_src/chart_facade.cpp +317 -23
  10. package/cpp/_core_src/fair_value_gaps.cpp +76 -0
  11. package/cpp/_core_src/fair_value_gaps.h +54 -0
  12. package/cpp/_core_src/footprints.cpp +226 -0
  13. package/cpp/_core_src/footprints.h +45 -0
  14. package/cpp/_core_src/footprints_layout.cpp +140 -0
  15. package/cpp/_core_src/footprints_layout.h +94 -0
  16. package/cpp/_core_src/fvg_overlay.cpp +262 -0
  17. package/cpp/_core_src/fvg_overlay.h +43 -0
  18. package/cpp/_core_src/ichimoku.cpp +65 -0
  19. package/cpp/_core_src/ichimoku.h +45 -0
  20. package/cpp/_core_src/labels.cpp +3 -0
  21. package/cpp/_core_src/line_morph.h +159 -0
  22. package/cpp/_core_src/ma_overlay.cpp +259 -36
  23. package/cpp/_core_src/ma_overlay.h +57 -2
  24. package/cpp/_core_src/macd.cpp +24 -1
  25. package/cpp/_core_src/macd.h +16 -0
  26. package/cpp/_core_src/macd_pane.cpp +71 -62
  27. package/cpp/_core_src/macd_pane.h +13 -1
  28. package/cpp/_core_src/pane_series.h +169 -0
  29. package/cpp/_core_src/rsi.cpp +4 -0
  30. package/cpp/_core_src/rsi.h +7 -0
  31. package/cpp/_core_src/rsi_pane.cpp +85 -29
  32. package/cpp/_core_src/rsi_pane.h +11 -1
  33. package/cpp/_core_src/tip_pulse.h +4 -4
  34. package/cpp/_core_src/viewport.h +35 -0
  35. package/lib/index.d.mts +385 -3
  36. package/lib/index.d.ts +385 -3
  37. package/lib/index.js +305 -7
  38. package/lib/index.js.map +1 -1
  39. package/lib/index.mjs +305 -7
  40. package/lib/index.mjs.map +1 -1
  41. package/package.json +1 -1
  42. package/src/VroomChart.tsx +108 -7
  43. package/src/dataTransitions.ts +47 -0
  44. package/src/index.ts +10 -0
  45. package/src/jsi.d.ts +136 -1
  46. package/src/types.ts +10 -0
  47. package/src/useChartCore.ts +330 -5
@@ -0,0 +1,67 @@
1
+ #include "atr.h"
2
+
3
+ #include <algorithm> // std::max
4
+ #include <cmath> // std::fabs, std::nan
5
+
6
+ #include "ma.h"
7
+ #include "series_ma.h"
8
+
9
+ namespace vroom::atr {
10
+
11
+ void compute(const ::VroomCandle* candles, std::size_t n, int period,
12
+ int smoothing, std::vector<double>& out) {
13
+ out.assign(n, std::nan(""));
14
+ if (!candles || period < 1) return;
15
+ const std::size_t P = static_cast<std::size_t>(period);
16
+ if (n < P) return;
17
+
18
+ std::vector<double> tr(n);
19
+ tr[0] = candles[0].high - candles[0].low; // no previous close to gap from
20
+ for (std::size_t i = 1; i < n; ++i) {
21
+ const double prev_close = candles[i - 1].close;
22
+ tr[i] = std::max({candles[i].high - candles[i].low,
23
+ std::fabs(candles[i].high - prev_close),
24
+ std::fabs(candles[i].low - prev_close)});
25
+ }
26
+
27
+ if (smoothing == kSma) {
28
+ vroom::series_ma::smooth(tr, vroom::ma::KIND_SMA, period, out);
29
+ return;
30
+ }
31
+ if (smoothing == kEma) {
32
+ vroom::series_ma::smooth(tr, vroom::ma::KIND_EMA, period, out);
33
+ return;
34
+ }
35
+
36
+ // Wilder's RMA: seeded with the simple average of the first P true ranges,
37
+ // then avg = (prevAvg * (P - 1) + current) / P.
38
+ double avg = 0.0;
39
+ for (std::size_t i = 0; i < P; ++i) avg += tr[i];
40
+ avg /= static_cast<double>(P);
41
+ out[P - 1] = avg;
42
+
43
+ const double pm1 = static_cast<double>(P - 1);
44
+ const double pd = static_cast<double>(P);
45
+ for (std::size_t i = P; i < n; ++i) {
46
+ avg = (avg * pm1 + tr[i]) / pd;
47
+ out[i] = avg;
48
+ }
49
+ }
50
+
51
+ double autoscale(const double* visible, std::size_t n) {
52
+ double scale = 0.0;
53
+ if (!visible) return scale;
54
+ for (std::size_t i = 0; i < n; ++i) {
55
+ if (std::isfinite(visible[i])) scale = std::max(scale, visible[i]);
56
+ }
57
+ return scale;
58
+ }
59
+
60
+ double band_fraction(double v, double scale, double y_scale) {
61
+ // Nothing on show yet — everything sits on the baseline rather than
62
+ // dividing by zero.
63
+ if (!(scale > 0.0)) return 0.0;
64
+ return (v / scale) * kBandPadFraction * y_scale;
65
+ }
66
+
67
+ } // namespace vroom::atr
@@ -0,0 +1,44 @@
1
+ // Average True Range — pure computation, no Skia. Kept Skia-free so it builds
2
+ // into the unit-test target.
3
+ //
4
+ // True Range is the widest of the bar's own high-low span and the two gaps from
5
+ // its extremes to the previous close, so an overnight jump the bar's range
6
+ // misses still counts. ATR is that series smoothed over `period` bars.
7
+
8
+ #pragma once
9
+
10
+ #include <cstddef>
11
+ #include <vector>
12
+
13
+ #include "vroom/vroom_chart.h" // ::VroomCandle
14
+
15
+ namespace vroom::atr {
16
+
17
+ // How the true-range series is smoothed. kRma is Wilder's original
18
+ // (alpha = 1/period) and the conventional default.
19
+ enum Smoothing { kRma = 0, kSma = 1, kEma = 2 };
20
+
21
+ // How much of the pane band the curve is allowed to fill, so a peak stops short
22
+ // of the separator above it instead of touching.
23
+ constexpr double kBandPadFraction = 0.85;
24
+
25
+ // Computes ATR over [candles, candles+n). `period` is clamped to >= 1.
26
+ // Fills `out` (resized to n): out[i] is the ATR at candle i in price units, or
27
+ // NaN before the first defined value. True range exists from bar 0 (which has
28
+ // no previous close, so it falls back to high - low), so the first ATR lands at
29
+ // index period - 1 — one earlier than RSI.
30
+ void compute(const ::VroomCandle* candles, std::size_t n, int period,
31
+ int smoothing, std::vector<double>& out);
32
+
33
+ // The value the pane band is fitted to: the largest finite ATR on show, or 0
34
+ // when there is nothing to plot. ATR is strictly positive, so the domain runs
35
+ // from 0 at the band's bottom edge up to this.
36
+ double autoscale(const double* visible, std::size_t n);
37
+
38
+ // Where a value sits in the pane band, as a fraction of its height — 0 at the
39
+ // bottom edge, 1 at the top. `y_scale` is the user's y-axis zoom (1 = the
40
+ // default fit). Split out of the renderer so the interval-morph capture maps
41
+ // its geometry through the same math the pane draws with.
42
+ double band_fraction(double v, double scale, double y_scale);
43
+
44
+ } // namespace vroom::atr
@@ -0,0 +1,162 @@
1
+ #include "atr_pane.h"
2
+
3
+ #pragma clang diagnostic push
4
+ #pragma clang diagnostic ignored "-Wdocumentation"
5
+ #include "include/core/SkCanvas.h"
6
+ #include "include/core/SkColor.h"
7
+ #include "include/core/SkFont.h"
8
+ #include "include/core/SkFontTypes.h"
9
+ #include "include/core/SkPaint.h"
10
+ #include "include/core/SkPathBuilder.h"
11
+ #include "include/core/SkRect.h"
12
+ #include "include/core/SkTypeface.h"
13
+ #pragma clang diagnostic pop
14
+
15
+ #include <algorithm>
16
+ #include <cmath>
17
+ #include <cstdio>
18
+ #include <cstring>
19
+
20
+ #include "atr.h"
21
+ #include "chart.h"
22
+ #include "fonts.h"
23
+ #include "line_morph.h"
24
+ #include "pane_series.h"
25
+ #include "price_format.h"
26
+ #include "style_inherit.h"
27
+ #include "theme.h"
28
+ #include "viewport.h"
29
+
30
+ namespace vroom::atr_pane {
31
+
32
+ namespace {
33
+ using vroom::style::color_or;
34
+ using vroom::style::width_or;
35
+
36
+ constexpr SkColor kAtrLine = 0xff26a69a; // teal
37
+ constexpr SkColor kDivider = 0xff21262d; // pane separator
38
+ constexpr float kLineWidth = 1.5f;
39
+ } // namespace
40
+
41
+ void draw(SkCanvas* canvas,
42
+ const VroomChart& chart,
43
+ const Layout& lay,
44
+ const ::VroomCandle* visible,
45
+ std::size_t n,
46
+ const double* atr_visible,
47
+ int64_t window_ms,
48
+ int64_t visible_start_ms,
49
+ int64_t candle_duration_ms,
50
+ float candle_right,
51
+ float pane_top,
52
+ float pane_bottom,
53
+ const vroom::LineMorph* from,
54
+ float morph_t) {
55
+ if (!canvas || candle_right <= 0.f) return;
56
+ const float band_h = pane_bottom - pane_top;
57
+ if (band_h <= 0.f) return;
58
+ morph_t = std::clamp(morph_t, 0.f, 1.f);
59
+ // A fade's outgoing half has no new data at all, so the capture is the whole
60
+ // frame. Nothing on either side means nothing to paint, shell included.
61
+ if (n == 0 && vroom::morph_line_count(from, morph_t) == 0) return;
62
+
63
+ const VroomATR& cfg = chart.atr;
64
+
65
+ // ATR is strictly positive, so the domain runs 0..peak off the bottom edge.
66
+ // User y-zoom stretches it from there; 1.0 is the default fit.
67
+ const double scale = vroom::atr::autoscale(atr_visible, n);
68
+ auto y_for = [&](double v) -> float {
69
+ return pane_bottom -
70
+ static_cast<float>(
71
+ vroom::atr::band_fraction(v, scale, chart.atr_y_scale)) *
72
+ band_h;
73
+ };
74
+
75
+ // The peak the label reports. Mid-morph it eases out of the fit the capture
76
+ // was taken against, so the number tracks the curve instead of jumping to
77
+ // the new resolution's peak on the first frame.
78
+ const double label_scale =
79
+ (from && morph_t < 1.f)
80
+ ? from->scale + (scale - from->scale) * static_cast<double>(morph_t)
81
+ : scale;
82
+
83
+ // Mask the band (candles can overflow below the shortened price pane).
84
+ SkPaint bg;
85
+ bg.setColor(chart.theme.colors[VROOM_COLOR_BACKGROUND]);
86
+ canvas->drawRect(SkRect::MakeLTRB(0.f, pane_top, candle_right, pane_bottom),
87
+ bg);
88
+
89
+ // Pane separator (top edge).
90
+ SkPaint divider;
91
+ divider.setColor(kDivider);
92
+ divider.setStrokeWidth(1.f);
93
+ canvas->drawLine(0.f, pane_top, candle_right, pane_top, divider);
94
+
95
+ canvas->save();
96
+ canvas->clipRect(SkRect::MakeLTRB(0.f, pane_top, candle_right, pane_bottom));
97
+
98
+ if (atr_visible || from) {
99
+ SkPaint line;
100
+ line.setAntiAlias(true);
101
+ line.setColor(color_or(cfg.line_color, kAtrLine));
102
+ line.setStyle(SkPaint::kStroke_Style);
103
+ line.setStrokeWidth(width_or(cfg.line_width, kLineWidth));
104
+ canvas->drawPath(
105
+ vroom::pane_series::build_path(
106
+ lay, visible, n, atr_visible, window_ms, visible_start_ms,
107
+ candle_duration_ms, pane_top, pane_bottom, from, morph_t, y_for),
108
+ line);
109
+ }
110
+
111
+ // Caption, top-left of the pane.
112
+ auto tf = vroom::axis_typeface();
113
+ if (tf) {
114
+ SkFont font(tf, chart.theme.floats[VROOM_FLOAT_AXIS_FONT_SIZE_PX]);
115
+ font.setSubpixel(true);
116
+ font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
117
+ char caption[24];
118
+ std::snprintf(caption, sizeof(caption), "ATR %d", cfg.period);
119
+ SkRect cb;
120
+ font.measureText(caption, std::strlen(caption), SkTextEncoding::kUTF8,
121
+ &cb);
122
+ SkPaint cap_paint;
123
+ cap_paint.setAntiAlias(true);
124
+ cap_paint.setColor(chart.theme.colors[VROOM_COLOR_AXIS_TEXT]);
125
+ canvas->drawString(caption, 6.f, pane_top + 4.f - cb.fTop, font,
126
+ cap_paint);
127
+ }
128
+ canvas->restore();
129
+
130
+ // Peak label in the y-axis strip — ATR is in price units, so it shares the
131
+ // price axis's formatting. Hidden with that strip.
132
+ if (tf && label_scale > 0.0 && lay.y_axis_opacity > 0.f) {
133
+ SkFont font(tf, chart.theme.floats[VROOM_FLOAT_AXIS_FONT_SIZE_PX]);
134
+ font.setSubpixel(true);
135
+ font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
136
+ SkPaint text_paint;
137
+ text_paint.setAntiAlias(true);
138
+ text_paint.setColor(chart.theme.colors[VROOM_COLOR_AXIS_TEXT]);
139
+ text_paint.setAlphaf(text_paint.getAlphaf() * lay.y_axis_opacity);
140
+ char label[48];
141
+ vroom::format_price(label, sizeof(label), label_scale, chart.price_fmt);
142
+ SkRect tb;
143
+ const float tw = font.measureText(label, std::strlen(label),
144
+ SkTextEncoding::kUTF8, &tb);
145
+ const float axis_center_x = lay.width_px - lay.y_axis_width_px * 0.5f;
146
+ const float text_x = axis_center_x - tw * 0.5f;
147
+ // A series' own peak lands at the top of the padded band whatever the
148
+ // fit is, so the label's height doesn't move as the morph re-scales —
149
+ // only the number it reports does. Clamped into the band so a zoomed-in
150
+ // peak doesn't label another pane.
151
+ const float half_text = (tb.fBottom - tb.fTop) * 0.5f;
152
+ const float peak_y = std::clamp(
153
+ pane_bottom - static_cast<float>(vroom::atr::band_fraction(
154
+ label_scale, label_scale, chart.atr_y_scale)) *
155
+ band_h,
156
+ pane_top + half_text, pane_bottom - half_text);
157
+ const float baseline_y = peak_y - (tb.fTop + tb.fBottom) * 0.5f;
158
+ canvas->drawString(label, text_x, baseline_y, font, text_paint);
159
+ }
160
+ }
161
+
162
+ } // namespace vroom::atr_pane
@@ -0,0 +1,48 @@
1
+ // ATR indicator pane — draws the Average True Range line, its caption, and a
2
+ // peak label in the band below the candles. Its own module alongside
3
+ // rsi_pane / macd_pane so the chart orchestrator stays thin.
4
+
5
+ #pragma once
6
+
7
+ #include <cstddef>
8
+ #include <cstdint>
9
+
10
+ #include "vroom/vroom_chart.h" // ::VroomCandle
11
+
12
+ class SkCanvas;
13
+
14
+ namespace vroom {
15
+ struct Layout;
16
+ struct LineMorph;
17
+ } // namespace vroom
18
+
19
+ struct VroomChart;
20
+
21
+ namespace vroom::atr_pane {
22
+
23
+ // Draws the ATR pane spanning vertically [pane_top, pane_bottom]. `atr_visible`
24
+ // is the cached ATR series aligned with `visible` (NaN where undefined). ATR is
25
+ // strictly positive and unbounded, so the pane fits 0..peak anchored at its
26
+ // bottom edge rather than centering on a reference level.
27
+ //
28
+ // `from` / `morph_t` are the interval morph: the capture holds the curve's
29
+ // outgoing shape indexed from the right (slot 0 = newest), in fractions of the
30
+ // band, so the pane is free to re-fit across the switch without the shape
31
+ // moving. The peak label eases between the two fits. A fade's outgoing half
32
+ // passes n = 0 with morph_t = 0, which paints the capture alone.
33
+ void draw(SkCanvas* canvas,
34
+ const VroomChart& chart,
35
+ const Layout& lay,
36
+ const ::VroomCandle* visible,
37
+ std::size_t n,
38
+ const double* atr_visible,
39
+ int64_t window_ms,
40
+ int64_t visible_start_ms,
41
+ int64_t candle_duration_ms,
42
+ float candle_right,
43
+ float pane_top,
44
+ float pane_bottom,
45
+ const LineMorph* from = nullptr,
46
+ float morph_t = 1.f);
47
+
48
+ } // namespace vroom::atr_pane