115 lines
4.2 KiB
MQL5
115 lines
4.2 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| RSI.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 "Relative Strength Index"
|
|
//--- indicator settings
|
|
#property indicator_separate_window
|
|
#property indicator_minimum 0
|
|
#property indicator_maximum 100
|
|
#property indicator_level1 30
|
|
#property indicator_level2 70
|
|
#property indicator_buffers 3
|
|
#property indicator_plots 1
|
|
#property indicator_type1 DRAW_LINE
|
|
#property indicator_color1 clrDodgerBlue
|
|
//--- input parameters
|
|
input int InpPeriodRSI=14; // Period
|
|
//--- indicator buffers
|
|
double ExtRSIBuffer[];
|
|
double ExtPosBuffer[];
|
|
double ExtNegBuffer[];
|
|
|
|
int ExtPeriodRSI;
|
|
//+------------------------------------------------------------------+
|
|
//| Custom indicator initialization function |
|
|
//+------------------------------------------------------------------+
|
|
void OnInit()
|
|
{
|
|
//--- check for input
|
|
if(InpPeriodRSI<1)
|
|
{
|
|
ExtPeriodRSI=14;
|
|
PrintFormat("Incorrect value for input variable InpPeriodRSI = %d. Indicator will use value %d for calculations.",
|
|
InpPeriodRSI,ExtPeriodRSI);
|
|
}
|
|
else
|
|
ExtPeriodRSI=InpPeriodRSI;
|
|
//--- indicator buffers mapping
|
|
SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
|
|
SetIndexBuffer(1,ExtPosBuffer,INDICATOR_CALCULATIONS);
|
|
SetIndexBuffer(2,ExtNegBuffer,INDICATOR_CALCULATIONS);
|
|
//--- set accuracy
|
|
IndicatorSetInteger(INDICATOR_DIGITS,2);
|
|
//--- sets first bar from what index will be drawn
|
|
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
|
|
//--- name for DataWindow and indicator subwindow label
|
|
IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Relative Strength Index |
|
|
//+------------------------------------------------------------------+
|
|
int OnCalculate(const int rates_total,
|
|
const int prev_calculated,
|
|
const int begin,
|
|
const double &price[])
|
|
{
|
|
if(rates_total<=ExtPeriodRSI)
|
|
return(0);
|
|
//--- preliminary calculations
|
|
int pos=prev_calculated-1;
|
|
if(pos<=ExtPeriodRSI)
|
|
{
|
|
double sum_pos=0.0;
|
|
double sum_neg=0.0;
|
|
//--- first RSIPeriod values of the indicator are not calculated
|
|
ExtRSIBuffer[0]=0.0;
|
|
ExtPosBuffer[0]=0.0;
|
|
ExtNegBuffer[0]=0.0;
|
|
for(int i=1; i<=ExtPeriodRSI; i++)
|
|
{
|
|
ExtRSIBuffer[i]=0.0;
|
|
ExtPosBuffer[i]=0.0;
|
|
ExtNegBuffer[i]=0.0;
|
|
double diff=price[i]-price[i-1];
|
|
sum_pos+=(diff>0?diff:0);
|
|
sum_neg+=(diff<0?-diff:0);
|
|
}
|
|
//--- calculate first visible value
|
|
ExtPosBuffer[ExtPeriodRSI]=sum_pos/ExtPeriodRSI;
|
|
ExtNegBuffer[ExtPeriodRSI]=sum_neg/ExtPeriodRSI;
|
|
if(ExtNegBuffer[ExtPeriodRSI]!=0.0)
|
|
ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
|
|
else
|
|
{
|
|
if(ExtPosBuffer[ExtPeriodRSI]!=0.0)
|
|
ExtRSIBuffer[ExtPeriodRSI]=100.0;
|
|
else
|
|
ExtRSIBuffer[ExtPeriodRSI]=50.0;
|
|
}
|
|
//--- prepare the position value for main calculation
|
|
pos=ExtPeriodRSI+1;
|
|
}
|
|
//--- the main loop of calculations
|
|
for(int i=pos; i<rates_total && !IsStopped(); i++)
|
|
{
|
|
double diff=price[i]-price[i-1];
|
|
ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
|
|
ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
|
|
if(ExtNegBuffer[i]!=0.0)
|
|
ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
|
|
else
|
|
{
|
|
if(ExtPosBuffer[i]!=0.0)
|
|
ExtRSIBuffer[i]=100.0;
|
|
else
|
|
ExtRSIBuffer[i]=50.0;
|
|
}
|
|
}
|
|
//--- OnCalculate done. Return new prev_calculated.
|
|
return(rates_total);
|
|
}
|
|
//+------------------------------------------------------------------+
|