This trading strategy leverages advanced signal processing and machine learning techniques to make informed trading decisions. We employ a Gaussian filter, which smooths the price series by reducing noise, and derive key indicators from it. These indicators include the filtered price and its bands, calculated by a non-recursive method. The signals are generated by comparing the filtered price to its bands, and identifying potential entry and exit points.

To enhance decision-making, we integrate a decision tree algorithm. This machine learning model is trained on historical signals, capturing complex patterns and relationships in the data. The model predicts future price movements, guiding long and short positions. By combining signal processing with machine learning, the strategy aims to exploit market inefficiencies and improve trading performance.

Code
#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 = 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
}

// 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];
}

// 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
    var Signals[2]; 
    Signals[0] = (GaussianFiltered[0] - GaussianFilteredTR[0]) / PIP;
    Signals[1] = 100 * FisherN(priceClose(), 100);

    // Train and trade the signals using the decision tree model
    if (adviseLong(DTREE, 0, Signals, 2) > 0)
        enterLong();
    if (adviseShort(DTREE, 0, Signals, 2) > 0)
        enterShort();
}

Last edited by TipmyPip; 07/11/24 05:45.