MT4_To_MT5_Indicat/SAR_index_based_on_MA__3.mq5
super.admin ffa3b09afa convert
2025-05-30 16:10:02 +02:00

250 lines
18 KiB
MQL5

//+------------------------------------------------------------------+
//| SAR index based on MA.mq5 |
//| Copyright © 2018, Vladimir Karputov |
//| http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2018, Vladimir Karputov"
#property link "http://wmua.ru/slesar/"
#property version "1.004"
//--- indicator settings
#property indicator_chart_window
#property indicator_buffers 4
#property indicator_plots 2
#property indicator_type1 DRAW_ARROW
#property indicator_color1 clrDodgerBlue
#property indicator_type2 DRAW_LINE
#property indicator_color2 clrRed
//--- External parametrs
input double InpSARStep=0.02; // Step
input double InpSARMaximum=0.04; // Maximum
//---- buffers
double ExtSARBuffer[];
double ExtMABuffer[];
double ExtEPBuffer[];
double ExtAFBuffer[];
//--- global variables
int ExtLastRevPos;
bool ExtDirectionLong;
double ExtSarStep;
double ExtSarMaximum;
//---
int handle_iMA; // variable for storing the handle of the iMA indicator
//--- we will keep the number of values in the Moving Average indicator
int bars_calculated=0;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- checking input data
if(InpSARStep<0.0)
{
ExtSarStep=0.02;
Print("Input parametr InpSARStep has incorrect value. Indicator will use value",
ExtSarStep,"for calculations.");
}
else
ExtSarStep=InpSARStep;
if(InpSARMaximum<0.0)
{
ExtSarMaximum=0.2;
Print("Input parametr InpSARMaximum has incorrect value. Indicator will use value",
ExtSarMaximum,"for calculations.");
}
else
ExtSarMaximum=InpSARMaximum;
//--- indicator buffers
SetIndexBuffer(0,ExtSARBuffer,INDICATOR_DATA);
SetIndexBuffer(1,ExtMABuffer,INDICATOR_DATA);
SetIndexBuffer(2,ExtEPBuffer,INDICATOR_CALCULATIONS);
SetIndexBuffer(3,ExtAFBuffer,INDICATOR_CALCULATIONS);
//--- set arrow symbol
PlotIndexSetInteger(0,PLOT_ARROW,159);
//--- set indicator digits
IndicatorSetInteger(INDICATOR_DIGITS,_Digits);
//--- set label name
PlotIndexSetString(0,PLOT_LABEL,"SAR("+
DoubleToString(ExtSarStep,2)+","+
DoubleToString(ExtSarMaximum,2)+")");
//--- set global variables
ExtLastRevPos=0;
ExtDirectionLong=false;
//--- create handle of the indicator iMA
handle_iMA=iMA(Symbol(),Period(),14,0,MODE_LWMA,PRICE_CLOSE);
//--- if the handle is not created
if(handle_iMA==INVALID_HANDLE)
{
//--- tell about the failure and output the error code
PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
Symbol(),
EnumToString(Period()),
GetLastError());
//--- the indicator is stopped early
return(INIT_FAILED);
}
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
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[])
{
//--- check for minimum rates count
if(rates_total<3)
return(0);
//--- detect current position
int pos=prev_calculated-1;
//--- correct position
if(pos<1)
{
//--- first pass, set as SHORT
pos=1;
ExtAFBuffer[0]=ExtSarStep;
ExtAFBuffer[1]=ExtSarStep;
ExtSARBuffer[0]=high[0];
ExtLastRevPos=0;
ExtDirectionLong=false;
ExtSARBuffer[1]=GetHigh(pos,ExtLastRevPos,high);
ExtEPBuffer[0]=low[pos];
ExtEPBuffer[1]=low[pos];
}
//---main cycle
for(int i=pos;i<rates_total-1 && !IsStopped();i++)
{
//--- check for reverse
if(ExtDirectionLong)
{
if(ExtSARBuffer[i]>low[i])
{
//--- switch to SHORT
ExtDirectionLong=false;
ExtSARBuffer[i]=GetHigh(i,ExtLastRevPos,high);
ExtEPBuffer[i]=low[i];
ExtLastRevPos=i;
ExtAFBuffer[i]=ExtSarStep;
}
}
else
{
if(ExtSARBuffer[i]<high[i])
{
//--- switch to LONG
ExtDirectionLong=true;
ExtSARBuffer[i]=GetLow(i,ExtLastRevPos,low);
ExtEPBuffer[i]=high[i];
ExtLastRevPos=i;
ExtAFBuffer[i]=ExtSarStep;
}
}
//--- continue calculations
if(ExtDirectionLong)
{
//--- check for new High
if(high[i]>ExtEPBuffer[i-1] && i!=ExtLastRevPos)
{
ExtEPBuffer[i]=high[i];
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
if(ExtAFBuffer[i]>ExtSarMaximum)
ExtAFBuffer[i]=ExtSarMaximum;
}
else
{
//--- when we haven't reversed
if(i!=ExtLastRevPos)
{
ExtAFBuffer[i]=ExtAFBuffer[i-1];
ExtEPBuffer[i]=ExtEPBuffer[i-1];
}
}
//--- calculate SAR for tomorrow
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
//--- check for SAR
if(ExtSARBuffer[i+1]>low[i] || ExtSARBuffer[i+1]>low[i-1])
ExtSARBuffer[i+1]=MathMin(low[i],low[i-1]);
}
else
{
//--- check for new Low
if(low[i]<ExtEPBuffer[i-1] && i!=ExtLastRevPos)
{
ExtEPBuffer[i]=low[i];
ExtAFBuffer[i]=ExtAFBuffer[i-1]+ExtSarStep;
if(ExtAFBuffer[i]>ExtSarMaximum)
ExtAFBuffer[i]=ExtSarMaximum;
}
else
{
//--- when we haven't reversed
if(i!=ExtLastRevPos)
{
ExtAFBuffer[i]=ExtAFBuffer[i-1];
ExtEPBuffer[i]=ExtEPBuffer[i-1];
}
}
//--- calculate SAR for tomorrow
ExtSARBuffer[i+1]=ExtSARBuffer[i]+ExtAFBuffer[i]*(ExtEPBuffer[i]-ExtSARBuffer[i]);
//--- check for SAR
if(ExtSARBuffer[i+1]<high[i] || ExtSARBuffer[i+1]<high[i-1])
ExtSARBuffer[i+1]=MathMax(high[i],high[i-1]);
}
}
//---- OnCalculate done. Return new prev_calculated.
return(rates_total);
}
//+------------------------------------------------------------------+
//| Find highest price from start to current position |
//+------------------------------------------------------------------+
double GetHigh(int nPosition,int nStartPeriod,const double &HiData[])
{
//--- calculate
double result=HiData[nStartPeriod];
for(int i=nStartPeriod;i<=nPosition;i++)
if(result<HiData[i])
result=HiData[i];
return(result);
}
//+------------------------------------------------------------------+
//| Find lowest price from start to current position |
//+------------------------------------------------------------------+
double GetLow(int nPosition,int nStartPeriod,const double &LoData[])
{
//--- calculate
double result=LoData[nStartPeriod];
for(int i=nStartPeriod;i<=nPosition;i++)
if(result>LoData[i])
result=LoData[i];
return(result);
}
//+------------------------------------------------------------------+
//| Filling indicator buffers from the MA indicator |
//+------------------------------------------------------------------+
bool FillArrayFromBuffer(double &values[], // indicator buffer of Moving Average values
int shift, // shift
int ind_handle, // handle of the iMA indicator
int amount // number of copied values
)
{
//--- reset error code
ResetLastError();
//--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index
if(CopyBuffer(ind_handle,0,-shift,amount,values)<0)
{
//--- if the copying fails, tell the error code
PrintFormat("Failed to copy data from the iMA indicator, error code %d",GetLastError());
//--- quit with zero result - it means that the indicator is considered as not calculated
return(false);
}
//--- everything is fine
return(true);
}
//+------------------------------------------------------------------+