CyclePeriod

Download script
Author: Coded by Witold Wozniak
CyclePeriod

This script is designed to identify and visualize the rhythmic cycles within financial markets. Based on the principles of cybernetic analysis, it moves beyond simple price action to attempt to calculate the underlying "tempo" or period of market movements.

The logic operates through several distinct layers of processing:

1. Data Preparation (Smoothing) To ensure the analysis isn't distracted by minor market "noise," the script first identifies a baseline price for every candle (the midpoint between the high and low). It then applies a smoothing filter to these points. This helps stabilize the data so the tool can focus on larger, more significant trends rather than momentary fluctuations.

2. Cycle Detection Once smoothed, the data is analyzed to isolate cyclic patterns. The algorithm looks for repeating waves in the price action. By comparing current values against previous ones, it identifies how much of a "swing" is occurring. This is essential for determining whether the market is moving in a predictable rhythm or behaving randomly.

3. Phase Analysis and Period Calculation The core logic then calculates the "Delta Phase." In simple terms, it measures the rate of change between different points in the cycle. By analyzing these changes, the script determines how long a typical cycle takes to complete (the "Instantaneous Period").

To make this calculation reliable, the script uses a "Median" approach—it looks at a small window of recent data and finds the middle value. This prevents extreme, one-off market spikes from distorting the period calculation.

4. Final Output (Cycle Period) The final result is a smoothed representation of these periods. Rather than jumping erratically, the indicator provides a refined line that shows the estimated duration of the current market cycle.

Summary for the User: Instead of telling you where the price is going, this tool helps you understand the speed at which the market is currently cycling. It filters out noise to show you the "heartbeat" of the market, allowing you to see the prevailing time frames of current trends more clearly.

Miscellaneous
Implements a curve of type %1
19 Views
1 Downloads
0 Favorites
CyclePeriod
//+------------------------------------------------------------------+
//|                                                  CyclePeriod.mq4 |
//|                                                                  |
//| Cycle Period                                                     |
//|                                                                  |
//| 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 1
#property indicator_color1 Red

#property indicator_minimum 0

double DeltaPhase[];
double CPeriod[];
double Smooth[];
double Cycle[];
double Q1[];
double I1[];
double InstPeriod[];

extern double Alpha = 0.07;

int buffers = 0;
int drawBegin = 8;
int median = 5;

int init() {
    initBuffer(CPeriod, "Cycle Period", DRAW_LINE);
    initBuffer(Smooth);
    initBuffer(Cycle);
    initBuffer(Q1);
    initBuffer(I1);
    initBuffer(DeltaPhase);
    initBuffer(InstPeriod);
    IndicatorBuffers(buffers);      
    IndicatorShortName("Cycle Period [" + DoubleToStr(Alpha, 2) + "]");
    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--) {
        Smooth[s] = (P(s) + 2.0 * P(s + 1) + 2.0 * P(s + 2) + P(s + 3)) / 6.0;
        Cycle[s] = (1.0 - 0.5 * Alpha) * (1.0 - 0.5 * Alpha) * (Smooth[s] - 2 * Smooth[s + 1] + Smooth[s + 2]) 
            + 2.0 * (1.0 - Alpha) * Cycle[s + 1]
            - (1.0 - Alpha) * (1.0 - Alpha) * Cycle[s + 2];
        if (s > Bars - 8) {
            Cycle[s] = (P(s) - 2.0 * P(s + 1) + P(s + 2)) / 4.0;           
        }
        Q1[s] = (0.0962 * Cycle[s] + 0.5769 * Cycle[s + 2] - 0.5769 * Cycle[s + 4] - 0.0962 * Cycle[s + 6])
            * (0.5 + 0.08 * InstPeriod[s + 1]);
        I1[s] = Cycle[s + 3];
        if (Q1[s] != 0.0 && Q1[s + 1] != 0.0) {
            DeltaPhase[s] = (I1[s] / Q1[s] - I1[s + 1] / Q1[s + 1]) 
                / (1.0 + I1[s] * I1[s + 1] / (Q1[s] * Q1[s + 1]));
        }
        DeltaPhase[s] = MathMax(0.1, DeltaPhase[s]);
        DeltaPhase[s] = MathMin(1.1, DeltaPhase[s]);
        double MedianDelta, DC;
        double M[];
        ArrayResize(M, median);
        ArrayCopy(M, DeltaPhase, 0, s, median);
        ArraySort(M);
        if (median % 2 == 0) {
            MedianDelta = (M[median / 2] + M[(median / 2) + 1]) / 2.0;
        } else {
            MedianDelta = M[median / 2];
        }
        if (MedianDelta == 0.0) {
            DC = 15.0;
        } else {
            DC = 6.28318 / MedianDelta + 0.5;
        }
        InstPeriod[s] = 0.33 * DC + 0.67 * InstPeriod[s + 1];
        CPeriod[s] = 0.15 * InstPeriod[s] + 0.85 * CPeriod[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, 0);
    SetIndexDrawBegin(buffers, drawBegin);
    SetIndexShift(buffers, 0);
    SetIndexStyle(buffers, type, style, width);
    SetIndexArrow(buffers, arrow);    
    buffers++;
}

Comments