/////////////////////////////////////////////////////// // // SaherElm IT Center RSI Oscillator // --------------------------------------------- // saherelm implementation of above oscillator ... // // Maintainer: // ------------ // Hadi Khazaee Asl (hadi_khazaee_asl@yahoo.com) // ////////////////////////////////////////////////////// // // Global Properties ... #property copyright "Copyright 2023, SaherElm IT Center" #property link "https://saherelm.ir" #property version "1.00" #property description "SaherElm RSI Oscillator" #property strict // // START Inputs ... // input int rsiPeriod=14; // RSI Period // // END Inputs ... // // // START Global Definitions: Variables, Properties and etc ... // // #property indicator_separate_window // #property indicator_minimum 0 #property indicator_maximum 100 // #property indicator_buffers 1 #property indicator_color1 DodgerBlue // #property indicator_level1 30.0 #property indicator_level2 50.0 #property indicator_level3 70.0 #property indicator_levelcolor clrSilver #property indicator_levelstyle STYLE_DOT // // Declare Buffers ... #define rsiBufferIndex 0 #define positiveBufferIndex 1 #define negativeBufferIndex 2 double rsiBuffer[]; double positiveBuffer[]; double negativeBuffer[]; // // END Global Definitions: Variables, Properties and etc ... // // // Start Event Handlers ... // // // Initialization ... int OnInit() { // // Initialize what we want ... // string short_name; // IndicatorBuffers(3); // SetIndexBuffer(positiveBufferIndex, positiveBuffer); SetIndexBuffer(negativeBufferIndex, negativeBuffer); // SetIndexStyle(rsiBufferIndex, DRAW_LINE); SetIndexBuffer(rsiBufferIndex, rsiBuffer); // // name for DataWindow and indicator subwindow label short_name="RSI("+string(rsiPeriod)+")"; IndicatorShortName(short_name); SetIndexLabel(rsiBufferIndex, short_name); // // check for input if (rsiPeriod < 2) { // Print("Incorrect value for input variable InpRSIPeriod = ", rsiPeriod); // // Failed Initialization ... return INIT_PARAMETERS_INCORRECT; } // // set where to start draw ... SetIndexDrawBegin(0, rsiPeriod); // // initialization done ... return INIT_SUCCEEDED; } // // Do Calculation ... 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 i,pos; double diff; // // Prevent from run calculations if there is no fulfilled conditions ... if (Bars <= rsiPeriod || rsiPeriod < 2) { // // return nothing calculated result ... return 0; } // // counting from 0 to rates_total, this is most important ... ArraySetAsSeries(rsiBuffer, false); ArraySetAsSeries(positiveBuffer, false); ArraySetAsSeries(negativeBuffer, false); // ArraySetAsSeries(close, false); // // preliminary calculations ... pos = prev_calculated - 1; if (pos <= rsiPeriod) { // // first RSIPeriod values of the indicator are not calculated rsiBuffer[0] = 0.0; positiveBuffer[0] = 0.0; negativeBuffer[0] = 0.0; // double sump=0.0; double sumn=0.0; for (i = 1; i <= rsiPeriod; i++) { // rsiBuffer[i]=0.0; positiveBuffer[i]=0.0; negativeBuffer[i]=0.0; // diff = close[i] - close[i - 1]; if(diff > 0) { sump += diff; } else { sumn -= diff; } } // // calculate first visible value ... positiveBuffer[rsiPeriod] = sump / rsiPeriod; negativeBuffer[rsiPeriod] = sumn / rsiPeriod; if (negativeBuffer[rsiPeriod] != 0.0) { // rsiBuffer[rsiPeriod] = 100.0 - ( 100.0 / ( 1.0 + positiveBuffer[rsiPeriod] / negativeBuffer[rsiPeriod] ) ); } else { // if (positiveBuffer[rsiPeriod] != 0.0) { rsiBuffer[rsiPeriod] = 100.0; } else { rsiBuffer[rsiPeriod] = 50.0; } } // // prepare the position value for main calculation ... pos = rsiPeriod + 1; } // // the main loop of calculations ... for (i = pos; i < rates_total && !IsStopped(); i++) { // diff = close[i] - close[i-1]; // positiveBuffer[i] = (positiveBuffer[i-1] * (rsiPeriod - 1) + (diff > 0.0 ? diff : 0.0)) / rsiPeriod; negativeBuffer[i] = (negativeBuffer[i-1] * (rsiPeriod - 1) + (diff < 0.0 ? -diff : 0.0)) / rsiPeriod; // if (negativeBuffer[i] != 0.0) { rsiBuffer[i] = 100.0 - 100.0 / (1 + positiveBuffer[i] / negativeBuffer[i]); } else { // if (positiveBuffer[i] != 0.0) { rsiBuffer[i] = 100.0; } else { rsiBuffer[i] = 50.0; } } } // return(rates_total); } // // END Event Handlers ... // // // START Functions ... // // // END Functions ... //