ThreePoleButterworthFilter

Download script
Author: Coded by Witold Wozniak
ThreePoleButterworthFilter

This tool is designed to provide a smoother, more refined view of market price action by filtering out "noise"—the erratic, short-term fluctuations that can often obscure the broader trend. Based on mathematical principles from signal processing literature, it functions as a specialized smoothing mechanism called a Three-Pole Butterworth Filter.

How the Logic Works

1. Identifying the Core Data Instead of looking at every individual price point (which can be very volatile), the script first identifies the "midpoint" for each candle by averaging the high and low prices. This creates a more balanced foundation for the analysis.

2. Determining the Smoothness (Cutoff Period) The user can define a "Cutoff Period." This is the primary lever for controlling how much data the filter considers. A larger period will result in a smoother, slower line that ignores small price movements, while a smaller period will make the line more responsive to immediate price changes.

3. The Filtering Process The script uses a sophisticated mathematical formula to calculate each new point on the indicator line. It doesn't just look at the current price; it looks back at several previous data points simultaneously. By weighing these past values against current data using specific coefficients, the filter "rounds off" sharp spikes and dips.

4. The Resulting Visual The final output is a continuous line that follows the primary direction of the market. Because it eliminates the "jitter" of the raw price, it allows traders to see the underlying momentum more clearly. It acts as a sophisticated moving average that prioritizes the integrity of the trend over the volatility of the moment.

Miscellaneous
Implements a curve of type %1
12 Views
0 Downloads
0 Favorites
ThreePoleButterworthFilter
//+------------------------------------------------------------------+
//|                                   ThreePoleButterworthFilter.mq4 |
//|                                                                  |
//| Three-Pole Butterworth Filter                                    |
//|                                                                  |
//| Algorithm taken from book                                        |
//|     "Cybernetics Analysis for Stock and Futures"                 |
//| by John F. Ehlers                                                |
//|                                                                  |
//|                                              contact@mqlsoft.com |
//|                                          http://www.mqlsoft.com/ |
//+------------------------------------------------------------------+
#property copyright "Coded by Witold Wozniak"
#property link      "www.mqlsoft.com"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Red

extern int CutoffPeriod = 15;

double Filter[];

int buffers = 0;
int drawBegin = 0;

double tempReal, rad2Deg, deg2Rad;
double coef1, coef2, coef3, coef4;

int init() {
    drawBegin = 4;
    initBuffer(Filter, "Three-Pole Butterworth Filter", DRAW_LINE);
    IndicatorBuffers(buffers);
    IndicatorShortName("Three-Pole Butterworth Filter [" + CutoffPeriod + "]");  
    tempReal = MathArctan(1.0);
    rad2Deg = 45.0 / tempReal;
    deg2Rad = 1.0 / rad2Deg;
    double a1 = MathExp(-3.14159 / CutoffPeriod);
    double b1 = 2 * a1 * MathCos(deg2Rad * 1.414 * 180 / CutoffPeriod);
    double c1 = a1 * a1;
    coef2 = b1 + c1;
    coef3 = -(c1 + b1 * c1);
    coef4 = c1 * c1;
    coef1 = (1.0 - b1 + c1) * (1.0 - c1) / 8.0;
    return (0);
}

int start() {
    if (Bars <= drawBegin) return (0);
    int countedBars = IndicatorCounted();
    if (countedBars < 0) return (-1);
    if (countedBars > 0) countedBars--;
    int s, limit = Bars - countedBars - 1;
    for (s = limit; s >= 0; s--) {
        Filter[s] = coef1 * (P(s) + 3.0 * P(s + 1) + 3.0 * P(s + 2) + P(s + 3)) +
                    coef2 * Filter[s + 1] + 
                    coef3 * Filter[s + 2] +
                    coef4 * Filter[s + 3];
        if (s > Bars - 4) {
            Filter[s] = P(s);
        }
    }   
    return (0);   
}

double P(int index) {
    return ((High[index] + Low[index]) / 2.0);
}

void initBuffer(double array[], string label = "", int type = DRAW_NONE, int arrow = 0, int style = EMPTY, int width = EMPTY, color clr = CLR_NONE) {
    SetIndexBuffer(buffers, array);
    SetIndexLabel(buffers, label);
    SetIndexEmptyValue(buffers, EMPTY_VALUE);
    SetIndexDrawBegin(buffers, drawBegin);
    SetIndexShift(buffers, 0);
    SetIndexStyle(buffers, type, style, width);
    SetIndexArrow(buffers, arrow);
    buffers++;
}

Comments