Indicators Used
2
Views
0
Downloads
0
Favorites
ZZ
//+------------------------------------------------------------------+
//| ZZ.mq5 |
//| Copyright © 2008, Tinytjan |
//| tinytjan@mail.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2008, Tinytjan"
#property link "tinytjan@mail.ru"
//---- indicator version number
#property version "1.00"
//---- drawing the indicator in the main window
#property indicator_chart_window
//---- number of indicator buffers
#property indicator_buffers 3
//---- only one plot is used
#property indicator_plots 1
//+-----------------------------------+
//| Parameters of indicator drawing |
//+-----------------------------------+
//---- drawing the indicator as a line
#property indicator_type1 DRAW_LINE
//---- BlueViolet color is used as the color of the bullish line of the indicator
#property indicator_color1 clrBlueViolet
//---- the indicator line is a continuous curve
#property indicator_style1 STYLE_SOLID
//---- the width of indicator line is equal to 3
#property indicator_width1 3
//---- displaying the indicator label
#property indicator_label1 "ZigZag"
//+-----------------------------------+
//| INDICATOR INPUT PARAMETERS |
//+-----------------------------------+
input uint SmoothPeriod=1; //The period for smoothing extremums, for filtering spikes
input uint ChannelWidth=150; //Channel width, in points
input uint FontSize=10; //Text font size
input color TextColor=clrBlue; // The text color
input bool DrawInfo=false; // Display information about apexes
input int Shift=0; // horizontal shift of the indicator in bars
//+-----------------------------------+
//---- declaration of dynamic arrays that will further be
// used as indicator buffers
double ZZ[];
double SmoothedMaxValues[];
double SmoothedMinValues[];
string symbol;
//+-----------------------------------+
//| declaration of constants |
//+-----------------------------------+
#define RESET 0 // the constant for returning the indicator recalculation command to the terminal
#define UP +1
#define DN -1
#define NONE 0
//+-----------------------------------+
int Direction;
datetime StartMax;
datetime EndMax;
datetime StartMin;
datetime EndMin;
// ZZ variables
datetime StartDraw;
datetime EndDraw;
double StartDrawValue;
double EndDrawValue;
// ObjectVariables
int Counter;
int Length;
double LastLength;
//---- Declaration of integer variables for the indicator handles
int UpMA_Handle,DnMA_Handle;
//---- Declaration of integer variables of data starting point
int min_rates_total;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- Initialization of variables of data calculation starting point
min_rates_total=int(30+SmoothPeriod+4);
//---- getting the iMA indicator handle
UpMA_Handle=iMA(NULL,PERIOD_CURRENT,SmoothPeriod,0,MODE_EMA,PRICE_HIGH);
if(UpMA_Handle==INVALID_HANDLE) Print(" Failed to get handle of the iMA indicator");
//---- getting the iMA indicator handle
DnMA_Handle=iMA(NULL,PERIOD_CURRENT,SmoothPeriod,0,MODE_EMA,PRICE_LOW);
if(DnMA_Handle==INVALID_HANDLE) Print(" Failed to get handle of the iMA indicator");
//---- set dynamic array as an indicator buffer
SetIndexBuffer(0,ZZ,INDICATOR_DATA);
//---- indexing the elements in buffers as in timeseries
ArraySetAsSeries(ZZ,true);
//---- shifting the indicator horizontally by Shift
PlotIndexSetInteger(0,PLOT_SHIFT,Shift);
//---- shifting the starting point of the indicator drawing
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,min_rates_total);
//---- setting values of the indicator that won't be visible on a chart
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//---- set dynamic array as an indicator buffer
SetIndexBuffer(1,SmoothedMaxValues,INDICATOR_CALCULATIONS);
//---- indexing the elements in buffers as in timeseries
ArraySetAsSeries(SmoothedMaxValues,true);
//---- set dynamic array as an indicator buffer
SetIndexBuffer(2,SmoothedMinValues,INDICATOR_CALCULATIONS);
//---- indexing the elements in buffers as in timeseries
ArraySetAsSeries(SmoothedMinValues,true);
//---- initializations of variable for indicator short name
string shortname;
StringConcatenate(shortname,"ChannelZZ(",SmoothPeriod,",",ChannelWidth,",",Shift,")");
//--- creation of the name to be displayed in a separate sub-window and in a pop up help
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//--- determination of accuracy of displaying the indicator values
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//---- end of initialization
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//----
int total=ObjectsTotal(0,0,-1)-1;
string name,sirname;
for(int numb=total; numb>=0 && !IsStopped(); numb--)
{
name=ObjectName(0,numb,0,-1);
sirname=StringSubstr(name,0,StringLen("Stats"));
if(sirname=="Stats") ObjectDelete(0,name);
}
//----
ChartRedraw(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(
const int rates_total, // amount of history in bars at the current tick
const int prev_calculated,// amount of history in bars at the previous tick
const datetime &time[],
const double &open[],
const double& high[], // price array of maximums of price for the calculation of indicator
const double& low[], // price array of minimums of price for the calculation of indicator
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[]
)
{
//---- checking for the sufficiency of the number of bars for the calculation
if(BarsCalculated(UpMA_Handle)<rates_total
|| BarsCalculated(DnMA_Handle)<rates_total
|| rates_total<min_rates_total) return(RESET);
//---- indexing elements in arrays as in timeseries
ArraySetAsSeries(time,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
//---- declaration of local variables
int to_copy,limit,bar;
double;
//---- calculations of the necessary number of copied data and limit starting index for the bars recalculation loop
if(prev_calculated>rates_total || prev_calculated<=0)// checking for the first start of the indicator calculation
{
limit=rates_total-1; // starting number for calculation of all bars
symbol=Symbol();
Direction=NONE;
Counter=0;
StartMax=0;
EndMax=0;
StartMin=0;
EndMin=0;
Length=0;
LastLength=EMPTY_VALUE;
}
else
{
limit=rates_total-prev_calculated; // starting number for the calculation of new bars
}
to_copy=limit+1;
//---- copy newly appeared data into the arrays
if(CopyBuffer(UpMA_Handle,0,0,to_copy,SmoothedMaxValues)<=0) return(RESET);
if(CopyBuffer(DnMA_Handle,0,0,to_copy,SmoothedMinValues)<=0) return(RESET);
//---- main cycle of calculation of the indicator
for(bar=limit; bar>=0 && !IsStopped(); bar--)
{
ZZ[bar]=0.0;
switch(Direction)
{
case NONE: CheckInit(bar,time); break;
case UP: CheckUp(bar,rates_total,time); break;
case DN: CheckDown(bar,rates_total,time); break;
}
}
if(prev_calculated>rates_total || prev_calculated<=0) limit-=4;
//---- unnecessary labels deleting loop
for(bar=limit; bar>=0 && !IsStopped(); bar--)
{
if(ZZ[bar+2]>ZZ[bar+1] && ZZ[bar+1]<ZZ[bar] || ZZ[bar+2]<ZZ[bar+1] && ZZ[bar+1]>ZZ[bar]) continue;
else if(ZZ[bar+2] && ZZ[bar+1] && ZZ[bar]) ObjectDelete(0,"Stats"+TimeToString(time[bar+1],TIME_DATE|TIME_MINUTES));
}
//----
ChartRedraw(0);
return(rates_total);
}
//+----------------------------------------------------------------------------+
//| |
//+----------------------------------------------------------------------------+
void CheckInit(int offset,const datetime &Time[])
{
//----
if(!StartMax || !StartMin)
{
if(!StartMax) StartMax = Time[offset];
if(!StartMin) StartMin = Time[offset];
return;
}
if(Direction==NONE)
{
double maxValue = SmoothedMaxValues[iBarShift(symbol,PERIOD_CURRENT,StartMax)];
double minValue = SmoothedMinValues[iBarShift(symbol,PERIOD_CURRENT,StartMin)];
double nowMax = SmoothedMaxValues[offset];
double nowMin = SmoothedMaxValues[offset];
if(nowMax>maxValue && Time[offset]>StartMax)
{
// Logic
EndMax=Time[offset];
StartMin=Time[offset];
Direction=UP;
// Drawing
StartDraw=StartMax;
EndDraw=EndMax;
StartDrawValue=maxValue;
EndDrawValue=nowMax;
Length=int(NormalizeDouble((nowMax-maxValue)/_Point,0));
RePaint();
}
else if(nowMin>minValue && Time[offset]>StartMin)
{
// Logic
EndMin=Time[offset];
StartMax=Time[offset];
Direction=DN;
// Drawing
StartDraw=StartMin;
EndDraw=EndMin;
StartDrawValue=minValue;
EndDrawValue=nowMin;
Length=int(NormalizeDouble((minValue-nowMin)/_Point,0));
RePaint();
}
}
//----
}
//+----------------------------------------------------------------------------+
//| |
//+----------------------------------------------------------------------------+
void CheckUp(int offset,int rates_total_,const datetime &Time[])
{
//----
int startIndex=iBarShift(symbol,PERIOD_CURRENT,StartMax);
int endIndex=iBarShift(symbol,PERIOD_CURRENT,EndMax);
double endMaxValue=SmoothedMaxValues[endIndex];
if(endMaxValue<SmoothedMaxValues[offset])
{
// Logic
endMaxValue=SmoothedMaxValues[offset];
EndMax=Time[offset];
// Drawing
EndDraw=EndMax;
EndDrawValue=endMaxValue;
double endMinValue=SmoothedMinValues[iBarShift(symbol,PERIOD_CURRENT,EndMin)];
Length=int(NormalizeDouble((endMaxValue-endMinValue)/_Point,0));
RePaint();
}
else
{
double startMaxValue=SmoothedMaxValues[startIndex];
int shift=iBarShift(symbol,PERIOD_CURRENT,StartMin);
shift=MathMax(MathMin(shift,0),rates_total_-1);
double startMinValue=SmoothedMinValues[shift];
double nowMaxValue=endMaxValue;
if(startIndex-endIndex!=0)
{
nowMaxValue+=(endMaxValue-startMaxValue)/(startIndex-endIndex)*(endIndex-offset);
}
double nowMinValue=SmoothedMinValues[offset];
if(nowMaxValue-nowMinValue>ChannelWidth*_Point)
{
if(EndMax!=offset)
{
StartMin=Time[offset];
EndMin=Time[offset];
Direction=DN;
// Drawing
StartDraw=EndMax;
EndDraw=EndMin;
StartDrawValue=endMaxValue;
EndDrawValue=nowMinValue;
Counter++;
LastLength=Length;
Length=int(NormalizeDouble((endMaxValue-nowMinValue)/_Point,0));
RePaint();
}
}
}
//----
}
//+----------------------------------------------------------------------------+
//| |
//+----------------------------------------------------------------------------+
void CheckDown(int offset,int rates_total_,const datetime &Time[])
{
//----
int startIndex=iBarShift(symbol,PERIOD_CURRENT,StartMin);
int endIndex=iBarShift(symbol,PERIOD_CURRENT,EndMin);
double endMinValue=SmoothedMinValues[endIndex];
if(endMinValue>SmoothedMinValues[offset])
{
endMinValue=SmoothedMinValues[offset];
EndMin=Time[offset];
// Drawing
EndDraw=EndMin;
EndDrawValue=endMinValue;
double endMaxValue=SmoothedMaxValues[iBarShift(symbol,PERIOD_CURRENT,EndMax)];
Length=int(NormalizeDouble((endMaxValue-endMinValue)/_Point,0));
RePaint();
}
else
{
double startMinValue=SmoothedMinValues[startIndex];
int shift=iBarShift(symbol,PERIOD_CURRENT,StartMax);
shift=MathMax(MathMin(shift,0),rates_total_-1);
double startMaxValue=SmoothedMaxValues[shift];
double nowMinValue=endMinValue;
if(startIndex-endIndex!=0)
{
nowMinValue+=(endMinValue-startMinValue)/(startIndex-endIndex)*(endIndex-offset);
}
double nowMaxValue=SmoothedMaxValues[offset];
if(nowMaxValue-nowMinValue>ChannelWidth*_Point)
{
if(EndMin!=offset)
{
EndMax=Time[offset];
StartMax=Time[offset];
Direction=UP;
// Drawing
StartDraw=EndMin;
EndDraw=EndMax;
StartDrawValue=endMinValue;
EndDrawValue=nowMaxValue;
Counter++;
LastLength=Length;
Length=int(NormalizeDouble((nowMaxValue-endMinValue)/_Point,0));
RePaint();
}
}
}
//----
}
//+----------------------------------------------------------------------------+
//| |
//+----------------------------------------------------------------------------+
void RePaint()
{
//----
if(DrawInfo)
{
double pos=EndDrawValue;
if(Direction==UP) pos+=15*_Point;
string id="Stats"+TimeToString(EndDraw,TIME_DATE|TIME_MINUTES);
string text;
if(LastLength) text=text+DoubleToString((0.0001+Length)/(0.0001+LastLength),2);
text=text+"("+string(Length)+")";
SetText(0,id,0,EndDraw,pos,text,TextColor,"Arial Black",FontSize,ANCHOR_CENTER);
}
int start=iBarShift(symbol,PERIOD_CURRENT,StartDraw);
int end=iBarShift(symbol,PERIOD_CURRENT,EndDraw);
if(start==end)
{
ZZ[end]=EndDrawValue;
return;
}
double preValue=(EndDrawValue-StartDrawValue)/(end-start);
for(int i=start; i>=end; i--)
{
ZZ[i]=StartDrawValue+preValue*(i-start);
}
//----
}
//+------------------------------------------------------------------+
//| iBarShift() function |
//+------------------------------------------------------------------+
int iBarShift(string symbol_,ENUM_TIMEFRAMES timeframe,datetime time)
// iBarShift(symbol, timeframe, time)
//+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -+
{
//----
if(time<0) return(-1);
datetime Arr[],time1;
time1=(datetime)SeriesInfoInteger(symbol_,timeframe,SERIES_LASTBAR_DATE);
if(CopyTime(symbol_,timeframe,time,time1,Arr)>0)
{
int size=ArraySize(Arr);
return(size-1);
}
else return(-1);
//----
}
//+------------------------------------------------------------------+
//| creating a text label |
//+------------------------------------------------------------------+
void CreateText(long chart_id,// chart ID
string name, // object name
int nwin, // window index
datetime time, // price level time
double price, // price level
string text, // Labels text
color Color, // Text color
string Font, // Text font
int Size, // Text size
ENUM_ANCHOR_POINT point // The chart corner to Which an text is attached
)
//----
{
//----
ObjectCreate(chart_id,name,OBJ_TEXT,nwin,time,price);
ObjectSetString(chart_id,name,OBJPROP_TEXT,text);
ObjectSetInteger(chart_id,name,OBJPROP_COLOR,Color);
ObjectSetString(chart_id,name,OBJPROP_FONT,Font);
ObjectSetInteger(chart_id,name,OBJPROP_FONTSIZE,Size);
ObjectSetInteger(chart_id,name,OBJPROP_BACK,false);
ObjectSetInteger(chart_id,name,OBJPROP_ANCHOR,point);
//----
}
//+------------------------------------------------------------------+
//| changing a text label |
//+------------------------------------------------------------------+
void SetText(long chart_id,// chart ID
string name, // object name
int nwin, // window index
datetime time, // price level time
double price, // price level
string text, // Labels text
color Color, // Text color
string Font, // Text font
int Size, // Text size
ENUM_ANCHOR_POINT point // The chart corner to Which an text is attached
)
//----
{
//----
if(ObjectFind(chart_id,name)==-1) CreateText(chart_id,name,nwin,time,price,text,Color,Font,Size,point);
else
{
ObjectSetString(chart_id,name,OBJPROP_TEXT,text);
ObjectMove(chart_id,name,0,time,price);
}
//----
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---