//+------------------------------------------------------------------+ //| ReVoIn.mq5 | //| Copyright © 2019, Vladimir Karputov | //| http://wmua.ru/slesar/ | //+------------------------------------------------------------------+ #property copyright "Copyright © 2019, Vladimir Karputov" #property link "http://wmua.ru/slesar/" #property version "1.000" #property indicator_separate_window #property indicator_buffers 4 #property indicator_plots 1 //--- plot ReVoIn #property indicator_label1 "ReVoIn" #property indicator_type1 DRAW_LINE #property indicator_color1 clrViolet #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- input parameters input int InpReVoIn=14; // ReVoIn: averaging period //--- StdDev input int Inp_StdDev_ma_period = 10; // StdDev: averaging period input int Inp_StdDev_ma_shift = 0; // StdDev: horizontal shift input ENUM_MA_METHOD Inp_StdDev_ma_method = MODE_EMA; // StdDev: smoothing type input ENUM_APPLIED_PRICE Inp_StdDev_applied_price= PRICE_CLOSE; // StdDev: type of price //--- indicator buffers double ReVoInBuffer[]; double iStdDevBuffer[]; double bBUF2[]; double bBUF3[]; //--- int handle_iStdDev; // variable for storing the handle of the iStdDev indicator int bars_calculated=0; // we will keep the number of values in the Standard Deviation indicator //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- indicator buffers mapping SetIndexBuffer(0,ReVoInBuffer,INDICATOR_DATA); SetIndexBuffer(1,iStdDevBuffer,INDICATOR_CALCULATIONS); SetIndexBuffer(2,bBUF2,INDICATOR_CALCULATIONS); SetIndexBuffer(3,bBUF3,INDICATOR_CALCULATIONS); //--- create handle of the indicator iStdDev handle_iStdDev=iStdDev(Symbol(),Period(),Inp_StdDev_ma_period, Inp_StdDev_ma_shift,Inp_StdDev_ma_method,Inp_StdDev_applied_price); //--- if the handle is not created if(handle_iStdDev==INVALID_HANDLE) { //--- tell about the failure and output the error code PrintFormat("Failed to create handle of the iStdDev 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[]) { //--- number of values copied from the iStdDev indicator int values_to_copy; //--- determine the number of values calculated in the indicator int calculated=BarsCalculated(handle_iStdDev); if(calculated<=0) { PrintFormat("BarsCalculated() returned %d, error code %d",calculated,GetLastError()); return(0); } //--- if it is the first start of calculation of the indicator or if the number of values in the iStdDev indicator changed //---or if it is necessary to calculated the indicator for two or more bars (it means something has changed in the price history) if(prev_calculated==0 || calculated!=bars_calculated || rates_total>prev_calculated+1) { //--- if the iStdDevBuffer array is greater than the number of values in the iStdDev indicator for symbol/period, then we don't copy everything //--- otherwise, we copy less than the size of indicator buffers if(calculated>rates_total) values_to_copy=rates_total; else values_to_copy=calculated; } else { //--- it means that it's not the first time of the indicator calculation, and since the last call of OnCalculate() //--- for calculation not more than one bar is added values_to_copy=(rates_total-prev_calculated)+1; } //--- fill the array with values of the Standard Deviation indicator //--- if FillArrayFromBuffer returns false, it means the information is nor ready yet, quit operation if(!FillArrayFromBuffer(iStdDevBuffer,Inp_StdDev_ma_shift,handle_iStdDev,values_to_copy)) return(0); int limit=prev_calculated-1; if(prev_calculated==0) limit=15; for(int i=limit;i0.0) Sum_StDev2+=pStrDev; else Sum_StDev1+=pStrDev; } StDevAve2 = Sum_StDev2 / InpReVoIn; StDevAve1 = Sum_StDev1 / InpReVoIn; } else { vClose=close[i]-close[i-1]; pStrDev=iStdDevBuffer[i]; if(vClose>0.0) Sum_StDev2=pStrDev; else Sum_StDev1=pStrDev; StDevAve2 = ((bBUF2[i-1]) * (InpReVoIn - 1) + Sum_StDev2) / InpReVoIn; StDevAve1 = ((bBUF3[i-1]) * (InpReVoIn - 1) + Sum_StDev1) / InpReVoIn; } //--- bBUF2[i] = StDevAve2; bBUF3[i] = StDevAve1; if(StDevAve1==0.0) ReVoInBuffer[i]=0.0; else ReVoInBuffer[i]=100.0-100.0/(StDevAve2/StDevAve1+1.0); int d=0; } //--- memorize the number of values in the Standard Deviation indicator bars_calculated=calculated; //--- return the prev_calculated value for the next call return(rates_total); } //+------------------------------------------------------------------+ //| Filling indicator buffers from the iStdDev indicator | //+------------------------------------------------------------------+ bool FillArrayFromBuffer(double &std_buffer[], // indicator buffer of the Standard Deviation line int std_shift, // shift of the Standard Deviation line int ind_handle, // handle of the iStdDev indicator int amount // number of copied values ) { //--- reset error code ResetLastError(); //--- fill a part of the iStdDevBuffer array with values from the indicator buffer that has 0 index if(CopyBuffer(ind_handle,0,-std_shift,amount,std_buffer)<0) { //--- if the copying fails, tell the error code PrintFormat("Failed to copy data from the iStdDev 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); } //+------------------------------------------------------------------+