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);
| |||
}
| |||
//+------------------------------------------------------------------+
|