ind_DivPeakTroughRSI_SW_v1

Download script
Author: *
ind_DivPeakTroughRSI_SW_v1

This script is designed as a visual trading tool that identifies specific price action patterns—specifically "peaks" (high points) and "troughs" (low points)—by analyzing the momentum of the market. It uses a modified version of the Relative Strength Index (RSI) to detect these turning points and highlights them on your chart with arrows and trend lines.

Here is a breakdown of how the logic works:

1. Momentum Analysis (The Foundation)

The script starts by calculating a customized momentum value based on the RSI. It centers this value around zero (a "zero line"). When the line is above zero, it suggests bullish momentum; when it is below zero, it suggests bearish momentum. This serves as the primary data source for identifying where the market might be reaching an extreme.

2. Peak and Trough Detection

The logic scans the chart to find specific "extremes." It doesn't just look for any high or low point; it looks for points that satisfy three main criteria:

  • Magnitude: The momentum must cross a certain sensitivity threshold (user-defined).
  • Structure: To be considered a "Peak," the point must be higher than the bars immediately preceding it and following it. Conversely, a "Trough" must be lower than the surrounding bars.
  • Verification: It checks these points against specific "left" and "right" bar buffers to ensure the shape of the turn is significant enough to be considered a valid market pivot.

3. Pattern Recognition (The Comparison)

Once a peak or trough is identified, the script compares the current extreme to the previous one. It looks for specific geometric relationships between the momentum values and the actual asset prices (Highs and Lows):

  • Bullish/Bearish Confirmation: It checks if the price action at the current peak/trough aligns with the direction of the momentum.
  • Trend Line Creation: If the relationship between the previous point and the current point meets specific conditions (such as a price high coinciding with a lower momentum value, or vice versa), the script confirms a signal.

4. Visual Output

The script communicates these findings to the trader through three primary visual elements:

  • Arrows: It places distinct arrows on the chart to signal when a confirmed peak or trough has been detected.
  • Trend Lines: It automatically draws trend lines connecting the current point to the previous one. These lines help visualize the "slope" of the market's momentum and price movement simultaneously.
  • Color Coding: The signals are color-coded (using various shades of Red, Pink, Green, and Yellow) to help the user quickly distinguish between different types of turning points at a glance.

Summary for the User

In simple terms, this tool filters out the "noise" of daily price movement. It waits for the market to move into an extreme state, confirms that the turn is mathematically significant compared to the previous turn, and then draws a visual map (lines and arrows) to show you where those structural shifts occurred.

Indicators Used
Relative strength index
Miscellaneous
Implements a curve of type %1
13 Views
0 Downloads
0 Favorites
ind_DivPeakTroughRSI_SW_v1
//+------------------------------------------------------------------+
//|                                     ind_DivPeakTroughOsMA_v1.mq4 |
//|                                                                * |
//|                                                                * |
//+------------------------------------------------------------------+
#property copyright "*"
#property link      "*"

#property indicator_separate_window
#property indicator_buffers 3
#property indicator_color1 Orange
#property indicator_color2 Silver
#property indicator_color3 SlateGray
#property indicator_width2 1
#property indicator_width3 1
//---- input parameters

extern int RSIPeriod=14;
extern int RSIPrice=0; // 0-Close, 1-Open, 2-High, 3-Low, 4-Median, 5-Typical, 6-Weighted
extern int ExtrLeftBars=2; // áàðîâ ñëåâà îò ýêñòðåìóìà
extern int ExtrRightBars=1; // áàðîâ ñïðàâà îò ýêñòðåìóìà
extern double PlusSens=1;
extern double MinusSens=-1;
extern bool DrawLinesSW=true;
extern bool DrawLinesChW=true;
extern color Col_Peak_1=Red;
extern color Col_Peak_2=DeepPink;
extern color Col_Trough_1=LimeGreen;
extern color Col_Trough_2=YellowGreen;
extern string ShortName="DPTRSI";

//---- buffers
double osma[];
double Sig1[];
double Sig2[];
double peack_1_i[];
double peack_2_i[];
double trogh_1_i[];
double trogh_2_i[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators

   IndicatorBuffers(7);

   SetIndexStyle(0,DRAW_LINE);
   SetIndexBuffer(0,osma);
   SetIndexStyle(1,DRAW_ARROW);
   SetIndexArrow(1,159);   
   SetIndexBuffer(1,Sig1);
   SetIndexStyle(2,DRAW_ARROW);
   SetIndexArrow(2,159);    
   SetIndexBuffer(2,Sig2);
   
   SetIndexBuffer(3,peack_1_i);
   SetIndexBuffer(4,peack_2_i);
   SetIndexBuffer(5,trogh_1_i);
   SetIndexBuffer(6,trogh_2_i);
   
   IndicatorShortName(ShortName);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   if(DrawLinesSW || DrawLinesChW)fObjDeleteByPrefix(ShortName);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start(){

         int limit=Bars-IndicatorCounted();

            for(int i=limit-1;i>=0;i--){
               osma[i]=iRSI(NULL,0,RSIPeriod,RSIPrice,i)-50;
               int extri=i+ExtrRightBars;

               Sig1[i]=EMPTY_VALUE;
               Sig2[i]=EMPTY_VALUE;                            
               
               peack_1_i[i]=peack_1_i[i+1];
               peack_2_i[i]=peack_2_i[i+1];               
               trogh_1_i[i]=trogh_1_i[i+1];
               trogh_2_i[i]=trogh_2_i[i+1];               
               
               bool PeackNow=false;
               bool TroghNow=false;
               
                  double extrv=osma[extri];
                  
                  if(extrv>PlusSens){
                     for(int j=i;j<extri;j++){
                        if(extrv<=osma[j]){
                           break;
                        }
                     }
                     if(j==extri){
                        int extril=extri+ExtrLeftBars;
                           for(j=extril;j>extri;j--){
                              if(extrv<=osma[j]){
                                 break;
                              }
                           }
                           if(j==extri){
                              PeackNow=true;
                                    if(peack_1_i[i]==EMPTY_VALUE){
                                       peack_1_i[i]=Time[extri];
                                    }
                                    else{
                                       if(osma[extri]>osma[iBarShift(NULL,0,peack_1_i[i],false)]){
                                          peack_1_i[i]=Time[extri];
                                       }
                                    }
                           }
                     }
                  }
                  if(extrv<MinusSens){                  
                     for(j=i;j<extri;j++){
                        if(extrv>=osma[j]){
                           break;
                        }
                     }
                     if(j==extri){
                        extril=extri+ExtrLeftBars;
                           for(j=extril;j>extri;j--){
                              if(extrv>=osma[j]){
                                 break;
                              }
                           }
                           if(j==extri){
                              TroghNow=true;
                                    if(trogh_1_i[i]==EMPTY_VALUE){
                                       trogh_1_i[i]=Time[extri];
                                    }
                                    else{
                                       if(osma[extri]<osma[iBarShift(NULL,0,trogh_1_i[i],false)]){
                                          trogh_1_i[i]=Time[extri];
                                       }
                                    }                              
                           }
                     }                  
                  }  
                  
                  if(osma[i]>0 && osma[i+1]<=0){
                     peack_2_i[i]=peack_1_i[i];
                     peack_1_i[i]=EMPTY_VALUE;
                  }                    
                  
                  if(osma[i]<0 && osma[i+1]>=0){
                     trogh_2_i[i]=trogh_1_i[i];
                     trogh_1_i[i]=EMPTY_VALUE;                  
                  }
                  
               string ObjName1=ShortName+"_PeakIW_"+Time[extri];
               string ObjName2=ShortName+"_PeakPW_"+Time[extri];
               ObjectDelete(ObjName1);   
               ObjectDelete(ObjName2);    
                               
                  if(PeackNow){
                     if(peack_1_i[i]!=EMPTY_VALUE){
                        if(peack_2_i[i]!=EMPTY_VALUE){
                           if(osma[extri]>=osma[iBarShift(NULL,0,peack_1_i[i],false)]){ 
                              int z2=iBarShift(NULL,0,peack_2_i[i],false);
                              int z1=extri;
                                 if(osma[z2]<osma[z1] && High[z2]>High[z1]){
                                    Sig1[i]=osma[i]+Point/4;
                                       if(DrawLinesSW)fObjTrendLine(ObjName1,peack_2_i[i],osma[z2],Time[extri],osma[z1],false,Col_Peak_1,1,WindowFind(ShortName),0,true);
                                       if(DrawLinesChW)fObjTrendLine(ObjName2,peack_2_i[i],High[z2],Time[extri],High[z1],false,Col_Peak_1,1,0,0,false);
                                   }
                                 if(osma[z2]>osma[z1] && High[z2]<High[z1]){
                                    Sig2[i]=osma[i]+Point/4;
                                       if(DrawLinesSW)fObjTrendLine(ObjName1,peack_2_i[i],osma[z2],Time[extri],osma[z1],false,Col_Peak_2,1,WindowFind(ShortName),0,true);
                                       if(DrawLinesChW)fObjTrendLine(ObjName2,peack_2_i[i],High[z2],Time[extri],High[z1],false,Col_Peak_2,1,0,0,false);
                                 }                                                
                           }
                        }
                     }
                  }
                  

               ObjName1=ShortName+"_TroghIW_"+Time[extri];
               ObjName2=ShortName+"_TroghPW_"+Time[extri];
               ObjectDelete(ObjName1);   
               ObjectDelete(ObjName2);    
                               
                  if(TroghNow){
                     if(trogh_1_i[i]!=EMPTY_VALUE){
                        if(trogh_2_i[i]!=EMPTY_VALUE){
                           if(osma[extri]<=osma[iBarShift(NULL,0,trogh_1_i[i],false)]){ 
                              z2=iBarShift(NULL,0,trogh_2_i[i],false);
                              z1=extri;
                                 if(osma[z2]>osma[z1] && Low[z2]<Low[z1]){
                                    Sig1[i]=osma[i]-Point/4;
                                       if(DrawLinesSW)fObjTrendLine(ObjName1,trogh_2_i[i],osma[z2],Time[extri],osma[z1],false,Col_Trough_1,1,WindowFind(ShortName),0,true);
                                       if(DrawLinesChW)fObjTrendLine(ObjName2,trogh_2_i[i],Low[z2],Time[extri],Low[z1],false,Col_Trough_1,1,0,0,false);
                                 }
                                 if(osma[z2]<osma[z1] && Low[z2]>Low[z1]){
                                    Sig2[i]=osma[i]-Point/4;
                                       if(DrawLinesSW)fObjTrendLine(ObjName1,trogh_2_i[i],osma[z2],Time[extri],osma[z1],false,Col_Trough_2,1,WindowFind(ShortName),0,true);
                                       if(DrawLinesChW)fObjTrendLine(ObjName2,trogh_2_i[i],Low[z2],Time[extri],Low[z1],false,Col_Trough_2,1,0,0,false);
                                 }                                                
                           }
                        }
                     }
                  }                  
                  
                                 
                       
            }

      
   return(0);
  }
//+------------------------------------------------------------------+

void fObjTrendLine(
   string aObjectName,  // 1 èìÿ
   datetime aTime_1,    // 2 âðåìÿ 1
   double aPrice_1,     // 3 öåíà 1
   datetime aTime_2,    // 4 âðåìÿ 2
   double aPrice_2,     // 5 öåíà 2
   bool aRay=false,     // 6 ëó÷
   color aColor=Red,    // 7 öâåò
   int aWidth=1,        // 8 òîëùèíà
   int aWindowNumber=0, // 9 îêíî
   int aStyle=0,        // 10 0-STYLE_SOLID, 1-STYLE_DASH, 2-STYLE_DOT, 3-STYLE_DASHDOT, 4-STYLE_DASHDOTDOT
   bool aBack=false     // 11 ôîí
   ){
      if(ObjectFind(aObjectName)!=aWindowNumber){
         ObjectCreate(aObjectName,OBJ_TREND,aWindowNumber,aTime_1,aPrice_1,aTime_2,aPrice_2);
      }      
   ObjectSet(aObjectName,OBJPROP_TIME1,aTime_1);
   ObjectSet(aObjectName,OBJPROP_PRICE1,aPrice_1);   
   ObjectSet(aObjectName,OBJPROP_TIME2,aTime_2);       
   ObjectSet(aObjectName,OBJPROP_PRICE2,aPrice_2); 
   ObjectSet(aObjectName,OBJPROP_RAY,aRay);     
   ObjectSet(aObjectName,OBJPROP_COLOR,aColor);
   ObjectSet(aObjectName,OBJPROP_WIDTH,aWidth);
   ObjectSet(aObjectName,OBJPROP_BACK,aBack);
   ObjectSet(aObjectName,OBJPROP_STYLE,aStyle);                
}

void fObjDeleteByPrefix(string aPrefix){
   
   //fObjDeleteByPrefix("");
   
   for(int i=ObjectsTotal()-1;i>=0;i--){
      if(StringFind(ObjectName(i),aPrefix,0)==0){
         ObjectDelete(ObjectName(i));
      }
   }
}

Comments