ind_DivPeakTroughOsMA_SW_v1

Download script
Author: *
ind_DivPeakTroughOsMA_SW_v1

This indicator is designed to analyze market momentum and identify significant structural turning points (peaks and troughs) based on the Awesome Oscillator (OsMA). It helps traders visualize when price momentum is reaching an extreme and whether those moves are breaking previous trends.

Core Logic Overview

The tool operates by tracking the Awesome Oscillator, which is a momentum-based indicator that measures the difference between two moving averages. Instead of just looking at current price, it looks for specific "extremes" in this momentum data to identify potential reversals.

Key Functional Components

1. Peak and Trough Detection The script continuously scans the momentum data to find local highs (peaks) and lows (troughs). For a point to be considered a valid peak or trough, it must meet three criteria:

  • Threshold: The momentum value must cross a specific sensitivity level (defined in the settings as positive for peaks and negative for troughs).
  • Structural Shape: The point must be higher than its immediate neighbors on the left and right (for peaks) or lower than its neighbors (for troughs).
  • Significant Extremes: The script keeps track of the "Highest Peak" and "Lowest Trough" relative to previous trends to ensure it only highlights significant movements rather than minor price "noise."

2. Trend Breakout Analysis The logic goes beyond simply marking highs and lows; it compares new peaks and troughs against historical ones. When a new extreme is identified, the script checks:

  • If a new peak is higher (or lower) than the previous significant peak/trough.
  • If the actual price of the asset (the High or Low) has also moved in that same direction.

3. Visual Signaling When these specific conditions are met—where a momentum peak/trough occurs and confirms a shift in structural strength—the indicator provides visual cues:

  • Arrows: It places arrows on the chart to signal a potential trend change or breakout.
  • Trend Lines: Based on the settings, it automatically draws trend lines connecting the previous extreme to the current extreme. These lines serve as a visual bridge, helping the trader see the "path" of the momentum shift and the expansion of price movement.

Summary for the User

Essentially, this tool filters out minor market fluctuations to highlight major structural shifts. It tells you: "The momentum has reached an extreme point, and because it is higher/lower than the previous significant point, a trend transition or significant breakout may be occurring."

Indicators Used
Moving Average of Oscillator
Miscellaneous
Implements a curve of type %1
17 Views
0 Downloads
0 Favorites
ind_DivPeakTroughOsMA_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 OsMAFastPeriod=12;
extern int OsMASlowPeriod=26;
extern int OsMASignalPeriod=9;
extern int OsMAPrice=0;
extern int ExtrLeftBars=2; // áàðîâ ñëåâà îò ýêñòðåìóìà
extern int ExtrRightBars=1; // áàðîâ ñïðàâà îò ýêñòðåìóìà
extern double PlusSens=0.0001;
extern double MinusSens=-0.0001;
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="DPTOsMA";

//---- 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]=iOsMA(NULL,0,OsMAFastPeriod,OsMASlowPeriod,OsMASignalPeriod,OsMAPrice,i);
               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