Cycle_KROUFR_version
Download scriptThis script functions as a sophisticated market cycle analyzer designed to identify and quantify the rhythmic patterns of price movements. Instead of simply looking at where the price is currently going, it attempts to calculate the underlying "heartbeat" of the market by measuring how often and how significantly the trend changes direction.
Core Logic Breakdown
1. Trend Identification and Cross-Counting The script begins by monitoring two Moving Averages (Fast and Slow). It watches for specific moments when these averages cross each other, which signifies a change in momentum. The logic identifies these "crosses" to establish a baseline for market behavior. It specifically tracks the distance between these shifts to understand the frequency of trend reversals.
2. Cycle Measurement (The Time Average) By analyzing a set number of these crossings, the script calculates a "Period Time Average." This represents the average duration of a market cycle. Essentially, it determines how many bars (or units of time) typically pass before the trend flips from up to down or vice versa.
3. Volatility and Deviation Tracking While identifying these cycles, the script also tracks the high and low prices reached between each crossing. It calculates the "Point Deviation," which measures the average magnitude of price swings. This helps distinguish between "quiet" cycles with small movements and "volatile" cycles with large price swings.
4. Stochastic-Based Normalization The script takes these findings and applies them to a modified Stochastic calculation based on the Moving Average Convergence Divergence (MACD).
- It looks at the current MACD value relative to its highest and lowest points over the "Time Average" period calculated earlier.
- This allows the indicator to normalize the market data—essentially telling you where the current price sits within the context of a typical cycle.
5. Smoothing and Visualization Finally, the script applies a smoothing formula to these calculations. Rather than showing jagged, erratic jumps, it produces a fluid line (similar to a smoothed oscillator). This helps traders see the overarching trend of the market cycle more clearly.
Summary for the User
In plain terms, this tool looks at past history to figure out "how long does a move usually last?" and "how far does it usually go?" It then uses those historical averages to plot an indicator that shows where the current price stands within its natural cycle. It provides on-screen comments showing the average number of bars per cycle and the average point deviation, giving you a data-driven view of market rhythm.
//+------------------------------------------------------------------+
//| Cycle_KROUFR_version.mq4 |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008 | Grayman77, zIG, akadex"
#property link "ForexResearch"
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property indicator_level1 20
#property indicator_level2 50
#property indicator_level3 80
#property indicator_buffers 1
#property indicator_color1 Yellow
//---- input parameters
extern int FastMA=5;
extern int SlowMA=8;
extern int Crosses=3;
extern bool Comments=true;
//---- buffers
double MA[];
double MCD[];
double MAfast[],MAslow[];
double Cross[];
double max_min[];
double PointDeviation[];
double PeriodTimeAVG[];
//---- var
double smconst,ST,max,min;
int ShiftFirstCross; // ñìåùåíèå ïåðâîãî ïåðåñå÷åíèÿ c íà÷àëà èñòîðèè
int ShiftCrossesCross; // ñìåùåíèå (Crosses+1)-ãî ïåðåñå÷åíèÿ c íà÷àëà èñòîðèè (ïåðâîå - ïðîïóñêàåì)
int k;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int init()
{
// string short_name;
//---- indicator line
IndicatorBuffers(8);
SetIndexBuffer(0, MA);
SetIndexStyle(0,DRAW_LINE,STYLE_DOT,1,DarkOrange);
SetIndexBuffer(1, MCD);
SetIndexBuffer(2, MAfast);
SetIndexBuffer(3, MAslow);
SetIndexBuffer(4, Cross);
SetIndexBuffer(5, max_min);
SetIndexBuffer(6, PointDeviation);
SetIndexBuffer(7, PeriodTimeAVG);
SetIndexEmptyValue(0,0.0);
SetIndexEmptyValue(1,0.0);
SetIndexEmptyValue(2,0.0);
SetIndexEmptyValue(3,0.0);
SetIndexEmptyValue(4,0.0);
SetIndexEmptyValue(5,0.0);
SetIndexEmptyValue(6,0.0);
SetIndexEmptyValue(7,0.0);
ShiftFirstCross=0;
ShiftCrossesCross=0;
k=0;
max=0.;
min=1000000.;
return(0);
}
int deinit()
{
Comment("");
return(0);
}
//+------------------------------------------------------------------+
//| Schaff Trend Cycle |
//+------------------------------------------------------------------+
int start()
{
int counted_bars=IndicatorCounted();
int i,j,limit,NumberCross,BarsCross;
double prev,MinMACD,MaxMACD,delta,Sum_max_min;
if(Bars<=SlowMA) return(-1);
//---- ïîñëåäíèé ïîñ÷èòàííûé áàð áóäåò ïåðåñ÷èòàí
if(counted_bars>0) counted_bars--;
limit=Bars-counted_bars;
if(limit>Bars-SlowMA-1) limit=Bars-SlowMA-1;
//+------------------------------------------------------------------+
//| Time AVG |
//+------------------------------------------------------------------+
for(i=limit;i>0;i--)
{
Cross[i]=0.;
// Âû÷èñëèòü çíà÷åíèÿ ñðåäíèõ è ïîìåñòèòü â áóôåðû
MAfast[i]=iMA(NULL,Period(),FastMA,0,MODE_SMA,PRICE_CLOSE,i);
MAslow[i]=iMA(NULL,Period(),SlowMA,0,MODE_SMA,PRICE_CLOSE,i);
// Íàéòè ïåðåñå÷åíèÿ ñðåäíèõ
if(MAfast[i]>=MAslow[i] && MAfast[i+1]<MAslow[i+1]) // áûñòðàÿ ïåðåñåêàåò ìåäëåííóþ ñíèçó ââåðõ
{
// Åñëè ýòî ïåðâîå íàéäåííîå ïåðåñå÷åíèå - çàïîìíèòü åãî ñìåùåíèå
if(ShiftFirstCross==0) ShiftFirstCross=i;
// Åñëè åùå íå íàéäåíî Crosses+1 ïåðåñå÷åíèå
if(ShiftCrossesCross==0)
{
k++;
// åñëè íàéäåíî - çàïîìíèòü
if(k==Crosses+1) ShiftCrossesCross=i;
}
// Çàïîìíèòü ôàêò ïåðåñå÷åíèÿ â áóôåðå
Cross[i]=1.;
// Çàïîìíèòü ðàçíîñòü max-min â áóôåðå
max_min[i]=max-min;
// Ñáðîñèòü çíà÷åíèÿ max è min
max=0.;
min=1000000.;
}
if(MAfast[i]<=MAslow[i] && MAfast[i+1]>MAslow[i+1]) // áûñòðàÿ ïåðåñåêàåò ìåäëåííóþ ñâåðõó âíèç
{
// Åñëè ýòî ïåðâîå íàéäåííîå ïåðåñå÷åíèå - çàïîìíèòü åãî ñìåùåíèå
if(ShiftFirstCross==0) ShiftFirstCross=i;
// Åñëè åùå íå íàéäåíî Crosses+1 ïåðåñå÷åíèå
if(ShiftCrossesCross==0)
{
k++;
// åñëè íàéäåíî - çàïîìíèòü
if(k==Crosses+1) ShiftCrossesCross=i;
}
// Çàïîìíèòü ôàêò ïåðåñå÷åíèÿ â áóôåðå
Cross[i]=-1.;
// Çàïîìíèòü ðàçíîñòü max-min â áóôåðå
max_min[i]=max-min;
// Ñáðîñèòü çíà÷åíèÿ max è min
max=0.;
min=1000000.;
}
// Âûáèðàåì ìàêñèìàëüíóþ öåíó (èç High) ìåæäó ïåðåñå÷åíèÿìè è ìèíèìàëüíóþ èç Low
if(max<High[i]) max=High[i];
if(min>Low[i]) min=Low[i];
}
// Ñ÷èòàåì ñòàòèñòèêó
if(limit>ShiftCrossesCross) limit=ShiftCrossesCross;
for(i=limit;i>0;i--)
{
// Íàéòè ïåðâîå ïåðåñå÷åíèå (ñïðàâà íàëåâî)
j=i;
while(Cross[j]==0.) j++;
// Íàéòè ñëåäóþùèå Crosses ïåðåñå÷åíèé
NumberCross=0;
BarsCross=0;
Sum_max_min=0.;
while(NumberCross<Crosses)
{
// Åñëè íàéäåíî î÷åðåäíîå ïåðåñå÷åíèå
if(Cross[j]!=0.)
{
NumberCross++; // óâåëè÷èòü íà 1 ñ÷åò÷èê ïåðåñå÷åíèé
Sum_max_min=Sum_max_min+max_min[j];
}
j++;
BarsCross++;
}
// Èòîãîâûå çíà÷åíèÿ Time AVG
PeriodTimeAVG[i]=BarsCross/Crosses; // ñðåäíåå êîë-âî áàðîâ ìåæäó ïåðåñå÷åíèÿìè
PointDeviation[i]=NormalizeDouble(Sum_max_min/Crosses/2./Point,0); // ñð. îòêëîíåíèå
}
//+------------------------------------------------------------------+
//| Cycle |
//+------------------------------------------------------------------+
for(i=limit;i>=0;i--)
{
// Âû÷èñëèòü MACD
MCD[i]=iMA(NULL,0,FastMA,0, MODE_EMA, PRICE_TYPICAL, i)-
iMA(NULL,0,SlowMA,0, MODE_EMA, PRICE_TYPICAL, i);
// Íàéòè ìàêñ. è ìèí. çíà÷åíèÿ MACD íà ïåðèîäå TimeAVG
MinMACD=MCD[i];
MaxMACD=MCD[i];
for(j=i+1;j<i+PeriodTimeAVG[i+1];j++)
{
if(MCD[j]<MinMACD) MinMACD=MCD[j];
if(MCD[j]>MaxMACD) MaxMACD=MCD[j];
}
// Âû÷èñëèòü ñòîõàñòèê îò MACD
delta=MaxMACD-MinMACD;
if(delta==0.) // ïðîâåðêà äëÿ èñêëþ÷åíèÿ äåëåíèÿ íà 0
ST=50.;
else // åñëè íå 0 - äåëèì
{
ST=(MCD[i]-MinMACD)/delta*100;
}
// Çàïîëíèòü áóôåð
prev=MA[i+1];
MA[i]=(2./(1.+PeriodTimeAVG[i+1]/2.))*(ST-prev)+prev;
//Âûâåñòè êîììåíòàðèè
if (!IsTesting() && Comments)
Comment(" Áîêîâûå îòêëîíåíèÿ: "+DoubleToStr(PointDeviation[1],0)+
" ïóíêòîâ\n Ñðåäíåå êîëè÷åñòâî áàðîâ: "+DoubleToStr(PeriodTimeAVG[1],0)+
"\n Ïåðåñå÷åíèé: "+Crosses);
}
return(0);
}
//+------------------------------------------------------------------+
Comments