Author: Coded by Witold Wozniak
FisherCG

The Fisher Stochastic Cybernetic Gain (CG) Oscillator is a sophisticated technical analysis tool designed to help traders identify momentum trends and potential reversal points in financial markets. Based on the principles of cybernetics—the study of control and communication in systems—this indicator moves beyond simple price action to analyze the underlying "rhythm" of the market.

How the Logic Works

The script processes market data through a multi-layered mathematical sequence to filter out market noise and highlight significant trends:

1. Price Averaging The logic begins by calculating the midpoint of each price candle (the average of the high and low prices). This creates a baseline from which the rest of the calculations proceed, smoothing out minor fluctuations that might distract from the primary trend.

2. Cybernetic Gain Calculation The indicator then applies a weighted calculation to these midpoints. Instead of treating all recent data points equally, it assigns higher importance to more recent price movements. By comparing these weighted values against an average, the script determines the "Gain"—essentially measuring how much the current momentum is accelerating or decelerating compared to its recent history.

3. Normalization and Smoothing To make the data easier to read, the results are normalized. The script identifies the highest and lowest values over a specific period (defined by the user) and scales the current position within that range. It then applies a weighted moving average to this data, which helps to "round off" erratic jumps and provides a smoother, more reliable visual line.

4. Logarithmic Transformation The final step involves a logarithmic transformation. This is a critical mathematical step that allows the indicator to react more dynamically to significant price shifts while remaining stable during periods of consolidation. It compresses large fluctuations and expands smaller ones, making it easier for traders to spot the exact moment a trend begins to peak or bottom out.

Visual Interpretation for Traders

The indicator produces two primary lines on a separate window below your main chart:

  • The Main Line (Fisher CG): This represents the smoothed momentum of the market. When this line moves upward, it suggests bullish strength; when it moves downward, it suggests bearish pressure.
  • The Trigger Line: This is a lagged version of the main line. It acts as a secondary reference point.

Traders typically look for "crosses" between these two lines—where the Main Line cuts through the Trigger Line—as potential signals to enter or exit a position, providing a visual confirmation of a shift in market sentiment.

Miscellaneous
Implements a curve of type %1
11 Views
0 Downloads
0 Favorites
FisherCG
//+------------------------------------------------------------------+
//|                                                     FisherCG.mq4 |
//|                                                                  |
//| Fisher Stochastic CG Oscillator                                  |
//|                                                                  |
//| 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_separate_window
#property indicator_buffers 2
#property indicator_color1 Red
#property indicator_color2 Blue

#property indicator_level1 0

double FisherCG[];
double Trigger[];
double CG[];
double Value1[];
double Value2[];

extern int Length = 8;
int buffers = 0;
int drawBegin = 0;

int init() {
    drawBegin = Length;
    initBuffer(FisherCG, "Fisher CG", DRAW_LINE);
    initBuffer(Trigger, "Trigger", DRAW_LINE);
    initBuffer(CG);
    initBuffer(Value1);
    initBuffer(Value2);    
    IndicatorBuffers(buffers);
    IndicatorShortName("Fisher CG [" + Length + "]");
    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--) {
        double Num = 0.0;
        double Denom = 0.0;
        for (int count = 0; count < Length; count++) {
            Num += (1.0 + count) * P(s + count);
            Denom += P(s + count);
        }
        if (Denom != 0.0) {
            CG[s] = -Num / Denom + (Length + 1.0) / 2.0;
        } else {
            CG[s] = 0.0;
        }
        double hh = CG[s], ll = CG[s];
        for (int i = 0; i < Length; i++) {
            double tmp = CG[s + i];
            hh = MathMax(hh, tmp);
            ll = MathMin(ll, tmp);
        }
        Value1[s] = 0.0;
        if (hh != ll) {
            Value1[s] = (CG[s] - ll) / (hh - ll);
        }
        Value2[s] = (4.0 * Value1[s] + 3.0 * Value1[s + 1] + 2.0 * Value1[s + 2] + Value1[s + 3]) / 10.0;
        FisherCG[s] = 0.5 * MathLog((1.0 + 1.98 * (Value2[s] - 0.5)) / (1.0 - 1.98 * (Value2[s] - 0.5)));
        Trigger[s] = FisherCG[s + 1];
    }
    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