PineForge unreleased
Deterministic PineScript v6 backtest runtime — C ABI reference
Loading...
Searching...
No Matches
ta.hpp
Go to the documentation of this file.
1#pragma once
2#include "na.hpp"
3#include "series.hpp"
4#include "window_sum.hpp"
5#include <deque>
6#include <cmath>
7#include <vector>
8#include <string>
9
10namespace pineforge {
11
12namespace ta {
13
14// How an ``EMA`` seeds its recursion. A per-instance option
15// (``EMA(length, seeding)``); an instance that names none latches the
16// ambient default below on its first ``compute()``.
17enum class EmaSeeding : unsigned char {
18 // ``ema := src`` on the first finite input, so the output is never na.
19 // The default, and byte-identical to every EMA before the option existed.
21 // na until ``length`` finite inputs have accumulated, then their simple
22 // average, then the ordinary recursion: an SMA-seeded EMA, warming up the
23 // way ``RMA`` and ``SMA`` already do (na for the whole warm-up window).
25};
26
27// Ambient default seeding for ``EMA`` instances constructed without one
28// (thread-local; ``false`` = ``EmaSeeding::FirstValue``, ``true`` =
29// ``EmaSeeding::SimpleAverage``; default ``false``).
30//
31// An instance reads it once, on its first ``compute()``, and keeps that
32// seeding for life, so a host that wants the instances of one evaluation
33// context SMA-seeded without naming the seeding at each construction raises
34// the reference around that context and restores it on exit (an RAII scope;
35// the restore must also run during unwinding). Thread-local so parallel
36// in-process engines never cross-contaminate. Nothing in the kernel raises
37// it: with the default, every EMA that names no seeding is the first-value
38// recursion, byte-identical to the behaviour before the option existed.
40
41// Per-context bar index for bar-addressed window state (thread-local).
42//
43// TradingView keeps the source history of a window call site (``ta.highest``,
44// ``ta.lowest``, ``ta.highestbars``, ``ta.lowestbars``) in a ring of
45// ``K = length + 1`` slots addressed by ``bar_index % K``. A call on bar ``b``
46// writes ``slot[b % K] = src`` and returns the extremum over the WRITTEN slots
47// ``(b - k) % K``, ``k in [0, length)``. For a call that executes every bar
48// that is the plain positional window. For a call that executes
49// CONDITIONALLY (inside an ``if`` block that does not run every bar) the slots
50// not rewritten keep their stale values from earlier executions, never-written
51// slots are skipped, and the result is na iff ``bar_index < length - 1`` — NOT
52// until ``length`` executions have accumulated. Pinned 2026-09-03 with
53// ``lab tv`` on NYSE:F 1D (``if bar_index % 7 == 3: v = ta.highest(high, 5)``
54// 39/39 entry sizes exact, cadence 9 30/30; production: colasbreugnon-sma
55// F@1D 31/31 only with K = 6). ``ta.sma`` inside ``if`` is NOT ring-addressed
56// (per-execution buffer, pinned separately) and is untouched.
57//
58// The engine installs the executing context's bar index around every dispatch
59// of generated code: the chart's Pine ``bar_index`` around ``on_bar`` and the
60// requested context's evaluated-bar index around each ``evaluate_security``
61// (HTF / lower-tf / auxiliary feeds). ``origin`` is the first bar index the
62// context has data for — the warmup reference — so a feed that starts after
63// TradingView's hidden first chart bar (``bar_index_offset``) still warms up
64// over its own first ``length`` bars, exactly as before. With no context
65// installed (the default — unit tests, standalone use) every ``compute()`` is
66// its own bar and the objects are byte-identical to the previous positional
67// deque.
68//
69// The ring is read through a cached extremum with an implied bar. Each call
70// site keeps ``{value, bar}``: the first call caches ``(src, b)``; a call on
71// bar ``b`` with ``b - bar < length`` only compares ``src`` against the cache
72// (strict — ties never displace the cached member); the new-extremum test
73// comes FIRST, so a bar whose ``src`` beats the cache takes it without
74// reading the slots even when the cache has aged out; otherwise, once the
75// cached extremum has aged out (``b - bar >= length`` — by bars, not calls)
76// the slots are rescanned, oldest first, and the cache becomes
77// ``(best, b - k_best)``; otherwise the cache is kept. The output is the
78// cached value (the *Bars offset is ``b - bar``). Pinned 2026-09-04 with 8
79// ``lab tv`` tapes on NYSE:F 1D (696/696 entries), the BINANCE:ETHUSDT.P
80// geometry pin (82/82) and the jayentriken BBWP ETH replay (593/593):
81// ``m = bar_index % 49; if m < 4 or 37 <= m < 47 or m == 48: v =
82// ta.lowest(low, 10)`` answers 9.88 (cached from bar 42) on bars 48..51
83// although bar 3's stale 9.20 sits one slot behind bar 48 — the plain ring
84// would say 9.20 — and rescans to 9.20 on bar 52 once the cache has aged;
85// on ETH the run-start bar 4990 (low 2648.62 < the expired cache 2650.47)
86// answers its own low and never reads the aliased 08:15 slot the plain ring
87// returned. For an every-bar caller the cache is exactly the positional
88// window, so nothing changes there.
89//
90// Never-written slots read 0 in a rescan, for every source kind (pinned
91// 2026-09-04 on BINANCE:BTCUSDT 1D and OANDA:XAUUSD 1D, cadence 13 / length
92// 10: ``low``, ``close - 2000``, ``sma(close, 5)``, ``low[1]``, ``hl2`` and
93// the sign-mixed ``sma(close, 5) - close`` each 13/13). A slot WRITTEN with
94// na POISONS the ring (pinned 2026-09-04 on OANDA:XAUUSD 1D, scratchpad
95// r6/pins/ringkind: leading-na sites 7 x 13/13, the market-logic replica
96// 32/32; and the every-bar NYSE:F 1D gap tape pin-lowest-na-everybar, 20/20;
97// ledger log-20260904t112527z-ea13dfcd): the rescan walks oldest first and a
98// written-na slot resets the running extremum, so the answer is the extremum
99// over the slots NEWER than the newest na slot in the window (never-written
100// 0 slots among them included) and na when the newest slot is itself na; the
101// na write also poisons the cache to ``(na, b)``, so the next valid call
102// restarts from its own src without reading the slots. ``ta.lowest(
103// sma(close, 14), 10)`` at cadence 13 answers na (bar 5 writes na), 2998
104// (bar 18: restart on src, the never-written slot behind it unread), 0, 0,
105// 0, 0 (rescans: never-written slots newer than the na slot), 3357.6 (bar
106// 83: the na slot re-entered at k = 1, src is the only live member), 3327.4
107// (new minimum), 2998, 2998, 2998, 2998 (the stale first valid write, once
108// newer than the na slot), 3112. Every-bar ``x = bar_index % 4 == 0 ? na :
109// low``: ``ta.lowest(x, 5) == ta.highest(x, 5)`` on the bar after every na
110// bar — a single live member — where the old "skip the gap" reading kept
111// the pre-gap extremum (bar 9: TV 9.20, the untouched cache 8.44).
113 bool installed = false;
114 long long bar_index = 0; // ring address: the context's current bar index
115 long long origin = 0; // warmup reference: the context's first bar index
116};
118
119// RAII installer: sets the thread-local BarContext for the enclosed dispatch
120// and restores the previous one on exit (also during stack unwinding), so
121// chart and request.security evaluation never see each other's index.
123 BarContext previous_;
124
125public:
126 BarContextScope(long long bar_index, long long origin);
130};
131
132// Bar-addressed extremum ring shared by Highest / Lowest / HighestBars /
133// LowestBars — the TradingView rule documented at bar_context() above.
135public:
136 struct Result {
137 double value; // na: window not formed yet, or no written non-na member
138 int bars_back; // k of the extremum slot (0 = the current bar)
139 };
141 // advance = true -> compute(): records src for the context's current bar
142 // advance = false -> recompute(): rewrites the current bar's slot
143 // An na src is WRITTEN: it answers na, poisons the cache and, in every
144 // later rescan, resets the running extremum (the poison rule documented
145 // at bar_context()). The composites (Stoch, WPR, Range) share the ring
146 // and the rule: their only oracle (finding 331, a stochRSI whose RSI is
147 // na for its warmup only) is a leading-na series, on which the poison
148 // answers exactly what "live over the non-na members" did.
149 // Ties resolve to the OLDEST member (strict comparison, oldest slot first).
150 Result update(double src, bool advance, bool want_max);
151 WindowCacheStats cache_stats() const { return values_.cache_stats(); }
152
153private:
154 int length_;
155 // Unwritten slots read zero; writing na stores that poison explicitly.
157 long long own_bar_ = -1; // cadence when no context is installed
158 bool has_written_ = false;
159 // TradingView's cached extremum with an implied bar (bar_context() docs):
160 // the value the site last answered and the bar it is attributed to.
161 bool cached_ = false;
162 double cval_ = 0.0;
163 long long cbar_ = 0;
164 // The cache as it stood BEFORE the current bar's first tick, so a
165 // recompute() (same bar, advance=false) restores it and re-applies.
166 long long cache_seen_bar_ = -1;
167 bool saved_cached_ = false;
168 double saved_cval_ = 0.0;
169 long long saved_cbar_ = 0;
170};
171
172class RMA {
173 double output_val;
174 double sum;
175 int length;
176 int bar_count;
177
178 // saved state for recompute
179 double saved_output_val_;
180 double saved_sum_;
181 int saved_bar_count_;
182
183public:
184 explicit RMA(int length);
185 double compute(double src);
186 void save();
187 void restore();
188 double recompute(double src);
189};
190
191class RSI {
192 RMA rma_up;
193 RMA rma_down;
194 double prev_src;
195 int bar_count;
196
197 // saved state for recompute
198 double saved_prev_src_;
199 int saved_bar_count_;
200
201public:
202 explicit RSI(int length);
203 double compute(double src);
204 double recompute(double src);
205};
206
208 double prev_a;
209 double prev_b;
210
211 double saved_prev_a_, saved_prev_b_;
212
213public:
215 bool compute(double a, double b);
216 bool recompute(double a, double b);
217};
218
220 double prev_a;
221 double prev_b;
222
223 double saved_prev_a_, saved_prev_b_;
224
225public:
227 bool compute(double a, double b);
228 bool recompute(double a, double b);
229};
230
231// --- SMA ---
232
233class SMA {
234 KahanWindowSum window_;
235 int length;
236 int bar_count;
237
238public:
239 explicit SMA(int length);
240 double compute(double src);
241 double recompute(double src);
242};
243
244// --- EMA ---
245
246class EMA {
247 double output_val;
248 double alpha;
249 double sum;
250 int bar_count;
251 // Read only by EmaSeeding::SimpleAverage, which counts `length` finite
252 // inputs before seeding with their mean. The FirstValue recursion uses
253 // `alpha` alone and never reads this.
254 int length_;
255
256 // saved state for recompute
257 double saved_output_val_;
258 double saved_sum_;
259 int saved_bar_count_;
260
261 // The instance's seeding (true = EmaSeeding::SimpleAverage): named by the
262 // two-argument constructor, or latched from ema_na_warmup_flag() on the
263 // first compute() and never revisited, so recompute()'s restore() (which
264 // only rewinds output_val/sum/bar_count) cannot flip the seeding
265 // mid-series. Deliberately NOT part of save()/restore().
266 bool na_warmup_ = false;
267 bool warmup_latched_ = false;
268
269public:
270 explicit EMA(int length);
271 // Names the seeding at construction; the ambient default is never read.
272 EMA(int length, EmaSeeding seeding);
273 double compute(double src);
274 void save();
275 void restore();
276 double recompute(double src);
277};
278
279// --- MACD ---
280
282 double macd_line;
284 double histogram;
285};
286
287class MACD {
288 EMA fast_ema;
289 EMA slow_ema;
290 EMA signal_ema;
291
292public:
293 MACD(int fast_length, int slow_length, int signal_length);
294 MACDResult compute(double src);
296};
297
298// --- Highest ---
299
300class Highest {
301 ExtremeRing ring_;
302
303public:
304 explicit Highest(int length);
305 double compute(double src);
306 double recompute(double src);
307};
308
309// --- Lowest ---
310
311class Lowest {
312 ExtremeRing ring_;
313
314public:
315 explicit Lowest(int length);
316 double compute(double src);
317 double recompute(double src);
318};
319
320// --- ATR ---
321
322class ATR {
323 RMA rma;
324 double prev_close;
325 int bar_count;
326
327 double saved_prev_close_;
328 int saved_bar_count_;
329
330public:
331 explicit ATR(int length);
332 double compute(double high, double low, double close);
333 double recompute(double high, double low, double close);
334 // issue #178 (pinned 2026-09-06, lab tv i178-sparse-atr-sense,
335 // BINANCE:BTCUSDT 60, 398/398 executions): TradingView's ta.atr called
336 // inside a block that does not execute every bar advances its RMA on
337 // the EXECUTIONS only, but the true range always reads the previous
338 // CHART bar's close (close[1]), never the close of the previous
339 // execution. The 3-arg path keeps the per-call prev_close for callers
340 // that run every bar (identical there); a sparse call site must pass
341 // the chart's previous close (BacktestEngine::prev_chart_close()).
342 double compute(double high, double low, double close, double prev_chart_close);
343 double recompute(double high, double low, double close, double prev_chart_close);
344};
345
346// --- Stoch ---
347
348class Stoch {
349 Highest highest;
350 Lowest lowest;
351
352public:
353 explicit Stoch(int length);
354 double compute(double src, double high, double low);
355 double recompute(double src, double high, double low);
356};
357
358// --- Change ---
359
360class Change {
361 std::deque<double> history;
362 int max_length_;
363
364public:
365 explicit Change(int max_length = 1);
366 double compute(double src, int length = 1);
367 double recompute(double src, int length = 1);
368};
369
370// --- Cross ---
371
372class Cross {
373 double prev_a;
374 double prev_b;
375 // Skip-tie state: TV's `ta.cross` tracks the last NON-TIED sign of
376 // (a - b) so that intermediate "tied" bars (a == b) are transparent.
377 // ta.crossover/ta.crossunder use the simpler immediate-prev rule and
378 // need no skip-tie state.
379 int last_nonzero_sign_; // -1, 0 (uninitialised), +1
380
381 double saved_prev_a_, saved_prev_b_;
382 int saved_last_nonzero_sign_;
383
384public:
386 bool compute(double a, double b);
387 bool recompute(double a, double b);
388};
389
390// --- WMA (Weighted Moving Average) ---
391
392class WMA {
393 int length_;
394 // Ring buffer (capacity == length_) instead of std::deque to avoid
395 // per-bar node allocation. Newest sample at offset 0, oldest at
396 // offset length_-1. The per-bar O(length) weighted-sum recompute is
397 // unchanged — see WMA::compute for the oldest→newest weight 1..length
398 // accumulation order that parity depends on.
400
401public:
402 explicit WMA(int length, WindowCacheCapacity cache = window_cache_capacity());
403 double compute(double src);
404 double recompute(double src);
405 WindowCacheStats cache_stats() const { return buffer_.cache_stats(); }
406};
407
408// --- HMA (Hull Moving Average) ---
409
410class HMA {
411 WMA wma_half_;
412 WMA wma_full_;
413 WMA wma_sqrt_;
414
415public:
416 explicit HMA(int length);
417 double compute(double src);
418 double recompute(double src);
419};
420
421// --- StdDev (Standard Deviation) ---
422// TradingView's ta.stdev (biased, the default) is NOT the two-pass
423// sum-of-squared-deviations of its documentation: it is
424// sqrt(Sxx / n - m * m), m = Sx / n,
425// with Sx = math.sum(src, n) and Sxx = math.sum(src * src, n) the same
426// sliding-window Kahan sums as ta.sma (window_sum.hpp) -- so the value carries
427// the cancellation error of that form and of those running sums. Pinned
428// 2026-09-05 (round 9, family W) on a full-precision NYSE:F@15 oracle
429// (pineforge-workflow famw-f15-sd-*: 7,029/7,029 bars bit-exact; the
430// two-pass form is exact on none of them). The unbiased variant
431// (biased = false) is unpinned and keeps the two-pass window arithmetic.
432class StdDev {
433 int length_;
434 bool biased_;
435 std::deque<double> buffer_; // unbiased path only
436 KahanWindowSum sum_x_; // Sx (biased path)
437 KahanWindowSum sum_xx_; // Sxx (biased path)
438 int bar_count_;
439
440public:
441 explicit StdDev(int length, bool biased = true);
442 double compute(double src);
443 double recompute(double src);
444
445private:
446 double held_stdev() const;
447 double biased_value() const;
448};
449
450// --- Supertrend ---
451
453 double value;
454 double direction;
455};
456
458 double factor_;
459 ATR atr_;
460 double prev_upper_, prev_lower_, prev_st_;
461 double prev_direction_;
462 double prev_close_;
463 bool initialized_;
464
465 // saved state
466 double saved_prev_upper_, saved_prev_lower_, saved_prev_st_;
467 double saved_prev_direction_, saved_prev_close_;
468 bool saved_initialized_;
469
470public:
471 Supertrend(double factor, int atr_period);
472 SupertrendResult compute(double high, double low, double close);
473 SupertrendResult recompute(double high, double low, double close);
474
475private:
476 SupertrendResult step(double high, double low, double close, bool again);
477};
478
479// --- DMI (Directional Movement Index) ---
480
481struct DMIResult {
482 double diplus;
483 double diminus;
484 double adx;
485};
486
487class DMI {
488 RMA rma_plus_, rma_minus_, rma_tr_;
489 RMA rma_adx_;
490 double prev_high_, prev_low_, prev_close_;
491 bool first_bar_;
492
493 // saved state
494 double saved_prev_high_, saved_prev_low_, saved_prev_close_;
495 bool saved_first_bar_;
496
497public:
498 DMI(int di_length, int adx_smoothing);
499 DMIResult compute(double high, double low, double close);
500 DMIResult recompute(double high, double low, double close);
501};
502
503// --- SAR (Parabolic SAR) ---
504
505class SAR {
506 double start_, increment_, maximum_;
507 double af_, ep_, sar_;
508 bool is_long_;
509 bool initialized_;
510 double prev_high_, prev_low_, prev_close_;
511 double prev_prev_high_, prev_prev_low_;
512
513 // saved state
514 double saved_af_, saved_ep_, saved_sar_;
515 bool saved_is_long_, saved_initialized_;
516 double saved_prev_high_, saved_prev_low_, saved_prev_close_;
517 double saved_prev_prev_high_, saved_prev_prev_low_;
518
519public:
520 SAR(double start, double increment, double maximum);
521 double compute(double high, double low, double close);
522 double recompute(double high, double low, double close);
523};
524
525// --- BB (Bollinger Bands) ---
526
527struct BBResult {
528 double middle;
529 double upper;
530 double lower;
531};
532
533class BB {
534 double mult_;
535 SMA sma_;
536 StdDev stdev_;
537
538public:
539 BB(int length, double mult);
540 BBResult compute(double src);
541 BBResult recompute(double src);
542};
543
544// --- KC (Keltner Channels) ---
545
546struct KCResult {
547 double middle;
548 double upper;
549 double lower;
550};
551
552// middle = EMA(src); the bands are middle +/- mult * EMA(range), where the
553// range is the true range against the previous bar's close (na where that
554// close is) or, with use_true_range = false, high - low. Omitting the flag is
555// the true range, value for value.
556class KC {
557 double mult_;
558 bool use_true_range_;
559 EMA ema_;
560 EMA range_ema_;
561 double prev_close_ = na<double>();
562 double saved_prev_close_ = na<double>();
563
564 double range_of(double high, double low) const;
565
566public:
567 KC(int length, double mult, bool use_true_range = true);
568 KCResult compute(double src, double high, double low, double close);
569 KCResult recompute(double src, double high, double low, double close);
570};
571
572// --- PivotHigh ---
573
575 int left_bars_, right_bars_;
576 std::deque<double> buffer_;
577
578public:
579 PivotHigh(int left_bars, int right_bars);
580 double compute(double src);
581 double recompute(double src);
582};
583
584// --- PivotLow ---
585
586class PivotLow {
587 int left_bars_, right_bars_;
588 std::deque<double> buffer_;
589
590public:
591 PivotLow(int left_bars, int right_bars);
592 double compute(double src);
593 double recompute(double src);
594};
595
596// --- Linreg (Linear Regression) ---
597
598class Linreg {
599 int length_;
600 std::deque<double> buffer_;
601
602public:
603 explicit Linreg(int length);
604 double compute(double src, double offset);
605 double recompute(double src, double offset);
606};
607
608// --- PercentRank ---
609
611 int length_;
612 std::deque<double> buffer_;
613
614public:
615 explicit PercentRank(int length);
616 double compute(double src);
617 double recompute(double src);
618};
619
620// --- VWMA (Volume-Weighted Moving Average) ---
621
622class VWMA {
623 int length_;
624 std::deque<double> sv_buffer_;
625 std::deque<double> v_buffer_;
626 double sv_sum_, v_sum_;
627
628public:
629 explicit VWMA(int length);
630 double compute(double src, double vol);
631 double recompute(double src, double vol);
632};
633
634// --- Mom (Momentum) ---
635
636class Mom {
637 int length_;
638 std::deque<double> buffer_;
639
640public:
641 explicit Mom(int length);
642 double compute(double src);
643 double recompute(double src);
644};
645
646// --- ROC (Rate of Change) ---
647
648class ROC {
649 int length_;
650 std::deque<double> buffer_;
651
652public:
653 explicit ROC(int length);
654 double compute(double src);
655 double recompute(double src);
656};
657
658// --- Rising ---
659
660class Rising {
661 int length_;
662 std::deque<double> buffer_;
663
664public:
665 explicit Rising(int length);
666 double compute(double src);
667 double recompute(double src);
668};
669
670// --- Falling ---
671
672class Falling {
673 int length_;
674 std::deque<double> buffer_;
675
676public:
677 explicit Falling(int length);
678 double compute(double src);
679 double recompute(double src);
680};
681
682// --- CCI (Commodity Channel Index) ---
683
684class CCI {
685 int length_;
686 std::deque<double> buffer_;
687
688public:
689 explicit CCI(int length);
690 double compute(double src);
691 double recompute(double src);
692};
693
694// --- Cum (Cumulative Sum) ---
695
696class Cum {
697 double sum_;
698
699 double saved_sum_;
700
701public:
703 double compute(double src);
704 double recompute(double src);
705};
706
707// --- Chart all-time max/min of a series (ta.max / ta.min single-arg) ---
708
710 double max_;
711 bool has_;
712
713 double saved_max_;
714 bool saved_has_;
715
716public:
718 double compute(double src);
719 double recompute(double src);
720};
721
723 double min_;
724 bool has_;
725
726 double saved_min_;
727 bool saved_has_;
728
729public:
731 double compute(double src);
732 double recompute(double src);
733};
734
735// --- RCI (Rank Correlation Index, Spearman × 100) ---
736
737class RCI {
738 int length_;
739 std::deque<double> buffer_;
740 std::vector<double> prices_;
741 std::vector<int> order_;
742 std::vector<double> price_rank_;
743
744 double calculate();
745
746public:
747 explicit RCI(int length);
748 double compute(double src);
749 double recompute(double src);
750};
751
752// --- Variance ---
753
754class Variance {
755 int length_;
756 bool biased_;
757 std::deque<double> buffer_;
758
759public:
760 explicit Variance(int length, bool biased = true);
761 double compute(double src);
762 double recompute(double src);
763};
764
765// --- Median ---
766
767class Median {
768 int length_;
769 std::deque<double> buffer_;
770 std::vector<double> scratch_;
771
772 double calculate();
773
774public:
775 explicit Median(int length);
776 double compute(double src);
777 double recompute(double src);
778};
779
780// --- HighestBars ---
781
783 ExtremeRing ring_;
784
785public:
786 explicit HighestBars(int length);
787 double compute(double src);
788 double recompute(double src);
789};
790
791// --- LowestBars ---
792
794 ExtremeRing ring_;
795
796public:
797 explicit LowestBars(int length);
798 double compute(double src);
799 double recompute(double src);
800};
801
802// --- ALMA (Arnaud Legoux Moving Average) ---
803// The Gaussian's centre is m = offset * (length - 1); with `floor` it is
804// floor(offset * (length - 1)) ("whether the offset calculation is floored
805// before ALMA is calculated", default false). Omitting floor is the unfloored
806// ALMA, value for value.
807class ALMA {
808 int length_;
809 double offset_, sigma_;
810 bool floor_;
811 std::deque<double> buffer_;
812 std::vector<double> weights_;
813
814public:
815 ALMA(int length, double offset = 0.85, double sigma = 6.0, bool floor = false);
816 double compute(double src);
817 double recompute(double src);
818};
819
820// Feature macro: ALMA takes the floor input (a fourth constructor argument).
821#define PF_ALMA_HAS_FLOOR 1
822
823// --- SWMA (Symmetrically Weighted Moving Average, period=4) ---
824
825class SWMA {
826 std::deque<double> buffer_;
827
828public:
830 double compute(double src);
831 double recompute(double src);
832};
833
834// --- MFI (Money Flow Index) ---
835
836class MFI {
837 int length_;
838 DynamicRingBuffer<double> pos_buffer_, neg_buffer_;
839 double prev_src_;
840 int bar_count_;
841
842 // saved state for recompute
843 double saved_prev_src_;
844 int saved_bar_count_;
845 DynamicRingBuffer<double> saved_pos_buffer_, saved_neg_buffer_;
846
847public:
848 explicit MFI(int length);
849 double compute(double src, double vol);
850 double recompute(double src, double vol);
851};
852
853// --- CMO (Chande Momentum Oscillator) ---
854
855class CMO {
856 int length_;
857 DynamicRingBuffer<double> up_buffer_, down_buffer_;
858 double prev_src_;
859 int bar_count_;
860
861 // saved state for recompute
862 double saved_prev_src_;
863 int saved_bar_count_;
864 DynamicRingBuffer<double> saved_up_buffer_, saved_down_buffer_;
865
866public:
867 explicit CMO(int length);
868 double compute(double src);
869 double recompute(double src);
870};
871
872// --- TSI (True Strength Index) ---
873
874class TSI {
875 EMA ema_long_;
876 EMA ema_short_;
877 EMA ema_abs_long_;
878 EMA ema_abs_short_;
879 double prev_src_;
880 int bar_count_;
881
882 double saved_prev_src_;
883 int saved_bar_count_;
884
885public:
886 TSI(int short_length, int long_length);
887 double compute(double src);
888 double recompute(double src);
889};
890
891// --- WPR (Williams %R) ---
892
893class WPR {
894 Highest highest_;
895 Lowest lowest_;
896
897public:
898 explicit WPR(int length);
899 double compute(double close, double high, double low);
900 double recompute(double close, double high, double low);
901};
902
903// --- COG (Center of Gravity) ---
904
905class COG {
906 int length_;
907 std::deque<double> buffer_;
908
909public:
910 explicit COG(int length);
911 double compute(double src);
912 double recompute(double src);
913};
914
915// --- BBW (Bollinger Bands Width) ---
916
917class BBW {
918 BB bb_;
919
920public:
921 BBW(int length, double mult);
922 double compute(double src);
923 double recompute(double src);
924};
925
926// --- KCW (Keltner Channel Width) ---
927
928class KCW {
929 KC kc_;
930
931public:
932 KCW(int length, double mult, bool use_true_range = true);
933 double compute(double src, double high, double low, double close);
934 double recompute(double src, double high, double low, double close);
935};
936
937// Feature macro: KC and KCW take the range choice (a third constructor
938// argument, use_true_range).
939#define PF_KC_HAS_USE_TRUE_RANGE 1
940
941// --- BarsSince ---
942
944 int count_;
945 bool ever_true_;
946
947 int saved_count_;
948 bool saved_ever_true_;
949
950public:
952 double compute(bool condition);
953 double recompute(bool condition);
954};
955
956// --- ValueWhen ---
957
959 std::deque<double> values_;
960 int max_occurrence_;
961
962 std::deque<double> saved_values_;
963
964public:
965 explicit ValueWhen(int max_occurrence = 1);
966 double compute(bool condition, double source, int occurrence);
967 double recompute(bool condition, double source, int occurrence);
968};
969
970// --- Correlation ---
971
973 int length_;
974 std::deque<double> x_buffer_, y_buffer_;
975
976public:
977 explicit Correlation(int length);
978 double compute(double src1, double src2);
979 double recompute(double src1, double src2);
980};
981
982// --- TR (True Range as function) ---
983
984class TR {
985 double prev_close_;
986 int bar_count_;
987 bool handle_na_;
988
989 double saved_prev_close_;
990 int saved_bar_count_;
991
992public:
993 explicit TR(bool handle_na = false);
994 double compute(double high, double low, double close);
995 double recompute(double high, double low, double close);
996 // issue #178: the sparse-call form — true range against the previous
997 // CHART bar's close (na on the first chart bar: handle_na decides).
998 double compute(double high, double low, double close, double prev_chart_close);
999 double recompute(double high, double low, double close, double prev_chart_close);
1000};
1001
1002// --- PercentileWindow ---
1003// The window TradingView ranks its nearest-rank and linear-interpolation
1004// percentiles over: one array kept across bars
1005// (tests/fixtures/percentile_window). Once `length` values are held, the value
1006// `length` bars back leaves at its first occurrence (na matching na) and the
1007// new value enters before the first held element greater than it: the held
1008// non-na values stay ascending, and na, greater than nothing and with nothing
1009// greater than it, enters last.
1011 int length_;
1012 std::deque<double> history_;
1013 std::vector<double> ranked_;
1014 // The last push, which a recompute of its bar undoes: where its value
1015 // entered, and the value that left and where it stood (-1: none left).
1016 int entered_at_ = -1;
1017 int left_at_ = -1;
1018 double left_value_ = na<double>();
1019
1020public:
1021 explicit PercentileWindow(int length);
1022 // The ranked array once `length` values are held, else null.
1023 const std::vector<double>* push(double src);
1024 // The bar's value replaced by `src` (a push when nothing was pushed yet).
1025 const std::vector<double>* repush(double src);
1026};
1027
1028// --- PercentileNearestRank ---
1029
1031 PercentileWindow window_;
1032
1033public:
1034 explicit PercentileNearestRank(int length);
1035 double compute(double src, double percentage);
1036 double recompute(double src, double percentage);
1037};
1038
1039// --- PercentileLinearInterpolation ---
1040
1042 PercentileWindow window_;
1043
1044public:
1045 explicit PercentileLinearInterpolation(int length);
1046 double compute(double src, double percentage);
1047 double recompute(double src, double percentage);
1048};
1049
1050// --- Volume indicators ---
1051class OBV {
1052 double sum_ = 0.0;
1053 double prev_close_ = na<double>();
1054 int bar_count_ = 0;
1055
1056 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1057 // before the first compute() restores a well-defined pristine state.
1058 double saved_sum_ = 0.0, saved_prev_close_ = na<double>();
1059 int saved_bar_count_ = 0;
1060
1061public:
1062 OBV() = default;
1063 double compute(double close, double volume);
1064 double recompute(double close, double volume);
1065};
1066
1067class AccDist {
1068 double sum_ = 0.0;
1069
1070 // Mirror the initial committed sum_ (see RMA::RMA) so a recompute()
1071 // before the first compute() restores a well-defined pristine state.
1072 double saved_sum_ = 0.0;
1073
1074public:
1075 AccDist() = default;
1076 double compute(double high, double low, double close, double volume);
1077 double recompute(double high, double low, double close, double volume);
1078};
1079
1080class NVI {
1081 double nvi_ = 1.0;
1082 double prev_close_ = na<double>();
1083 double prev_volume_ = na<double>();
1084 int bar_count_ = 0;
1085
1086 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1087 // before the first compute() restores a well-defined pristine state.
1088 double saved_nvi_ = 1.0, saved_prev_close_ = na<double>(),
1089 saved_prev_volume_ = na<double>();
1090 int saved_bar_count_ = 0;
1091
1092public:
1093 NVI() = default;
1094 double compute(double close, double volume);
1095 double recompute(double close, double volume);
1096};
1097
1098class PVI {
1099 double pvi_ = 1.0;
1100 double prev_close_ = na<double>();
1101 double prev_volume_ = na<double>();
1102 int bar_count_ = 0;
1103
1104 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1105 // before the first compute() restores a well-defined pristine state.
1106 double saved_pvi_ = 1.0, saved_prev_close_ = na<double>(),
1107 saved_prev_volume_ = na<double>();
1108 int saved_bar_count_ = 0;
1109
1110public:
1111 PVI() = default;
1112 double compute(double close, double volume);
1113 double recompute(double close, double volume);
1114};
1115
1116class PVT {
1117 double pvt_ = 0.0;
1118 double prev_close_ = na<double>();
1119
1120 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1121 // before the first compute() restores a well-defined pristine state.
1122 double saved_pvt_ = 0.0, saved_prev_close_ = na<double>();
1123
1124public:
1125 PVT() = default;
1126 double compute(double close, double volume);
1127 double recompute(double close, double volume);
1128};
1129
1130class WAD {
1131 double wad_ = 0.0;
1132 double prev_close_ = na<double>();
1133
1134 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1135 // before the first compute() restores a well-defined pristine state.
1136 double saved_wad_ = 0.0, saved_prev_close_ = na<double>();
1137
1138public:
1139 WAD() = default;
1140 double compute(double high, double low, double close);
1141 double recompute(double high, double low, double close);
1142};
1143
1144class WVAD {
1145public:
1146 WVAD() = default;
1147 double compute(double open, double high, double low, double close, double volume);
1148 double recompute(double open, double high, double low, double close, double volume);
1149};
1150
1151class III {
1152public:
1153 III() = default;
1154 double compute(double high, double low, double close, double volume);
1155 double recompute(double high, double low, double close, double volume);
1156};
1157
1158// --- VWAP Bands result (3-tuple: vwap, upper_band, lower_band) ---
1160 double vwap;
1161 double upper;
1162 double lower;
1163};
1164
1165class VWAP {
1166 double cum_pv_ = 0.0;
1167 double cum_vol_ = 0.0;
1168 // Sum of (price^2 * volume) for running variance computation used by
1169 // compute_bands(). Variance = cum_pv_sq_ / cum_vol_ - mean^2.
1170 double cum_pv_sq_ = 0.0;
1171 // Anchor day index: the SESSION day of the bar (session_day_index —
1172 // timestamp_ms / 86_400_000 on a UTC/24x7 symbol, the 17:00-ET-keyed
1173 // trading day on forex, the 09:30 RTH day on equities). On the first
1174 // compute() call we record this from the bar timestamp; on every
1175 // subsequent compute() the cumulator is reset whenever the day index
1176 // advances. Pine v6 `ta.vwap(source)` defaults to a Daily anchor
1177 // (`anchor = timeframe.change("1D")` on the SYMBOL's daily bar); the
1178 // engine matches that when the codegen threads syminfo tz + session.
1179 int64_t anchor_day_ = std::numeric_limits<int64_t>::min();
1180
1181 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1182 // before the first compute() restores a well-defined pristine state.
1183 double saved_cum_pv_ = 0.0, saved_cum_vol_ = 0.0, saved_cum_pv_sq_ = 0.0;
1184 int64_t saved_anchor_day_ = std::numeric_limits<int64_t>::min();
1185
1186 void roll_anchor(int64_t day);
1187
1188public:
1189 VWAP() = default;
1190 // tz-less forms key the anchor on the UTC day (the 24x7 corpus regime);
1191 // the tz/session forms key it on the symbol's session day and reduce to
1192 // the same integer math for tz="UTC" + empty/"24x7" session.
1193 // Feature macro PF_VWAP_HAS_SESSION_ANCHOR (below the class) lets
1194 // generated code compile the (tz, session) tail out on older engines.
1195 double compute(double src, double volume, int64_t timestamp_ms);
1196 double recompute(double src, double volume, int64_t timestamp_ms);
1197 double compute(double src, double volume, int64_t timestamp_ms,
1198 const std::string& tz, const std::string& session);
1199 double recompute(double src, double volume, int64_t timestamp_ms,
1200 const std::string& tz, const std::string& session);
1201 VWAPBandsResult compute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult);
1202 VWAPBandsResult recompute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult);
1203 VWAPBandsResult compute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult,
1204 const std::string& tz, const std::string& session);
1205 VWAPBandsResult recompute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult,
1206 const std::string& tz, const std::string& session);
1207};
1208
1209// Feature macro: the emitted prelude's PF_VWAP_SESSION_ANCHOR_ARGS(tz, s)
1210// expands to `, tz, s` only when this is defined (see VWAP overloads above).
1211#define PF_VWAP_HAS_SESSION_ANCHOR 1
1212
1213// --- VWAP Bands wrapper class (3-tuple form: ta.vwap(src, anchor, stdev_mult)) ---
1214// Wraps VWAP and routes compute/recompute to compute_bands/recompute_bands with
1215// a fixed stdev_mult supplied at construction time. This lets the codegen use
1216// the standard .compute()/.recompute() dispatch pattern for tuple returns.
1218 VWAP vwap_;
1219 double stdev_mult_;
1220public:
1221 explicit VWAPBands(double stdev_mult) : stdev_mult_(stdev_mult) {}
1222 VWAPBandsResult compute(double src, double volume, int64_t timestamp_ms) {
1223 return vwap_.compute_bands(src, volume, timestamp_ms, stdev_mult_);
1224 }
1225 VWAPBandsResult recompute(double src, double volume, int64_t timestamp_ms) {
1226 return vwap_.recompute_bands(src, volume, timestamp_ms, stdev_mult_);
1227 }
1228 VWAPBandsResult compute(double src, double volume, int64_t timestamp_ms,
1229 const std::string& tz, const std::string& session) {
1230 return vwap_.compute_bands(src, volume, timestamp_ms, stdev_mult_, tz, session);
1231 }
1232 VWAPBandsResult recompute(double src, double volume, int64_t timestamp_ms,
1233 const std::string& tz, const std::string& session) {
1234 return vwap_.recompute_bands(src, volume, timestamp_ms, stdev_mult_, tz, session);
1235 }
1236};
1237
1238// --- Anchored VWAP (the accumulation restarts where the caller says) ---
1239// VWAP over the bars since the most recent bar whose `anchor` was true, that
1240// bar included: an anchored bar starts a new accumulation, and until the first
1241// anchored bar the value is na (ta.vwap's anchor: "When true, calculations
1242// reset"; "Calculations only begin the first time the anchor condition
1243// becomes true. Until then, the function returns na"). The arithmetic is
1244// VWAP's -- running sums of src * volume, src * src * volume and volume, the
1245// bands mean +/- stdev_mult * sqrt(max(0, sum(src*src*volume) / sum(volume) -
1246// mean * mean)) -- so an anchor raised on the bars where VWAP's session day
1247// changes, and on the first bar, reproduces VWAP bit for bit. An na src or
1248// volume answers na and adds nothing; an anchor on such a bar still resets the
1249// sums. A zero summed volume answers na. recompute() re-runs the current bar
1250// from the state its first compute() found, anchor included.
1252 double cum_pv_ = 0.0;
1253 double cum_vol_ = 0.0;
1254 double cum_pv_sq_ = 0.0;
1255 bool started_ = false; // an anchored bar has been seen
1256
1257 // Mirror the initial committed state (see RMA::RMA) so a recompute()
1258 // before the first compute() restores a well-defined pristine state.
1259 double saved_cum_pv_ = 0.0, saved_cum_vol_ = 0.0, saved_cum_pv_sq_ = 0.0;
1260 bool saved_started_ = false;
1261
1262 // Folds one bar into the sums; false when the bar has no value.
1263 bool accumulate(double src, double volume, bool anchor);
1264
1265public:
1266 AnchoredVWAP() = default;
1267 double compute(double src, double volume, bool anchor);
1268 double recompute(double src, double volume, bool anchor);
1269 VWAPBandsResult compute_bands(double src, double volume, bool anchor, double stdev_mult);
1270 VWAPBandsResult recompute_bands(double src, double volume, bool anchor, double stdev_mult);
1271};
1272
1273// The 3-tuple form with a construction-time stdev_mult, for the standard
1274// compute()/recompute() dispatch (VWAPBands' shape). A per-bar multiplier goes
1275// through AnchoredVWAP::compute_bands directly.
1277 AnchoredVWAP vwap_;
1278 double stdev_mult_;
1279public:
1280 explicit AnchoredVWAPBands(double stdev_mult) : stdev_mult_(stdev_mult) {}
1281 VWAPBandsResult compute(double src, double volume, bool anchor) {
1282 return vwap_.compute_bands(src, volume, anchor, stdev_mult_);
1283 }
1284 VWAPBandsResult recompute(double src, double volume, bool anchor) {
1285 return vwap_.recompute_bands(src, volume, anchor, stdev_mult_);
1286 }
1287};
1288
1289// Feature macro: AnchoredVWAP / AnchoredVWAPBands exist (generated code may
1290// compile an anchored call site out on older engines, as with
1291// PF_VWAP_HAS_SESSION_ANCHOR).
1292#define PF_VWAP_HAS_ANCHOR_INPUT 1
1293
1294// --- Statistical ---
1295class Mode {
1296 struct CountEntry {
1297 double value = na<double>();
1298 int count = 0;
1299 unsigned char state = 0; // 0 empty, 1 occupied, 2 deleted
1300 };
1301
1302 int length_;
1303 std::deque<double> buffer_;
1304 std::vector<CountEntry> counts_;
1305
1306 void add_count(double value);
1307 void remove_count(double value);
1308 double current_mode() const;
1309
1310public:
1311 explicit Mode(int length);
1312 double compute(double src);
1313 double recompute(double src);
1314};
1315
1316class Range {
1317 Highest highest_;
1318 Lowest lowest_;
1319public:
1320 explicit Range(int length) : highest_(length), lowest_(length) {}
1321 double compute(double src);
1322 double recompute(double src);
1323};
1324
1325class Dev {
1326 int length_;
1327 std::deque<double> buffer_;
1328public:
1329 explicit Dev(int length) : length_(length) {}
1330 double compute(double src);
1331 double recompute(double src);
1332};
1333
1334// --- pivot_point_levels (free function) ---
1335// The 11 pivot levels [P, R1, S1, R2, S2, R3, S3, R4, S4, R5, S5] of one
1336// period's high, low and close, na for the levels a type does not define and
1337// all na for a missing input; an unknown name answers P alone. Traditional,
1338// Fibonacci, Classic and Camarilla are PivotPointLevels' formulas bit for bit.
1339// Woodie and DM are a historical approximation kept for source compatibility:
1340// this signature carries neither the next period's open, which Woodie's pivot
1341// weights (it weights the close, and spaces R3..S4 as Classic does), nor the
1342// period's open, which DM compares with the close (it branches on the close
1343// meeting the high or the low). The overload below takes both, and
1344// ta::PivotPointLevels is the TradingView form.
1345std::vector<double> pivot_point_levels(const std::string& method,
1346 double high, double low, double close);
1347
1348// The same 11 levels from the period's open, high, low and close and the open
1349// of the period after it -- the period the levels are for -- for every type as
1350// PivotPointLevels computes them: anchored on every bar with developing =
1351// false, its levels on a bar are this overload's of the bar before (open,
1352// high, low, close) and the bar's own open, bit for bit. Only Woodie reads
1353// next_open and only DM reads open; a formula missing an input it reads leaves
1354// all eleven na. The type by name: pivot_levels_type(), which throws
1355// std::invalid_argument for any other.
1356std::vector<double> pivot_point_levels(const std::string& method, double open, double high,
1357 double low, double close, double next_open);
1358
1359// --- Pivot point levels of an anchored period ---
1360// The six pivot types. DM is DeMark's.
1361enum class PivotLevelsType : unsigned char {
1366 DM = 4,
1368};
1369
1370// The type spelled "Traditional", "Fibonacci", "Woodie", "Classic", "DM" or
1371// "Camarilla"; std::invalid_argument for any other name.
1372PivotLevelsType pivot_levels_type(const std::string& name);
1373
1374// The 11 pivot levels [P, R1, S1, R2, S2, R3, S3, R4, S4, R5, S5] of a
1375// period of bars, na for the levels a type does not define. A period runs
1376// from an anchored bar (bar 0 before the first anchor) to the bar before the
1377// next anchored bar; a period is aggregated as its first finite open, highest
1378// finite high, lowest finite low and last finite close.
1379//
1380// developing = false: the levels computed on the last anchored bar, from the
1381// period that bar closed (and, for Woodie, that bar's own open -- the open of
1382// the period the levels are for), held until the next anchored bar; all na
1383// before the first anchored bar that closes a non-empty period.
1384// developing = true: the levels of the period in progress, this bar included,
1385// recomputed on every bar (DM reads the period's own open). Woodie has no
1386// developing levels -- its levels need the open of the period after the one
1387// measured -- so compute() and recompute() throw std::runtime_error for that
1388// pair, which fails a run as any exception out of a script callback does.
1389//
1390// The formulas are the standard pivot definitions, Traditional's R3..S5 and
1391// Woodie's among them, evaluated operation by operation as written: P =
1392// (H + L + C) / 3, R1 = P * 2 - L, ..., R3 = P * 2 + (H - 2 * L), ..., R5 =
1393// P * 4 + (H - 4 * L); Woodie P = (H + L + 2 * O_next) / 4, R3 = H + 2 * (P -
1394// L), R4 = R3 + (H - L); DM X = O == C ? H + L + 2 * C : C > O ? 2 * H + L +
1395// C : 2 * L + H + C, P = X / 4, R1 = X / 2 - L, S1 = X / 2 - H; Camarilla R1 =
1396// C + 1.1 * (H - L) / 12, ..., R5 = (H / L) * C (na on a zero low), S5 = C -
1397// (R5 - C). Anchored on every bar with developing = false, this is the
1398// six-argument free function above for every type, and the four-argument one
1399// for every type but Woodie and DM.
1400// recompute() re-runs the current bar from the state its first compute()
1401// found.
1403public:
1404 PivotPointLevels() = default;
1405 std::vector<double> compute(PivotLevelsType type, bool anchor, bool developing,
1406 double open, double high, double low, double close);
1407 std::vector<double> recompute(PivotLevelsType type, bool anchor, bool developing,
1408 double open, double high, double low, double close);
1409 // The type by name (pivot_levels_type()).
1410 std::vector<double> compute(const std::string& type, bool anchor, bool developing,
1411 double open, double high, double low, double close);
1412 std::vector<double> recompute(const std::string& type, bool anchor, bool developing,
1413 double open, double high, double low, double close);
1414
1415private:
1416 struct Period {
1417 double open = na<double>();
1418 double high = na<double>();
1419 double low = na<double>();
1420 double close = na<double>();
1421 void enter(double o, double h, double l, double c);
1422 };
1423 struct Levels {
1424 double v[11];
1425 };
1426 static Levels no_levels();
1427
1428 Period period_; // the period in progress
1429 Levels held_ = no_levels(); // the levels of the last closed period
1430 Period saved_period_;
1431 Levels saved_held_ = no_levels();
1432};
1433
1434// Feature macro: PivotPointLevels / PivotLevelsType / pivot_levels_type exist.
1435#define PF_PIVOT_LEVELS_HAS_ANCHOR 1
1436
1437} // namespace ta
1438
1439} // namespace pineforge
double compute(double src)
double recompute(double src)
ALMA(int length, double offset=0.85, double sigma=6.0, bool floor=false)
double recompute(double high, double low, double close)
double recompute(double high, double low, double close, double prev_chart_close)
double compute(double high, double low, double close)
double compute(double high, double low, double close, double prev_chart_close)
double compute(double high, double low, double close, double volume)
double recompute(double high, double low, double close, double volume)
double recompute(double src)
double compute(double src)
double recompute(double src)
double compute(double src)
VWAPBandsResult compute(double src, double volume, bool anchor)
Definition ta.hpp:1281
AnchoredVWAPBands(double stdev_mult)
Definition ta.hpp:1280
VWAPBandsResult recompute(double src, double volume, bool anchor)
Definition ta.hpp:1284
double recompute(double src, double volume, bool anchor)
double compute(double src, double volume, bool anchor)
VWAPBandsResult recompute_bands(double src, double volume, bool anchor, double stdev_mult)
VWAPBandsResult compute_bands(double src, double volume, bool anchor, double stdev_mult)
double compute(double src)
double recompute(double src)
BBW(int length, double mult)
BBResult recompute(double src)
BB(int length, double mult)
BBResult compute(double src)
BarContextScope(const BarContextScope &)=delete
BarContextScope & operator=(const BarContextScope &)=delete
BarContextScope(long long bar_index, long long origin)
double compute(bool condition)
double recompute(bool condition)
double compute(double src)
double recompute(double src)
double recompute(double src)
double compute(double src)
double recompute(double src)
double compute(double src)
double compute(double src, int length=1)
double recompute(double src, int length=1)
Change(int max_length=1)
double compute(double src1, double src2)
double recompute(double src1, double src2)
bool compute(double a, double b)
bool recompute(double a, double b)
bool recompute(double a, double b)
bool compute(double a, double b)
bool recompute(double a, double b)
bool compute(double a, double b)
double compute(double src)
double recompute(double src)
DMI(int di_length, int adx_smoothing)
DMIResult compute(double high, double low, double close)
DMIResult recompute(double high, double low, double close)
Dev(int length)
Definition ta.hpp:1329
double recompute(double src)
double compute(double src)
double compute(double src)
EMA(int length, EmaSeeding seeding)
double recompute(double src)
Result update(double src, bool advance, bool want_max)
WindowCacheStats cache_stats() const
Definition ta.hpp:151
ExtremeRing(int length, WindowCacheCapacity cache=window_cache_capacity())
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
double compute(double src)
double recompute(double src)
double recompute(double src)
double compute(double src)
double recompute(double high, double low, double close, double volume)
double compute(double high, double low, double close, double volume)
double recompute(double src, double high, double low, double close)
double compute(double src, double high, double low, double close)
KCW(int length, double mult, bool use_true_range=true)
KCResult compute(double src, double high, double low, double close)
KC(int length, double mult, bool use_true_range=true)
KCResult recompute(double src, double high, double low, double close)
double recompute(double src, double offset)
double compute(double src, double offset)
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
MACDResult recompute(double src)
MACD(int fast_length, int slow_length, int signal_length)
MACDResult compute(double src)
double compute(double src, double vol)
double recompute(double src, double vol)
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
double recompute(double src)
double compute(double src)
double recompute(double close, double volume)
double compute(double close, double volume)
double recompute(double close, double volume)
double compute(double close, double volume)
double recompute(double close, double volume)
double compute(double close, double volume)
double recompute(double close, double volume)
double compute(double close, double volume)
double compute(double src)
double recompute(double src)
double recompute(double src, double percentage)
double compute(double src, double percentage)
double recompute(double src, double percentage)
double compute(double src, double percentage)
const std::vector< double > * push(double src)
const std::vector< double > * repush(double src)
double compute(double src)
PivotHigh(int left_bars, int right_bars)
double recompute(double src)
PivotLow(int left_bars, int right_bars)
double recompute(double src)
double compute(double src)
std::vector< double > recompute(const std::string &type, bool anchor, bool developing, double open, double high, double low, double close)
std::vector< double > recompute(PivotLevelsType type, bool anchor, bool developing, double open, double high, double low, double close)
std::vector< double > compute(const std::string &type, bool anchor, bool developing, double open, double high, double low, double close)
std::vector< double > compute(PivotLevelsType type, bool anchor, bool developing, double open, double high, double low, double close)
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
double compute(double src)
Range(int length)
Definition ta.hpp:1320
double recompute(double src)
double compute(double src)
double recompute(double src)
SAR(double start, double increment, double maximum)
double compute(double high, double low, double close)
double recompute(double high, double low, double close)
double recompute(double src)
double compute(double src)
double compute(double src)
double recompute(double src)
StdDev(int length, bool biased=true)
double recompute(double src)
double compute(double src)
double compute(double src, double high, double low)
double recompute(double src, double high, double low)
Supertrend(double factor, int atr_period)
SupertrendResult recompute(double high, double low, double close)
SupertrendResult compute(double high, double low, double close)
double compute(double high, double low, double close, double prev_chart_close)
TR(bool handle_na=false)
double recompute(double high, double low, double close, double prev_chart_close)
double recompute(double high, double low, double close)
double compute(double high, double low, double close)
double compute(double src)
TSI(int short_length, int long_length)
double recompute(double src)
VWAPBandsResult recompute(double src, double volume, int64_t timestamp_ms)
Definition ta.hpp:1225
VWAPBandsResult compute(double src, double volume, int64_t timestamp_ms)
Definition ta.hpp:1222
VWAPBands(double stdev_mult)
Definition ta.hpp:1221
VWAPBandsResult compute(double src, double volume, int64_t timestamp_ms, const std::string &tz, const std::string &session)
Definition ta.hpp:1228
VWAPBandsResult recompute(double src, double volume, int64_t timestamp_ms, const std::string &tz, const std::string &session)
Definition ta.hpp:1232
double recompute(double src, double volume, int64_t timestamp_ms)
double recompute(double src, double volume, int64_t timestamp_ms, const std::string &tz, const std::string &session)
VWAPBandsResult recompute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult)
double compute(double src, double volume, int64_t timestamp_ms, const std::string &tz, const std::string &session)
VWAPBandsResult recompute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult, const std::string &tz, const std::string &session)
VWAPBandsResult compute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult, const std::string &tz, const std::string &session)
double compute(double src, double volume, int64_t timestamp_ms)
VWAPBandsResult compute_bands(double src, double volume, int64_t timestamp_ms, double stdev_mult)
double compute(double src, double vol)
double recompute(double src, double vol)
double compute(bool condition, double source, int occurrence)
double recompute(bool condition, double source, int occurrence)
ValueWhen(int max_occurrence=1)
Variance(int length, bool biased=true)
double recompute(double src)
double compute(double src)
double compute(double high, double low, double close)
double recompute(double high, double low, double close)
WindowCacheStats cache_stats() const
Definition ta.hpp:405
double recompute(double src)
double compute(double src)
WMA(int length, WindowCacheCapacity cache=window_cache_capacity())
double compute(double close, double high, double low)
double recompute(double close, double high, double low)
double recompute(double open, double high, double low, double close, double volume)
double compute(double open, double high, double low, double close, double volume)
bool & ema_na_warmup_flag()
BarContext & bar_context()
std::vector< double > pivot_point_levels(const std::string &method, double high, double low, double close)
PivotLevelsType pivot_levels_type(const std::string &name)
double na< double >()
Definition na.hpp:64
WindowCacheCapacity & window_cache_capacity()
Definition series.hpp:31