ATM_maHPF

Technical Overview: XP Moving Average (xpMA)

The XP Moving Average is a versatile technical analysis tool designed to help traders identify trends and potential entry points in financial markets. Unlike a standard moving average that simply averages price over time, this script provides an advanced framework that supports multiple calculation methods, customizable visual signals, and automated notifications.

Core Functionality

At its heart, the script calculates a "moving average"—a smoothed line that follows price action. However, it distinguishes itself by offering a wide variety of mathematical models to choose from. Depending on your preference, it can perform standard calculations (like Simple or Exponential Moving Averages) or utilize more complex, specialized algorithms such as the Hull Moving Average (HMA), Jurik Moving Average (JMA), or Triple Exponential Moving Average (TEMA).

Key Features and Logic

1. Versatile Calculation Modes The script allows users to switch between different "engines" to determine how the average is calculated. This enables traders to choose between models that are more responsive to sudden price changes or those that provide a smoother, less "noisy" representation of the trend.

2. Dynamic Signal Detection (Up/Down Buffers) One of the primary features of this script is its ability to generate visual signals. It compares the current moving average value against a short-term average of recent data.

  • Buy/Up Signals: These occur when the current value crosses above the local average, indicating potential upward momentum.
  • Sell/Down Signals: These occur when the current value falls below the local average, indicating potential downward momentum.

3. Visual Aids and Alerts To ensure traders do not miss key movements, the script includes several notification layers:

  • On-Chart Arrows: The script can automatically place arrows on the chart to highlight exactly where an "Up" or "Down" signal has been triggered.
  • Real-Time Alerts: It can trigger a pop-up alert on your trading platform when a signal occurs.
  • Email Notifications: For traders who are away from their screens, the script can be configured to send an email notification directly to a connected account.

4. Precision Customization The logic includes several "fine-tuning" options:

  • Vertical Shift: Allows you to move the average line up or down on the chart visually without changing the underlying math.
  • Timeframe Awareness: The script automatically adjusts its behavior (such as the distance of signals) based on the specific timeframe you are viewing (e.g., 1-minute charts vs. Daily charts).
  • Applied Price Selection: You can choose which price data the average follows, such as the high, low, close, or even a weighted average of the price action.

Summary for the User

In simple terms, this script acts as a sophisticated "trend tracker." It looks at the market's history using your preferred mathematical formula and draws a line representing the current trend. When that line moves significantly enough to suggest a change in direction, the script alerts you via arrows, pop-up messages, or emails, helping you identify potential trading opportunities more efficiently.

Indicators Used
Moving average indicatorMoving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emails
10 Views
0 Downloads
0 Favorites
ATM_maHPF
//Version: 9
//Updated: December 22, 2006. Modifyed by Accrete on January 2nd 2007
//and renamed ATM_xpMAvs   "vs" stands for "Vertical Shift"
//+------------------------------------------------------------------+
//|                       XP Moving Average                          | 
//|                          xpMA.mq4                                |
//|                    Developed by Coders Guru                      |
//|                     http://www.xpworx.com                        |
//|                                                                  |
//| Many thanks to Coders Guru for his MT4 Tutorials and his helpful |
//| assistance. Accrete added "vertical shift" option and matched    |
//| arrow and line buffer colors set by user. more doodles at :      |
//| www.twotrilliondollarsdaily.com and www.accrete.com   Enjoy !!   |
//+------------------------------------------------------------------+
#property link      "http://www.xpworx.com"


#property indicator_chart_window
#property indicator_buffers 4
#property indicator_color1 Yellow
#property indicator_color2 Yellow
#property indicator_color3 Blue

#define MODE_DEMA    4
#define MODE_TEMA    5
#define MODE_T3MA    6
#define MODE_JMA     7
#define MODE_HMA     8
#define MODE_DECEMA  9
#define MODE_SALT    10

/* Moving average types constants:
------------------------------------
MODE_SMA       0     Simple moving average, 
MODE_EMA       1     Exponential moving average, 
MODE_SMMA      2     Smoothed moving average, 
MODE_LWMA      3     Linear weighted moving average.
MODE_DEMA      4     Double Exponential Moving Average. 
MODE_TEMA      5     Triple Exponential Moving Average.
MODE_T3MA      6     T3 Moving Average. 
MODE_JMA       7     Jurik Moving Average. 
MODE_HMA       8     Hull Moving Average. 
MODE_DECEMA    9     DECEMA Moving Average. 
MODE_SALT      10    SALT Indicator. 

------------------------------------*/

/* Applied price constants:
-------------------------------
PRICE_CLOSE    0     Close price. 
PRICE_OPEN     1     Open price. 
PRICE_HIGH     2     High price. 
PRICE_LOW      3     Low price. 
PRICE_MEDIAN   4     Median price, (high+low)/2. 
PRICE_TYPICAL  5     Typical price, (high+low+close)/3. 
PRICE_WEIGHTED 6     Weighted close price, (high+low+close+close)/4.
--------------------------------- */


extern   int      TimeFrame               = 0;
extern   int      MA_Period               = 21;
extern   int      MA_Type                 = MODE_SMA;
extern   int      MA_Applied              = PRICE_HIGH;
extern   double   T3MA_VolumeFactor       = 0.8;
extern   double   JMA_Phase               = 0;
extern   int      Step_Period             = 4;
extern   int      Vertical_Shift          = 0;// added by accrete

extern   bool     DebugMode               = false;

bool     Alert_On                = false;
bool     Arrows_On               = false;
int      UpArrowCode             = 241;
int      DownArrowCode           = 242;
color    UpArrowColor            = indicator_color3;//was Red
color    DownArrowColor          = indicator_color2;//was Blue
int      UpArrowSize             = 3;
int      DownArrowSize           = 3;
bool     Email_Alert             = false;
string   pro  = "";//was xpMA_v9
string   ver  = "";


double UpBuffer[];
double DownBuffer[];
double Buffer3[];
double buffer[];
double tempbuffer[];
double matriple[];
double signal[];

int    nShift;   

int init()
{
   DeleteStamp();
   ver = GenVer();
   DeleteAllObjects();
   IndicatorBuffers(7); 

   SetIndexStyle(2,DRAW_LINE,STYLE_SOLID,1);
   SetIndexBuffer(2,UpBuffer);
   SetIndexStyle(1,DRAW_LINE,STYLE_SOLID,1);
   SetIndexBuffer(1,DownBuffer);
   SetIndexStyle(0,DRAW_LINE,STYLE_SOLID,1);
   SetIndexBuffer(0,Buffer3);
   
   SetIndexBuffer(3,signal);
   SetIndexBuffer(4,buffer);
   SetIndexBuffer(5,tempbuffer);
   SetIndexBuffer(6,matriple);
   
   SetIndexLabel(0,"XP Moving Average");
   SetIndexLabel(1,"DownBuffer");
   SetIndexLabel(2,"UpBuffer");
   SetIndexLabel(3,"Signal");
   
    switch(Period())
      {
        case     1: nShift = 5;   break;    
        case     5: nShift = 7;   break; 
        case    15: nShift = 10;   break; 
        case    30: nShift = 15;  break; 
        case    60: nShift = 20;  break; 
        case   240: nShift = 30;  break; 
        case  1440: nShift = 80;  break; 
        case 10080: nShift = 150; break; 
        case 43200: nShift = 250; break;               
      }
 
   return(0);
}

int deinit()
{
   DeleteStamp();
   DeleteAllObjects();
   return(0);
}



void start()
{
   
   StampVersion(pro,ver,5,20);
   
   int limit;
   int i = 0;
   
   int counted_bars=IndicatorCounted();
   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
   limit=Bars-counted_bars;
   
   switch (MA_Type)
   {
      case 0:
      case 1:
      case 2:
      case 3:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iMA(NULL,TimeFrame,MA_Period,0,MA_Type,MA_Applied,i)+Vertical_Shift*Point;
// "+Vertical_Shift*Point" added by accrete
                  }
            }
            break;
      
      case 4:
            {
                  for(i=0; i<limit; i++)
                  {
                     tempbuffer[i] = iMA(NULL,TimeFrame,MA_Period,0,MODE_EMA,MA_Applied,i)+Vertical_Shift*Point;
                  }
                  for(i=0; i<limit; i++)
                  {
                     matriple[i] = iMAOnArray(tempbuffer,0,MA_Period,0,MODE_EMA,i)+Vertical_Shift*Point;
                  }
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iMAOnArray(matriple,0,MA_Period,0,MODE_EMA,i)+Vertical_Shift*Point;
                  }
            }
            break;
      
      case 5:
            {
                  for(i=0; i<limit; i++)
                  {
                     tempbuffer[i] = iMA(NULL,TimeFrame,MA_Period,0,MODE_EMA,MA_Applied,i)+Vertical_Shift*Point;
                  }
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iMAOnArray(tempbuffer,0,MA_Period,0,MODE_EMA,i)+Vertical_Shift*Point;
                  }
            }
            break;
      
      case 6:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,TimeFrame,"T3MA",MA_Period,T3MA_VolumeFactor,0,i)+Vertical_Shift*Point;
                  }
            }
            break;
      case 7:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,TimeFrame,"JMA",MA_Period,JMA_Phase,0,i)+Vertical_Shift*Point;
                  }
            }
            break;
      
      case 8:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,TimeFrame,"HMA",MA_Period,0,i)+Vertical_Shift*Point;
                  }
            }
            break;
      
      case 9:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,TimeFrame,"DECEMA_v1",MA_Period,MA_Applied,0,i)+Vertical_Shift*Point;
                  }
            }
            break;

      case 10:
            {
                  for(i=0; i<limit; i++)
                  {
                     buffer[i] = iCustom(NULL,TimeFrame,"SATL",0,i)+Vertical_Shift*Point;
                  }
            }
            break;
            
   }

   for(int shift=0; shift<limit; shift++)
   {
       UpBuffer[shift] = buffer[shift];
       DownBuffer[shift] = buffer[shift];
       Buffer3[shift] = buffer[shift];
   }                   
   
   /*for(shift=0; shift<limit; shift++)
   {
      if (buffer[shift]<buffer[shift+1])
      {
         UpBuffer[shift] = EMPTY_VALUE;
      }
      else if (buffer[shift]>buffer[shift+1] )
      {
         DownBuffer[shift] = EMPTY_VALUE;
      } 
     else
      {
         UpBuffer[shift] = CLR_NONE;
         DownBuffer[shift] = CLR_NONE;
      }
   }*/
   
   for(shift=0; shift<limit; shift++)
   {
      double dMA = 0;
      for(int k = shift+1; k <= shift+Step_Period; k++){
         dMA += buffer[k];
      }
      dMA = dMA / Step_Period;

      if (buffer[shift] < dMA)
      {
         UpBuffer[shift] = EMPTY_VALUE;
      }
      else if (buffer[shift]>dMA)
      {
         DownBuffer[shift] = EMPTY_VALUE;
      } 
      else
      {
         UpBuffer[shift] = EMPTY_VALUE;
         DownBuffer[shift] = EMPTY_VALUE;
      }
   }
   for(shift=0; shift<limit; shift++)
   {
         signal[shift]=0;
         if(UpBuffer[shift+1] == EMPTY_VALUE &&  UpBuffer[shift] != EMPTY_VALUE && Buffer3[shift+1] != UpBuffer[shift] )
            {
               if(Arrows_On && shift !=0) DrawObject(1,shift, buffer[shift] - nShift*Point);
               if(Arrows_On && shift ==0) DrawOnce(1,shift, buffer[shift] - nShift*Point,1);
               signal[shift] = 1;
            }
            
         if(DownBuffer[shift+1] == EMPTY_VALUE &&  DownBuffer[shift] != EMPTY_VALUE && Buffer3[shift+1] != DownBuffer[shift])
           {
               if(Arrows_On && shift !=0) DrawObject(2,shift, buffer[shift] + nShift*Point);
               if(Arrows_On && shift ==0) DrawOnce(2,shift, buffer[shift] + nShift*Point,2);
               signal[shift] = -1;
           }
   } 
   
   if(Alert_On)
   {                  
      if(UpBuffer[1] == EMPTY_VALUE &&  UpBuffer[0] != EMPTY_VALUE && Buffer3[1] != UpBuffer[0])
         AlertOnce(Symbol()+ ":" + PeriodToText() + "  -  Up Signal",1);
      if(DownBuffer[1] == EMPTY_VALUE &&  DownBuffer[0] != EMPTY_VALUE && Buffer3[1] != DownBuffer[0])   
         AlertOnce(Symbol()+ ":" + PeriodToText() + "  -  Down Signal",2);
   }
   
   if(Email_Alert)
   {                  
      if(UpBuffer[1] == EMPTY_VALUE &&  UpBuffer[0] != EMPTY_VALUE && Buffer3[1] != UpBuffer[0])
         SendMailOnce("xpMA Signal",Symbol()+ ":" + PeriodToText() + "  -  Up Signal",1);
      if(DownBuffer[1] == EMPTY_VALUE &&  DownBuffer[0] != EMPTY_VALUE && Buffer3[1] != DownBuffer[0])   
         SendMailOnce("xpMA Signal",Symbol()+ ":" + PeriodToText() + "  -  Down Signal",2);
   }

   
   if(DebugMode)
   { 
      TakeScreenShot(40);
   }

   return(0);
}

bool DrawOnce(int direction, int bar , double price, int ref)
{  
   static int LastDraw_1 = 0;
   static int LastDraw_2 = 0;
   static int LastDraw_3 = 0;
   static int LastDraw_4 = 0;
   
   switch(ref)
   {
      case 1:
         if( LastDraw_1 == 0 || LastDraw_1 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_1 = Bars;
            return (1);
         }
      break;
      case 2:
         if( LastDraw_2 == 0 || LastDraw_2 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_2 = Bars;
            return (1);
         }
      break;
      case 3:
         if( LastDraw_3 == 0 || LastDraw_3 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_3 = Bars;
            return (1);
         }
      break;
      case 4:
         if( LastDraw_4 == 0 || LastDraw_4 < Bars )
         {
            DrawObject(direction, bar , price);
            LastDraw_4 = Bars;
            return (1);
         }
      break;
   }
}

void DrawObject(int direction, int bar , double price)
{

   static int count = 0;
   count++;
   string Obj = "";
   if (direction==1) //up arrow
   {
      Obj = "xpMA_up_" + DoubleToStr(count,0);
      ObjectCreate(Obj,OBJ_ARROW,0,Time[bar],price);
      ObjectSet(Obj,OBJPROP_COLOR,UpArrowColor);
      ObjectSet(Obj,OBJPROP_ARROWCODE,UpArrowCode);
      ObjectSet(Obj,OBJPROP_WIDTH,DownArrowSize);
   }
   if (direction==2) //down arrow
   {
      Obj = "xpMA_down_" + DoubleToStr(count,0);
      ObjectCreate(Obj,OBJ_ARROW,0,Time[bar],price);
      ObjectSet(Obj,OBJPROP_COLOR,DownArrowColor);
      ObjectSet(Obj,OBJPROP_ARROWCODE,DownArrowCode);
      ObjectSet(Obj,OBJPROP_WIDTH,DownArrowSize);
   }
   ObjectsRedraw();
}

void DeleteAllObjects()
{
   int objs = ObjectsTotal();
   string name;
   for(int cnt=ObjectsTotal()-1;cnt>=0;cnt--)
   {
      name=ObjectName(cnt);
      if (StringFind(name,"xpMA",0)>-1) ObjectDelete(name);
      ObjectsRedraw();
   }
}

bool AlertOnce(string alert_msg, int ref)
{  
   static int LastAlert_1 = 0;
   static int LastAlert_2 = 0;
   static int LastAlert_3 = 0;
   static int LastAlert_4 = 0;
   
   switch(ref)
   {
      case 1:
         if( LastAlert_1 == 0 || LastAlert_1 < Bars )
         {
            Alert(alert_msg);
            LastAlert_1 = Bars;
            return (1);
         }
      break;
      case 2:
         if( LastAlert_2 == 0 || LastAlert_2 < Bars )
         {
            Alert(alert_msg);
            LastAlert_2 = Bars;
            return (1);
         }
      break;
      case 3:
         if( LastAlert_3 == 0 || LastAlert_3 < Bars )
         {
            Alert(alert_msg);
            LastAlert_3 = Bars;
            return (1);
         }
      break;
      case 4:
         if( LastAlert_4 == 0 || LastAlert_4 < Bars )
         {
            Alert(alert_msg);
            LastAlert_4 = Bars;
            return (1);
         }
      break;
   }
}

bool SendMailOnce(string subject, string mail_msg, int ref)
{  
   static int LastMail_1 = 0;
   static int LastMail_2 = 0;
   static int LastMail_3 = 0;
   static int LastMail_4 = 0;
   
   switch(ref)
   {
      case 1:
         if( LastMail_1 == 0 || LastMail_1 < Bars )
         {
            SendMail(subject,mail_msg);
            LastMail_1 = Bars;
            return (1);
         }
      break;
      case 2:
         if( LastMail_2 == 0 || LastMail_2 < Bars )
         {
            SendMail(subject,mail_msg);
            LastMail_2 = Bars;
            return (1);
         }
      break;
      case 3:
         if( LastMail_3 == 0 || LastMail_3 < Bars )
         {
            SendMail(subject,mail_msg);
            LastMail_3 = Bars;
            return (1);
         }
      break;
      case 4:
         if( LastMail_4 == 0 || LastMail_4 < Bars )
         {
            SendMail(subject,mail_msg);
            LastMail_4 = Bars;
            return (1);
         }
      break;
   }
}

void TakeScreenShot(int exit_on = -1)
{
   int count = 1;
   
   if(!GlobalVariableCheck("ssc"))
   {
    GlobalVariableSet("ssc",1);
    count = 1;
   }
   else
   {
      count = GlobalVariableGet("ssc") + 1;
      GlobalVariableSet("ssc",count); 
   }
   
   if ( exit_on > 0 && count > exit_on ) return(0);
   
   string filename = "xpMA\\" + "xpMA_" + Symbol() +  "_" + DoubleToStr(count,0) + ".jpg";
   ScreenShot(filename,320,480);
}
string PeriodToText()
{
   switch (Period())
   {
      case 1:
            return("M1");
            break;
      case 5:
            return("M5");
            break;
      case 15:
            return("M15");
            break;
      case 30:
            return("M30");
            break;
      case 60:
            return("H1");
            break;
      case 240:
            return("H4");
            break;
      case 1440:
            return("D1");
            break;
      case 10080:
            return("W1");
            break;
      case 43200:
            return("MN1");
            break;
   }
}

void StampVersion(string pro , string ver , int x , int y)
{
   string Obj="Stamp_" + pro;
   int objs = ObjectsTotal();
   string name;
  
   for(int cnt=0;cnt<ObjectsTotal();cnt++)
   {
      name=ObjectName(cnt);
      if (StringFind(name,Obj,0)>-1) 
      {
         ObjectSet(Obj,OBJPROP_XDISTANCE,x);
         ObjectSet(Obj,OBJPROP_YDISTANCE,y);
         ObjectsRedraw();
      }
      else
      {
         ObjectCreate(Obj,OBJ_LABEL,0,0,0);
         ObjectSetText(Obj,pro + " - " + ver,8,"arial",Aqua);
         ObjectSet(Obj,OBJPROP_XDISTANCE,x);
         ObjectSet(Obj,OBJPROP_YDISTANCE,y);
         ObjectsRedraw();
      }
   }
   if (ObjectsTotal() == 0)
   {
         ObjectCreate(Obj,OBJ_LABEL,0,0,0);
         ObjectSetText(Obj,pro + " " + ver,8,"arial",Aqua);
         ObjectSet(Obj,OBJPROP_XDISTANCE,x);
         ObjectSet(Obj,OBJPROP_YDISTANCE,y);
         ObjectsRedraw();

   }
   
   return(0);
}
void DeleteStamp()
{
   int objs = ObjectsTotal();
   string name;
   for(int cnt=ObjectsTotal()-1;cnt>=0;cnt--)
   {
      name=ObjectName(cnt);
      if (StringFind(name,"Stamp",0)>-1) ObjectDelete(name);
      ObjectsRedraw();
   }
}

string GenVer()
{
/*
   string t1;
   if(MA_Type==0) t1="SMA"; 
   if(MA_Type==1) t1="EMA"; 
   if(MA_Type==2) t1="SMMA"; 
   if(MA_Type==3) t1="LWMA"; 
   if(MA_Type==4) t1="DEMA"; 
   if(MA_Type==5) t1="TEMA"; 
   if(MA_Type==6) t1="T3MA"; 
   if(MA_Type==7) t1="JMA"; 
   if(MA_Type==8) t1="HMA";
   if(MA_Type==9) t1="DECEMA";
   if(MA_Type==10) t1="SALT";
   
   return (t1+"("+MA_Period+")"); 
   */
}








Comments