#include <default.c>
// Variables
var alpha, beta;
var filt, filttr, hband, lband;
vars PriceClose, GaussianFiltered, GaussianFilteredTR;
vars UpperBand, LowerBand;
var Signals[2];
var MetaSignals[2]; // Signals for the meta-model
// Initialization
void init() {
BarPeriod = 60; // 1-hour bars
LookBack = 150; // Lookback period for the Gaussian filter
PriceClose = series(priceClose());
GaussianFiltered = series(0);
GaussianFilteredTR = series(0);
UpperBand = series(0);
LowerBand = series(0);
alpha = calculateAlpha(144, 4); // Sampling Period and Poles
beta = (1 - cos(2 * PI / 144)) / (pow(1.414, 2 / 4) - 1);
adviseLong(DTREE, 0, NULL, 0); // Initialize the Decision Tree model
adviseLong(NN, 0, NULL, 0); // Initialize the Neural Network model
adviseLong(NN, 1, NULL, 0); // Initialize the Meta-Model Neural Network
}
// Calculate Alpha
var calculateAlpha(int period, int poles) {
var beta = (1 - cos(2 * PI / period)) / (pow(1.414, 2 / poles) - 1);
return -beta + sqrt(beta * beta + 2 * beta);
}
// Optimized Gaussian Filter with Bands
var filt9x_with_bands(var a, var s, int poles, var deviationMultiplier, var* upperBand, var* lowerBand) {
static vars f[10]; // Array to store previous filter values
var x = 1 - a;
var filt = s * a;
// Precompute powers of x to avoid redundant calculations
var x_powers[10];
x_powers[1] = x;
for (int i = 2; i <= 9; i++) {
x_powers[i] = x_powers[i - 1] * x;
}
// Calculate the filter value iteratively
var coefficients[10] = {0, 1, -36, 84, -126, 126, -84, 36, -9, 1};
for (int i = 1; i <= poles; i++) {
filt += coefficients[i] * x_powers[i] * f[i];
}
// Shift the previous values in the array
for (int j = 9; j > 0; j--) {
f[j] = f[j - 1];
}
f[0] = filt;
// Calculate mean and variance in a single pass
var sum = 0, varianceSum = 0, count = 10;
for (int j = 0; j < count; j++) {
sum += f[j];
}
var mean = sum / count;
for (int j = 0; j < count; j++) {
varianceSum += (f[j] - mean) * (f[j] - mean);
}
var stddev = sqrt(varianceSum / count);
// Calculate upper and lower bands
*upperBand = filt + deviationMultiplier * stddev;
*lowerBand = filt - deviationMultiplier * stddev;
return filt;
}
// Gaussian Filter Calculation
void calculateGaussianFilter(vars src, int poles, int period) {
vars filtSeries = series(0);
vars filtSeriesTR = series(0);
var lag = (period - 1) / (2 * poles);
vars srcData = series(0);
vars trData = series(0);
for (int i = 0; i < Bar; i++) {
if (i > lag) {
srcData[i] = src[i] + (src[i] - src[i - lag]);
trData[i] = TR() + (TR() - TR(lag));
} else {
srcData[i] = src[i];
trData[i] = TR();
}
}
for (int i = 0; i < Bar; i++) {
var upper, lower;
filtSeries[i] = filt9x_with_bands(alpha, srcData[i], poles, 1.414, &upper, &lower);
filtSeriesTR[i] = filt9x_with_bands(alpha, trData[i], poles, 1.414, &upper, &lower);
UpperBand[i] = upper;
LowerBand[i] = lower;
}
GaussianFiltered[0] = filtSeries[0];
GaussianFilteredTR[0] = filtSeriesTR[0];
hband = UpperBand[0];
lband = LowerBand[0];
}
// Meta-Model for Combining Predictions using Neural Network
var metaModel(var dtreePrediction, var nnPrediction) {
MetaSignals[0] = dtreePrediction;
MetaSignals[1] = nnPrediction;
return advise(NN, 1, MetaSignals, 2); // Use another neural network (NN) model as meta-model
}
// Main Trading Logic
void run() {
BarPeriod = 60; // 1-hour bars
LookBack = 150; // Lookback period
TradesPerBar = 2;
if (Train) {
Hedge = 2; // Hedge during training
}
set(RULES | TESTNOW); // Set rules and test mode
if (is(INITRUN)) {
init();
}
calculateGaussianFilter(PriceClose, 4, 144);
// Generate some signals from GaussianFiltered in the -100..100 range
Signals[0] = (GaussianFiltered[0] - GaussianFilteredTR[0]) / PIP;
Signals[1] = 100 * FisherN(priceClose(), 100);
// Train and trade the signals using decision tree and neural network models
var dtreePrediction = advise(DTREE, 0, Signals, 2);
var nnPrediction = advise(NN, 0, Signals, 2);
var finalDecision = metaModel(dtreePrediction, nnPrediction);
if (finalDecision > 0)
enterLong();
else if (finalDecision < 0)
enterShort();
else {
if (isLong()) exitLong();
if (isShort()) exitShort();
}
}