mql-for-begginers/Indicators/Examples/Gator.mq5
2025-07-22 18:30:17 +03:00

264 lines
9.7 KiB
MQL5

//+------------------------------------------------------------------+
//| Gator.mq5 |
//| Copyright 2000-2025, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2025, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property description "Gator Oscillator"
#property description "based on 3 non-shifted moving averages"
//********************************************************************
// Attention! Following correlations must be obeyed:
// 1.InpJawsPeriod>InpTeethPeriod>InpLipsPeriod;
// 2.InpJawsShift>InpTeethShift>InpLipsShift;
// 3.InpJawsPeriod>InpJawsShift;
// 4.InpTeethPeriod>InpTeethShift;
// 5.InpLipsPeriod>InpLipsShift.
//********************************************************************
//--- indicator settings
#property indicator_separate_window
#property indicator_buffers 7
#property indicator_plots 2
#property indicator_type1 DRAW_COLOR_HISTOGRAM
#property indicator_type2 DRAW_COLOR_HISTOGRAM
#property indicator_color1 clrGreen,clrRed
#property indicator_color2 clrGreen,clrRed
#property indicator_width1 2
#property indicator_width2 2
#property indicator_label1 "Gator Upper"
#property indicator_label2 "Gator Lower"
//--- input parameters
input int InpJawsPeriod=13; // Jaws period
input int InpJawsShift=8; // Jaws shift
input int InpTeethPeriod=8; // Teeth period
input int InpTeethShift=5; // Teeth shift
input int InpLipsPeriod=5; // Lips period
input int InpLipsShift=3; // Lips shift
input ENUM_MA_METHOD InpMAMethod=MODE_SMMA; // Moving average method
input ENUM_APPLIED_PRICE InpAppliedPrice=PRICE_MEDIAN; // Applied price
//--- indicator buffers
double ExtUpperBuffer[];
double ExtUpColorsBuffer[];
double ExtLowerBuffer[];
double ExtLoColorsBuffer[];
double ExtJawsBuffer[];
double ExtTeethBuffer[];
double ExtLipsBuffer[];
int ExtJawsHandle;
int ExtTeethHandle;
int ExtLipsHandle;
int ExtUpperShift;
int ExtLowerShift;
bool ExtFlag;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- indicator buffers mapping
SetIndexBuffer(0,ExtUpperBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtUpColorsBuffer,INDICATOR_COLOR_INDEX);
SetIndexBuffer(2,ExtLowerBuffer,INDICATOR_DATA);
SetIndexBuffer(3,ExtLoColorsBuffer,INDICATOR_COLOR_INDEX);
//--- MAs
SetIndexBuffer(4,ExtJawsBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(5,ExtTeethBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(6,ExtLipsBuffer,INDICATOR_CALCULATIONS);
//--- get handles
ExtJawsHandle=iMA(NULL,0,InpJawsPeriod,0,InpMAMethod,InpAppliedPrice);
ExtTeethHandle=iMA(NULL,0,InpTeethPeriod,0,InpMAMethod,InpAppliedPrice);
ExtLipsHandle=iMA(NULL,0,InpLipsPeriod,0,InpMAMethod,InpAppliedPrice);
//--- set indicator digits
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//--- sets first bar from what index will be drawn
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,InpTeethShift+InpTeethPeriod);
PlotIndexSetInteger(1,PLOT_DRAW_BEGIN,InpLipsShift+InpLipsPeriod);
//--- line shifts when drawing
PlotIndexSetInteger(0,PLOT_SHIFT,InpTeethShift);
PlotIndexSetInteger(1,PLOT_SHIFT,InpLipsShift);
//--- name for indicator subwindow label
string short_name=StringFormat("Gator(%d,%d,%d)",InpJawsPeriod,InpTeethPeriod,InpLipsPeriod);
IndicatorSetString(INDICATOR_SHORTNAME,short_name);
//--- sets drawing line empty value
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
PlotIndexSetDouble(1,PLOT_EMPTY_VALUE,0.0);
//--- calculate global variables values
ExtUpperShift=InpJawsShift-InpTeethShift;
ExtLowerShift=InpTeethShift-InpLipsShift;
//--- check for input parameters
ExtFlag=CheckForInput();
if(!ExtFlag)
Print("Wrong input parameters. Indicator won't work.");
//--- initialization done. 0 returned if ExtFlag is true
return(!ExtFlag);
}
//+------------------------------------------------------------------+
//| Gator Oscillator |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
const int prev_calculated,
const datetime &time[],
const double &open[],
const double &high[],
const double &low[],
const double &close[],
const long &tick_volume[],
const long &volume[],
const int &spread[])
{
int shift;
//--- check for rules and bars count
if(ExtUpperShift>ExtLowerShift)
shift=ExtUpperShift;
else
shift=ExtLowerShift;
if(!ExtFlag || shift>rates_total)
return(0);
//--- not all data may be calculated
int calculated=BarsCalculated(ExtJawsHandle);
if(calculated<rates_total)
{
Print("Not all data of ExtJawsHandle is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
calculated=BarsCalculated(ExtTeethHandle);
if(calculated<rates_total)
{
Print("Not all data of ExtTeethHandle is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
calculated=BarsCalculated(ExtLipsHandle);
if(calculated<rates_total)
{
Print("Not all data of ExtLipsHandle is calculated (",calculated," bars). Error ",GetLastError());
return(0);
}
//--- we can copy not all data
int to_copy;
if(prev_calculated>rates_total || prev_calculated<0)
to_copy=rates_total;
else
{
to_copy=rates_total-prev_calculated;
if(prev_calculated>0)
to_copy++;
}
//--- get ma buffers
if(IsStopped()) // checking for stop flag
return(0);
if(CopyBuffer(ExtJawsHandle,0,0,to_copy,ExtJawsBuffer)<=0)
{
Print("getting ExtJawsHandle is failed! Error",GetLastError());
return(0);
}
if(IsStopped()) // checking for stop flag
return(0);
if(CopyBuffer(ExtTeethHandle,0,0,to_copy,ExtTeethBuffer)<=0)
{
Print("getting ExtTeethHandle is failed! Error",GetLastError());
return(0);
}
if(IsStopped()) // checking for stop flag
return(0);
if(CopyBuffer(ExtLipsHandle,0,0,to_copy,ExtLipsBuffer)<=0)
{
Print("getting ExtLipsHandle is failed! Error",GetLastError());
return(0);
}
//--- last 2 counted bars will be recounted
int pos=prev_calculated-2;
if(pos<shift)
{
for(int i=0; i<shift; i++)
{
ExtUpperBuffer[i]=0.0;
ExtUpColorsBuffer[i]=0.0;
ExtLowerBuffer[i]=0.0;
ExtLoColorsBuffer[i]=0.0;
}
pos=shift;
}
//--- main cycle
double cur_value,prev_value;
int lower_limit=ExtLowerShift+InpLipsShift+InpLipsPeriod;
int upper_limit=ExtUpperShift+InpTeethShift+InpTeethPeriod;
for(int i=pos; i<rates_total && !IsStopped(); i++)
{
if(i>=lower_limit)
{
//--- calculate down buffer value
cur_value=-MathAbs(ExtTeethBuffer[i-ExtLowerShift]-ExtLipsBuffer[i]);
prev_value=ExtLowerBuffer[i-1];
ExtLowerBuffer[i]=cur_value;
//--- set down buffer color
if(prev_value==cur_value)
ExtLoColorsBuffer[i]=ExtLoColorsBuffer[i-1];
else
{
if(prev_value<cur_value)
ExtLoColorsBuffer[i]=1.0;
else
ExtLoColorsBuffer[i]=0.0;
}
}
else
{
ExtLowerBuffer[i]=0.0;
ExtLoColorsBuffer[i]=0.0;
}
if(i>=upper_limit)
{
//--- calculate up buffer value
cur_value=MathAbs(ExtJawsBuffer[i-ExtUpperShift]-ExtTeethBuffer[i]);
ExtUpperBuffer[i]=cur_value;
prev_value=ExtUpperBuffer[i-1];
//--- set up buffer color
if(prev_value==cur_value)
ExtUpColorsBuffer[i]=ExtUpColorsBuffer[i-1];
else
{
if(prev_value<cur_value)
ExtUpColorsBuffer[i]=0.0;
else
ExtUpColorsBuffer[i]=1.0;
}
}
else
{
ExtUpperBuffer[i]=0.0;
ExtUpColorsBuffer[i]=0.0;
}
}
//---
return(rates_total);
}
//+------------------------------------------------------------------+
//| Check for rules |
//| 1.InpJawsPeriod>InpTeethPeriod>InpLipsPeriod; |
//| 2.InpJawsShift>InpTeethShift>InpLipsShift; |
//| 3.InpJawsPeriod>InpJawsShift; |
//| 4.InpTeethPeriod>InpTeethShift; |
//| 5.InpLipsPeriod>InpLipsShift. |
//+------------------------------------------------------------------+
bool CheckForInput()
{
//--- 1
if(InpJawsPeriod<=InpTeethPeriod || InpTeethPeriod<=InpLipsPeriod)
return(false);
//--- 2
if(InpJawsShift<=InpTeethShift || InpTeethShift<=InpLipsShift)
return(false);
//--- 3
if(InpJawsPeriod<=InpJawsShift)
return(false);
//--- 4
if(InpTeethPeriod<=InpTeethShift)
return(false);
//--- 5
if(InpLipsPeriod<=InpLipsShift)
return(false);
//--- all right
return(true);
}
//+------------------------------------------------------------------+