Coding Double Triangular MA Cross with Extrapolation (C++)

Female Software Engineer Coding on Computer
Make sure you have the - matplotlibcpp - library set up. 

Also, I have kept 'close_prices' for you to replace with your actual data. Try different values to better correlate with your trading timeframes and methods.
// Need to first include the necessary libraries and define the matplotlibcpp namespace.
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include "matplotlibcpp.h"

namespace plt = matplotlibcpp;

// Defining the helper functions for calculating the rolling mean, triangular moving average // (TMA), and extrapolating the TMA.
std::vector<double> rolling_mean(const std::vector<double>& data, int window) {
std::vector<double> result(data.size(), std::nan(""));
if (window > data.size()) return result;
double sum = 0.0;
for (int i = 0; i < data.size(); ++i) {
sum += data[i];
if (i >= window) {
sum -= data[i - window];
}
if (i >= window - 1) {
result[i] = sum / window;
}
}
return result;
}

std::vector<double> tma(const std::vector<double>& data, int length) {
return rolling_mean(rolling_mean(data, std::ceil(length / 2.0)), std::floor(length / 2.0) + 1);
}

std::vector<double> extrapolate_tma(const std::vector<double>& data, int length, int i) {
std::vector<double> x = rolling_mean(rolling_mean(data, std::ceil((length - i) / 2.0)), std::floor((length - i) / 2.0) + 1);
std::vector<double> result(data.size(), std::nan(""));
for (int j = 0; j < data.size(); ++j) {
result[j] = (x[j] * (length - i) + data[j] * i) / length;
}
return result;
}

// From here we will define the main function to calculate and plot the TMAs and their // extrapolated values.
int main() {
// Sample data
std::vector<double> close_prices = {100, 102, 101, 105, 107, 108, 110, 112, 115, 117, 118, 119, 121, 123, 124, 126, 127, 128, 130, 132, 134, 135, 137, 138, 140, 141, 142, 143, 145, 147};

// Settings for the first TMA
int length1 = 15;
int shift1 = -15;
std::string cl1 = "green";

// Calculating the first TMA
std::vector<double> tma1 = tma(close_prices, length1);

// Plotting the first TMA
plt::plot(tma1, {{"label", "TMA1"}, {"color", cl1}, {"linewidth", "2"}});

// Plotting the extrapolated values as circles for the first TMA
for (int i = 1; i <= 17; ++i) {
std::vector<double> tma1_extrapolated = extrapolate_tma(close_prices, length1, i);
plt::scatter({(double)close_prices.size() - 1}, {tma1_extrapolated.back()}, 100.0, {{"color", cl1}, {"edgecolor", "black"}});
}

// Settings for the second TMA
int length2 = 30;
int shift2 = -10;
std::string cl2 = "red";

// Calculating the second TMA
std::vector<double> tma2 = tma(close_prices, length2);

// Plotting the second TMA
plt::plot(tma2, {{"label", "TMA2"}, {"color", cl2}, {"linewidth", "2"}});

// Plotting the extrapolated values as circles for the second TMA
for (int i = 1; i <= 15; ++i) {
std::vector<double> tma2_extrapolated = extrapolate_tma(close_prices, length2, i);
plt::scatter({(double)close_prices.size() - 1}, {tma2_extrapolated.back()}, 100.0, {{"color", cl2}, {"edgecolor", "black"}});
}

// Finalizing the plot
plt::title("Double Triangular MA Cross");
plt::xlabel("Time");
plt::ylabel("Close Price");
plt::legend();
plt::grid(true);
plt::show();

return 0;
}

Download and see more projects at my GitHub page.

Now, let’s check out how well it back tests!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top