MA_Angle_v2

Download script
MA_Angle_v2

This tool is designed to help traders visualize the "slope" or momentum of a Moving Average (MA) by converting its movement into a measurable angle. Rather than just looking at the price line, this indicator focuses on how aggressively that line is tilting upward or downward, which can help identify trend strength or periods of consolidation.

How the Logic Works

1. Customizable Moving Average Selection The script allows you to choose between various types of Moving Averages (such as Simple, Exponential, Smoothed, Linear Weighted, or Least Squares). You can also specify which price data the average should be based on—for example, whether it should track the closing price, the high/low extremes, or a weighted average of all price points.

2. Angle Calculation Mechanism The core logic works by comparing two different points in time on your chosen Moving Average:

  • Current Point: The value at the present moment (or a very recent shift).
  • Previous Point: A value from a set number of bars back (determined by the "Shift" settings).

By calculating the difference between these two points and applying a scaling factor (which automatically adjusts based on the currency pair, such as Japanese Yen pairs), the script determines the "steepness" of the trend.

3. Visual Feedback System Instead of showing a simple line, the indicator uses a histogram in a separate window to categorize the market's momentum into three distinct states based on a user-defined threshold:

  • Upward Trend (Green): If the angle is positive and exceeds your chosen threshold, the histogram shows a green bar. This indicates a strong upward tilt.
  • Downward Trend (Red): If the angle is negative and falls below your negative threshold, the histogram shows a red bar. This indicates a strong downward tilt.
  • Neutral/Consolidation (Yellow): If the angle falls between your positive and negative thresholds (near zero), the histogram shows a yellow bar. This signals that the Moving Average is flattening out, suggesting a period of sideways movement or a lack of clear momentum.

Summary for the User

Essentially, this tool acts as a "momentum filter." It strips away the noise of price fluctuations to tell you one thing: Is the current trend moving with strength, or is it losing steam? By watching the color shifts between Green, Red, and Yellow, you can more easily identify when a trend is accelerating or when the market is entering a period of indecision.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
9 Views
0 Downloads
0 Favorites
MA_Angle_v2
//+------------------------------------------------------------------+
//|                                                     MA_Angle.mq4 |
//| Modified from code for EMA_Angle by jpkfox                       |
//|                                                                  |
//| You can use this indicator to measure when the MA angle is       |
//| "near zero". AngleTreshold determines when the angle for the     |
//| MA is "about zero": This is when the value is between            |
//| [-AngleTreshold, AngleTreshold] (or when the histogram is red).  |
//|   MAPeriod: MA period                                            |
//|   AngleTreshold: The angle value is "about zero" when it is      |
//|     between the values [-AngleTreshold, AngleTreshold].          |      
//|   StartMAShift: The starting point to calculate the              |   
//|     angle. This is a shift value to the left from the            |
//|     observation point. Should be StartMAShift > EndMAShift.      | 
//|   EndMAShift: The ending point to calculate the                  |
//|     angle. This is a shift value to the left from the            | 
//|     observation point. Should be StartMAShift > EndMAShift.      |
//|                                                                  |
//|   Modified by MrPip                                              |
//|       Red for down                                               |
//|       Yellow for near zero                                       |
//|       Green for up                                               |
//|  10/15/05  MrPip                                                 |
//|            Corrected problem with USDJPY and optimized code      |
//|  10/23/05  Added other JPY crosses                               |   
//|                                                                  |
//|   8/1/2006 Modified to use any MA including LSMA                 |                                                                  |
//|                                                                  |
//+------------------------------------------------------------------+

#property  copyright "MrPip and jpkfox"
//---- indicator settings
#property  indicator_separate_window
#property  indicator_buffers 3
#property  indicator_color1  LimeGreen
#property  indicator_color2  Yellow
#property  indicator_color3 FireBrick
//---- indicator parameters
extern int MAPeriod=34;
extern string  m = "--Moving Average Types--";
extern string  m0 = " 0 = SMA";
extern string  m1 = " 1 = EMA";
extern string  m2 = " 2 = SMMA";
extern string  m3 = " 3 = LWMA";
extern string  m4 = " 4 = LSMA";
extern int MA_Type = 1; //0=SMA, 1=EMA, 2=SMMA, 3=LWMA, 4=LSMA
extern string  p = "--Applied Price Types--";
extern string  p0 = " 0 = close";
extern string  p1 = " 1 = open";
extern string  p2 = " 2 = high";
extern string  p3 = " 3 = low";
extern string  p4 = " 4 = median(high+low)/2";
extern string  p5 = " 5 = typical(high+low+close)/3";
extern string  p6 = " 6 = weighted(high+low+close+close)/4";
extern int MA_AppliedPrice = 4;//0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2, 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4
extern double AngleTreshold=15;
extern int PrevMAShift=4;
extern int CurMAShift=0;

int MA_Mode;
string strMAType;

//---- indicator buffers
double UpBuffer[];
double DownBuffer[];
double ZeroBuffer[];

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
{
//---- 2 additional buffers are used for counting.
   IndicatorBuffers(3);
//---- drawing settings
   SetIndexStyle(0,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexStyle(1,DRAW_HISTOGRAM,STYLE_SOLID,2);
   SetIndexStyle(2,DRAW_HISTOGRAM,STYLE_SOLID,2);

   IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)+2);

//---- 3 indicator buffers mapping
   if(!SetIndexBuffer(0,UpBuffer) &&
      !SetIndexBuffer(1,DownBuffer) &&
      !SetIndexBuffer(2,ZeroBuffer))
      Print("cannot set indicator buffers!");
switch (MA_Type)
   {
      case 1: strMAType="EMA"; MA_Mode=MODE_EMA; break;
      case 2: strMAType="SMMA"; MA_Mode=MODE_SMMA; break;
      case 3: strMAType="LWMA"; MA_Mode=MODE_LWMA; break;
      case 4: strMAType="LSMA"; break;
      default: strMAType="SMA"; MA_Mode=MODE_SMA; break;
   }
//---- name for DataWindow and indicator subwindow label
   IndicatorShortName(strMAType+"_Angle("+MAPeriod+","+AngleTreshold+","+PrevMAShift+","+CurMAShift+")");
//---- initialization done
   return(0);
}

//+------------------------------------------------------------------+
//| LSMA with PriceMode                                              |
//| PrMode  0=close, 1=open, 2=high, 3=low, 4=median(high+low)/2,    |
//| 5=typical(high+low+close)/3, 6=weighted(high+low+close+close)/4  |
//+------------------------------------------------------------------+

double LSMA(int Rperiod, int prMode, int shift)
{
   int i;
   double sum, pr;
   int length;
   double lengthvar;
   double tmp;
   double wt;

   length = Rperiod;
 
   sum = 0;
   for(i = length; i >= 1  ; i--)
   {
     lengthvar = length + 1;
     lengthvar /= 3;
     tmp = 0;
     switch (prMode)
     {
     case 0: pr = Close[length-i+shift];break;
     case 1: pr = Open[length-i+shift];break;
     case 2: pr = High[length-i+shift];break;
     case 3: pr = Low[length-i+shift];break;
     case 4: pr = (High[length-i+shift] + Low[length-i+shift])/2;break;
     case 5: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift])/3;break;
     case 6: pr = (High[length-i+shift] + Low[length-i+shift] + Close[length-i+shift] + Close[length-i+shift])/4;break;
     }
     tmp = ( i - lengthvar)*pr;
     sum+=tmp;
    }
    wt = sum*6/(length*(length+1));
    
    return(wt);
}

//+------------------------------------------------------------------+
//| The angle for MA                                                |
//+------------------------------------------------------------------+
int start()
{
   double fCurMA, fPrevMA;
   double fAngle, mFactor, dFactor;
   int nLimit, i;
   int nCountedBars;
   double angle;
   int ShiftDif;
   string Sym;
 
   if(CurMAShift >= PrevMAShift)
   {
      Print("Error: CurMAShift >= PrevMAShift");
      PrevMAShift = 6;
      CurMAShift = 0;      
   }  
         
   nCountedBars = IndicatorCounted();
//---- check for possible errors
   if(nCountedBars<0) 
      return(-1);
//---- last counted bar will be recounted
   if(nCountedBars>0) 
      nCountedBars--;
   nLimit = Bars-nCountedBars;
   dFactor = 2*3.14159/180.0;
   mFactor = 100000.0;
   Sym = StringSubstr(Symbol(),3,3);
   if (Sym == "JPY") mFactor = 1000.0;
   ShiftDif = PrevMAShift-CurMAShift;
   mFactor /= ShiftDif; 
//---- main loop
   for(i=0; i<nLimit; i++)
   {
      if (MA_Type == 4)
      {
        fCurMA=LSMA(MAPeriod,MA_AppliedPrice, i+CurMAShift);
        fPrevMA=LSMA(MAPeriod,MA_AppliedPrice, i+PrevMAShift);
      }
      else
      {
        fCurMA=iMA(NULL,0,MAPeriod,0,MA_Mode,MA_AppliedPrice,i+CurMAShift);
        fPrevMA=iMA(NULL,0,MAPeriod,0,MA_Mode,MA_AppliedPrice,i+PrevMAShift);
      }
      // 10000.0 : Multiply by 10000 so that the fAngle is not too small
      // for the indicator Window.
      fAngle = mFactor * (fCurMA - fPrevMA)/2.0;
//      fAngle = MathArctan(fAngle)/dFactor;

      DownBuffer[i] = 0.0;
      UpBuffer[i] = 0.0;
      ZeroBuffer[i] = 0.0;
      
      if(fAngle > AngleTreshold)
      {
         UpBuffer[i] = fAngle;
      }
      else if (fAngle < -AngleTreshold)
      {
         DownBuffer[i] = fAngle;
      }
      else ZeroBuffer[i] = fAngle;
   }

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

Comments