#include <default.c>
// Variables
var alpha, beta;
var filt, filttr, hband, lband;
vars PriceClose, GaussianFiltered, GaussianFilteredTR;
vars UpperBand, LowerBand;
// Initialization
void init() {
BarPeriod = 60; // 1-hour bars
LookBack = 144; // 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);
}
// 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);
}
// Modified 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 x2 = x * x;
var x3 = x2 * x;
var x4 = x3 * x;
var x5 = x4 * x;
var x6 = x5 * x;
var x7 = x6 * x;
var x8 = x7 * x;
var x9 = x8 * x;
// Calculate the filter value iteratively
for (int i = 1; i <= poles; i++) {
switch (i) {
case 1:
filt += x * f[i];
break;
case 2:
filt -= 36 * x2 * f[i];
break;
case 3:
filt += 84 * x3 * f[i];
break;
case 4:
filt -= 126 * x4 * f[i];
break;
case 5:
filt += 126 * x5 * f[i];
break;
case 6:
filt -= 84 * x6 * f[i];
break;
case 7:
filt += 36 * x7 * f[i];
break;
case 8:
filt -= 9 * x8 * f[i];
break;
case 9:
filt += x9 * f[i];
break;
}
}
// Shift the previous values in the array
for (int j = 9; j > 0; j--) {
f[j] = f[j - 1];
}
f[0] = filt;
// Calculate standard deviation of filter values
var sum = 0, mean = 0, count = 10;
for (int j = 0; j < count; j++) {
sum += f[j];
}
mean = sum / count;
var varianceSum = 0;
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];
}
// CrossOver and CrossUnder Functions
bool crossOver(vars data, var level) {
return (data[1] < level && data[0] >= level);
}
bool crossUnder(vars data, var level) {
return (data[1] > level && data[0] <= level);
}
// Main Trading Logic
void run() {
if(is(INITRUN)) {
init();
}
calculateGaussianFilter(PriceClose, 4, 144);
bool longCondition = crossOver(priceClose(), hband);
bool closeAllCondition = crossUnder(priceClose(), lband);
if (longCondition) {
enterLong();
}
if (closeAllCondition) {
exitLong();
}
}