Gaussian Channel Adaptive Moving Average Strategy, for those who like adaptive strategies :-)


Code
#include <default.c>

var alpha, beta;
var filt, filttr, hband, lband;
vars PriceClose, GaussianFiltered, GaussianFilteredTR;

void init() {
  BarPeriod = 60; // 1-hour bars
  LookBack = 144; // Lookback period for the Gaussian filter

  PriceClose = series(priceClose());
  GaussianFiltered = series(0);
  GaussianFilteredTR = series(0);
  
  alpha = calculateAlpha(144, 4); // Sampling Period and Poles
  beta = (1 - cos(2 * PI / 144)) / (pow(1.414, 2 / 4) - 1);
}

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);
}

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++) {
    filtSeries[i] = filt9x(alpha, srcData[i], 1, poles);
    filtSeriesTR[i] = filt9x(alpha, trData[i], 1, poles);
  }
  
  GaussianFiltered[0] = filtSeries[0];
  GaussianFilteredTR[0] = filtSeriesTR[0];
  
  hband = GaussianFiltered[0] + GaussianFilteredTR[0] * 1.414;
  lband = GaussianFiltered[0] - GaussianFilteredTR[0] * 1.414;
}

var filt9x(var a, var s, int i, int poles) {
  static vars f[10];
  var x = 1 - a;
  var filt = pow(a, i) * s + i * x * f[1] - (i >= 2 ? 36 * pow(x, 2) * f[2] : 0) + (i >= 3 ? 84 * pow(x, 3) * f[3] : 0)
            - (i >= 4 ? 126 * pow(x, 4) * f[4] : 0) + (i >= 5 ? 126 * pow(x, 5) * f[5] : 0) - (i >= 6 ? 84 * pow(x, 6) * f[6] : 0)
            + (i >= 7 ? 36 * pow(x, 7) * f[7] : 0) - (i >= 8 ? 9 * pow(x, 8) * f[8] : 0) + (i == 9 ? 1 * pow(x, 9) * f[9] : 0);
  
  for(int j = 9; j > 0; j--) {
    f[j] = f[j - 1];
  }
  f[0] = filt;
  
  return filt;
}

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);
}

void run() {
  if(is(INITRUN)) {
    init();
  }

  calculateGaussianFilter(PriceClose, 4, 144);
  
  bool longCondition = crossOver(priceClose(), hband);
  bool closeAllCondition = crossUnder(priceClose(), hband);

  if (longCondition) {
    enterLong();
  }

  if (closeAllCondition) {
    exitLong();
  }
}