Author: copyright© mladen
dsl_-_rsi

This script is a specialized technical analysis tool designed for the MetaTrader platform. It provides traders with visual data to help identify market trends and potential price movements by combining two sophisticated financial concepts: Relative Strength Index (RSI) and Heikin Ashi price smoothing.

Here is a breakdown of how the logic works in plain terms:

Core Data Processing

The tool starts by taking standard market prices (like Open, High, Low, and Close) and transforming them into Heikin Ashi values. Heikin Ashi is a popular charting method used to filter out "market noise," making it easier to see the underlying trend of the price movement.

Advanced RSI Calculation

Instead of using a standard RSI, which can often be jagged or erratic, this script calculates a customized RSI based on those smoothed Heikin Ashi values. It allows you to choose exactly which type of price data (such as "Median," "Typical," or "Weighted") the RSI should track. This gives the user significant flexibility in how the momentum is measured.

Trend Tracking and Smoothing

The script goes beyond a simple "overbought" or "oversold" calculation. It uses a dynamic logic to track trend levels:

  • Dynamic Thresholds: It calculates two moving "levels"—one for upward trends and one for downward trends.
  • Alpha Smoothing: It uses a mathematical smoothing factor (Alpha) to ensure that these levels move fluidly rather than jumping abruptly from bar to bar.
  • State Detection: The script identifies the market "state." If the current price is above its upper dynamic level, it registers a bullish state; if below the lower level, it registers a bearish state.

Visual Presentation (Signal Lines)

The final output is designed to be clean and readable on your chart. It doesn't just show raw numbers; it creates distinct visual "points" or segments based on the market state.

  • It uses logic to detect where one trend ends and another begins.
  • It "cleans" the data points so that you see clear, continuous lines representing the current momentum.
  • By plotting these smoothed signal lines, the tool helps traders visualize whether the current price action is confirming a sustained trend or if it is simply fluctuating within a range.

Summary for the User

In short, this script acts as a momentum stabilizer. It takes raw, messy price data, cleans it using Heikin Ashi logic, calculates the strength of that movement via a custom RSI, and then draws smooth visual lines that help you see whether the market is trending up, trending down, or staying neutral.

18 Views
0 Downloads
0 Favorites
dsl_-_rsi
ÿþ//------------------------------------------------------------------

#property copyright   "copyright© mladen"

#property description "discontinued signal lines rsi"

#property description "made by mladen"

#property link        "mladenfx@gmail.com"

//------------------------------------------------------------------



#property indicator_separate_window

#property indicator_buffers 7

#property indicator_color1  clrDimGray

#property indicator_color2  clrDimGray

#property indicator_color3  clrSilver

#property indicator_color4  clrLimeGreen

#property indicator_color5  clrLimeGreen

#property indicator_color6  clrOrange

#property indicator_color7  clrOrange

#property indicator_style1  STYLE_DOT

#property indicator_style2  STYLE_DOT

#property indicator_width3  2

#property indicator_width4  2

#property indicator_width5  2

#property indicator_width6  2

#property indicator_width7  2

#property strict



//

//

//

//

//



enum enPrices

{

   pr_close,      // Close

   pr_open,       // Open

   pr_high,       // High

   pr_low,        // Low

   pr_median,     // Median

   pr_typical,    // Typical

   pr_weighted,   // Weighted

   pr_average,    // Average (high+low+open+close)/4

   pr_medianb,    // Average median body (open+close)/2

   pr_tbiased,    // Trend biased price

   pr_tbiased2,   // Trend biased (extreme) price

   pr_haclose,    // Heiken ashi close

   pr_haopen ,    // Heiken ashi open

   pr_hahigh,     // Heiken ashi high

   pr_halow,      // Heiken ashi low

   pr_hamedian,   // Heiken ashi median

   pr_hatypical,  // Heiken ashi typical

   pr_haweighted, // Heiken ashi weighted

   pr_haaverage,  // Heiken ashi average

   pr_hamedianb,  // Heiken ashi median body

   pr_hatbiased,  // Heiken ashi trend biased price

   pr_hatbiased2  // Heiken ashi trend biased (extreme) price

};



extern int      RsiPeriod = 32;       // Rsi period

extern enPrices RsiPrice  = pr_close; // Rsi price

extern double   RsiSignal = 32;       // Signal period



double val[],valua[],valub[],valda[],valdb[],levelu[],leveld[],state[];



//------------------------------------------------------------------

//

//------------------------------------------------------------------

//

//

//

//

//



int OnInit()

{

   IndicatorBuffers(8);

      SetIndexBuffer(0,levelu);

      SetIndexBuffer(1,leveld);

      SetIndexBuffer(2,val);

      SetIndexBuffer(3,valua);

      SetIndexBuffer(4,valub);

      SetIndexBuffer(5,valda);

      SetIndexBuffer(6,valdb);

      SetIndexBuffer(7,state);

   IndicatorShortName("dsl rsi ("+(string)RsiPeriod+", dsl period : "+(string)RsiSignal+")");

   return(INIT_SUCCEEDED);

}

void OnDeinit(const int reason) { return; }



//------------------------------------------------------------------

//

//------------------------------------------------------------------

//

//

//

//

//



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 limit=MathMax(rates_total-prev_calculated-1,0);



   //

   //

   //

   //

   //



   double alpha = 2.0/(1.0+RsiSignal);

      if (state[limit]== 1) CleanPoint(limit,valua,valub);

      if (state[limit]==-1) CleanPoint(limit,valda,valdb);

      int i=limit; for(; i>=0 && !_StopFlag; i--)

      {

         val[i]    = iRsi(getPrice(RsiPrice,open,close,high,low,i,Bars),RsiPeriod,i,Bars);

         levelu[i] = (i<Bars-1) ? (val[i]>50) ? levelu[i+1]+alpha*(val[i]-levelu[i+1]) : levelu[i+1] : 50;

         leveld[i] = (i<Bars-1) ? (val[i]<50) ? leveld[i+1]+alpha*(val[i]-leveld[i+1]) : leveld[i+1] : 50;

         state[i]  = (val[i]>levelu[i]) ? 1 : (val[i]<leveld[i]) ? -1 :  0;

         valda[i]  = EMPTY_VALUE;

         valdb[i]  = EMPTY_VALUE;

         valua[i]  = EMPTY_VALUE;

         valub[i]  = EMPTY_VALUE;

            if (state[i]== 1) PlotPoint(i,valua,valub,val);

            if (state[i]==-1) PlotPoint(i,valda,valdb,val);

      }

   return(rates_total-i-1);

}



//------------------------------------------------------------------

//

//------------------------------------------------------------------

//

//

//

//

//

//



#define _rsiInstances     1

#define _rsiInstancesSize 3

double workRsi[][_rsiInstances*_rsiInstancesSize];

#define _price  0

#define _change 1

#define _changa 2



double iRsi(double price, double period, int i, int bars, int instanceNo=0)

{

   if (ArrayRange(workRsi,0)!=bars) ArrayResize(workRsi,bars);

      int z = instanceNo*_rsiInstancesSize; 

      int r = bars-i-1;

   

   //

   //

   //

   //

   //

   

   workRsi[r][z+_price] = price;

      if (r<period)

         {

            int k; double sum = 0; for (k=0; k<period && (r-k-1)>=0; k++) sum += MathAbs(workRsi[r-k][z+_price]-workRsi[r-k-1][z+_price]);

               workRsi[r][z+_change] = (workRsi[r][z+_price]-workRsi[0][z+_price])/MathMax(k,1);

               workRsi[r][z+_changa] =                                         sum/MathMax(k,1);

         }

      else

         {

            double alpha = 1.0/period; 

            double change = workRsi[r][z+_price]-workRsi[r-1][z+_price];

                            workRsi[r][z+_change] = workRsi[r-1][z+_change] + alpha*(        change  - workRsi[r-1][z+_change]);

                            workRsi[r][z+_changa] = workRsi[r-1][z+_changa] + alpha*(MathAbs(change) - workRsi[r-1][z+_changa]);

         }

         if (workRsi[r][z+_changa] != 0)

               return(50.0*(workRsi[r][z+_change]/workRsi[r][z+_changa]+1));

         else  return(50.0);

}



//------------------------------------------------------------------

//

//------------------------------------------------------------------

//

//

//

//

//

//



#define _priceInstances     1

#define _priceInstancesSize 4

double workHa[][_priceInstances*_priceInstancesSize];

double getPrice(int tprice, const double& open[], const double& close[], const double& high[], const double& low[], int i, int bars, int instanceNo=0)

{

  if (tprice>=pr_haclose)

   {

      if (ArrayRange(workHa,0)!= bars) ArrayResize(workHa,bars); instanceNo*=_priceInstancesSize; int r = bars-i-1;

         

         //

         //

         //

         //

         //

         

         double haOpen;

         if (r>0)

                haOpen  = (workHa[r-1][instanceNo+2] + workHa[r-1][instanceNo+3])/2.0;

         else   haOpen  = (open[i]+close[i])/2;

         double haClose = (open[i] + high[i] + low[i] + close[i]) / 4.0;

         double haHigh  = MathMax(high[i], MathMax(haOpen,haClose));

         double haLow   = MathMin(low[i] , MathMin(haOpen,haClose));



         if(haOpen  <haClose) { workHa[r][instanceNo+0] = haLow;  workHa[r][instanceNo+1] = haHigh; } 

         else                 { workHa[r][instanceNo+0] = haHigh; workHa[r][instanceNo+1] = haLow;  } 

                                workHa[r][instanceNo+2] = haOpen;

                                workHa[r][instanceNo+3] = haClose;

         //

         //

         //

         //

         //

         

         switch (tprice)

         {

            case pr_haclose:     return(haClose);

            case pr_haopen:      return(haOpen);

            case pr_hahigh:      return(haHigh);

            case pr_halow:       return(haLow);

            case pr_hamedian:    return((haHigh+haLow)/2.0);

            case pr_hamedianb:   return((haOpen+haClose)/2.0);

            case pr_hatypical:   return((haHigh+haLow+haClose)/3.0);

            case pr_haweighted:  return((haHigh+haLow+haClose+haClose)/4.0);

            case pr_haaverage:   return((haHigh+haLow+haClose+haOpen)/4.0);

            case pr_hatbiased:

               if (haClose>haOpen)

                     return((haHigh+haClose)/2.0);

               else  return((haLow+haClose)/2.0);        

            case pr_hatbiased2:

               if (haClose>haOpen)  return(haHigh);

               if (haClose<haOpen)  return(haLow);

                                    return(haClose);        

         }

   }

   

   //

   //

   //

   //

   //

   

   switch (tprice)

   {

      case pr_close:     return(close[i]);

      case pr_open:      return(open[i]);

      case pr_high:      return(high[i]);

      case pr_low:       return(low[i]);

      case pr_median:    return((high[i]+low[i])/2.0);

      case pr_medianb:   return((open[i]+close[i])/2.0);

      case pr_typical:   return((high[i]+low[i]+close[i])/3.0);

      case pr_weighted:  return((high[i]+low[i]+close[i]+close[i])/4.0);

      case pr_average:   return((high[i]+low[i]+close[i]+open[i])/4.0);

      case pr_tbiased:   

               if (close[i]>open[i])

                     return((high[i]+close[i])/2.0);

               else  return((low[i]+close[i])/2.0);        

      case pr_tbiased2:   

               if (close[i]>open[i]) return(high[i]);

               if (close[i]<open[i]) return(low[i]);

                                     return(close[i]);        

   }

   return(0);

}   



//-------------------------------------------------------------------

//                                                                  

//-------------------------------------------------------------------

//

//

//

//

//



void CleanPoint(int i,double& first[],double& second[])

{

   if (i>=Bars-2) return;

   if ((second[i]  != EMPTY_VALUE) && (second[i+1] != EMPTY_VALUE))

        second[i+1] = EMPTY_VALUE;

   else

      if ((first[i] != EMPTY_VALUE) && (first[i+1] != EMPTY_VALUE) && (first[i+2] == EMPTY_VALUE))

          first[i+1] = EMPTY_VALUE;

}



void PlotPoint(int i,double& first[],double& second[],double& from[])

{

   if (i>=Bars-2) return;

   if (first[i+1] == EMPTY_VALUE)

      if (first[i+2] == EMPTY_VALUE) 

            { first[i]  = from[i]; first[i+1]  = from[i+1]; second[i] = EMPTY_VALUE; }

      else  { second[i] = from[i]; second[i+1] = from[i+1]; first[i]  = EMPTY_VALUE; }

   else     { first[i]  = from[i];                          second[i] = EMPTY_VALUE; }

}

Comments