tzutrader
A composable C++ backtesting library for trading strategies (experimental)
Loading...
Searching...
No Matches
indicators.h
Go to the documentation of this file.
1
17
18#ifndef INDICATORS_H
19#define INDICATORS_H
20
21#include <cstddef>
22#include <vector>
23#include "defs.h"
24
25namespace tzu {
26
33template <class T, typename In, typename Out>
34class Indicator {
35public:
36 Out get() const noexcept {
37 return static_cast<const T*>(this)->get();
38 }
39 Out update(In value) {
40 return static_cast<T*>(this)->update(value);
41 }
42};
43
59class SMA: public Indicator<SMA, double, double> {
60 double data = std::nan("");
61 std::vector<double> prev;
62 size_t pos = 0;
63 size_t len = 0;
64 double sum = 0.0;
65public:
66 SMA(size_t window_size): prev(window_size, std::nan("")) {}
67 double get() const noexcept { return data; }
68 double update(double value) {
69 if (len < prev.size())
70 len++;
71 else
72 sum -= prev[pos];
73 sum += value;
74 prev[pos] = value;
75 pos = (pos + 1) % prev.size();
76 data = len < prev.size()
77 ? std::nan("")
78 : sum / static_cast<double>(prev.size());
79 return data;
80 }
81};
82
100class EMA: public Indicator<EMA, double, double> {
101 double data = std::nan("");
102 double alpha;
103 double prev = 0.0;
104 size_t len = 0;
105 size_t period;
106public:
107 EMA(size_t period, double smoothing = 2.0)
108 : alpha(smoothing / (period + 1.0)), period(period) {}
109 double get() const noexcept { return data; }
110 double update(double value) {
111 len++;
112 if (len < period) {
113 prev += value;
114 data = std::nan("");
115 } else if (len == period) {
116 prev += value;
117 prev /= period;
118 data = prev;
119 } else {
120 prev = (value * alpha) + (prev * (1.0 - alpha));
121 data = prev;
122 }
123 return data;
124 }
125};
126
143class MVar {
144 double data = std::nan("");
145 SMA sma;
146 std::vector<double> prev;
147 size_t pos = 0;
148 size_t len = 0;
149 // double sum = 0.0;
150 size_t dof;
151public:
152 MVar(size_t window_size, size_t dof)
153 : sma(window_size), prev(window_size, std::nan("")), dof(dof) {}
154 double get() const noexcept { return data; }
155 double update(double value) {
156 if (len < prev.size()) len++;
157 prev[pos] = value;
158 pos = (pos + 1) % prev.size();
159 sma.update(value);
160 if (len < prev.size())
161 return std::nan("");
162 double accum = 0.0;
163 for (size_t prev_value : prev) {
164 if (std::isnan(prev_value))
165 return std::nan("");
166 double diff = prev_value - sma.get();
167 accum += diff * diff;
168 }
169 data = accum / (prev.size() - dof);
170 return data;
171 }
172};
173
189class RSI: public Indicator<RSI, Ohlcv, double> {
190 double data = std::nan("");
191 SMA gains;
192 SMA losses;
193public:
194 RSI(size_t period): gains(period), losses(period) {}
195 double get() const noexcept { return data; }
196 double update(Ohlcv value) {
197 double diff = value.close - value.open;
198 gains.update(diff >= 0.0 ? diff : 0.0);
199 losses.update(diff < 0 ? -diff : 0.0);
200 if (std::isnan(losses.get()))
201 return std::nan("");
202 data = 100.0 - 100.0 / (1.0 + gains.get() / losses.get());
203 return data;
204 }
205};
206
217 double macd;
218 double signal;
219 double histogram;
220};
221
233class MACD: public Indicator<MACD, double, MACDResult> {
234 MACDResult data;
235 EMA short_ema;
236 EMA long_ema;
237 EMA signal_ema;
238 size_t len = 0;
239 size_t start;
240public:
241 MACD(size_t short_period, size_t long_period, size_t signal_period,
242 double smoothing = 2.0)
243 : short_ema(short_period, smoothing),
244 long_ema(long_period, smoothing),
245 signal_ema(signal_period, smoothing),
246 start(std::fmax(short_period, long_period)) {}
247 MACDResult get() const noexcept { return data; }
248 MACDResult update(double value) {
249 len++;
250 short_ema.update(value);
251 long_ema.update(value);
252 if (len <= start)
253 return {std::nan(""), std::nan(""), std::nan("")};
254 double diff = short_ema.get() - long_ema.get();
255 signal_ema.update(diff);
256 data = {diff, signal_ema.get(), diff - signal_ema.get()};
257 return data;
258 }
259};
260
272class MDD: public Indicator<MDD, double, double> {
273 double data = 0.0;
274 double peak = 0.0;
275public:
276 double get() const noexcept { return data; }
277 double update(double value) {
278 if (value > peak)
279 peak = value;
280 if (peak > 0.0) {
281 double curr = (value - peak) / peak;
282 if (curr < data)
283 data = curr;
284 }
285 return data;
286 }
287};
288
289} // namespace tzu
290
291#endif // INDICATORS_H
Definition indicators.h:100
double get() const noexcept
Definition indicators.h:109
EMA(size_t period, double smoothing=2.0)
Definition indicators.h:107
double update(double value)
Definition indicators.h:110
Base indicator class using CRTP for static polymorphism.
Definition indicators.h:34
Out get() const noexcept
Definition indicators.h:36
Out update(In value)
Definition indicators.h:39
MACDResult get() const noexcept
Definition indicators.h:247
MACD(size_t short_period, size_t long_period, size_t signal_period, double smoothing=2.0)
Definition indicators.h:241
MACDResult update(double value)
Definition indicators.h:248
Definition indicators.h:272
double update(double value)
Definition indicators.h:277
double get() const noexcept
Definition indicators.h:276
MVar(size_t window_size, size_t dof)
Definition indicators.h:152
double get() const noexcept
Definition indicators.h:154
double update(double value)
Definition indicators.h:155
double update(Ohlcv value)
Definition indicators.h:196
RSI(size_t period)
Definition indicators.h:194
double get() const noexcept
Definition indicators.h:195
Simple Moving Average (SMA).
Definition indicators.h:59
SMA(size_t window_size)
Definition indicators.h:66
double update(double value)
Definition indicators.h:68
double get() const noexcept
Definition indicators.h:67
Core data structures and types for the tzutrader library.
Definition defs.h:20
Definition indicators.h:216
double signal
Definition indicators.h:218
double macd
Definition indicators.h:217
double histogram
Definition indicators.h:219
Open-High-Low-Close-Volume candlestick data.
Definition defs.h:84
double close
Closing price.
Definition defs.h:89
double open
Opening price.
Definition defs.h:86