ma_2MACross_shift_SigAlert_mtf

Author: mladen
ma_2MACross_shift_SigAlert_mtf

This script is designed for traders who use Moving Averages (MA) to identify trends and entry points in the financial markets. Its primary function is to detect "crossovers"—the specific moment when a faster-moving average line intersects with a slower-moving average line—and provide visual and auditory notifications when these events occur.

Core Logic & Functionality

1. Moving Average Calculations The script tracks two distinct Moving Averages:

  • Faster MA: Reacts quickly to recent price changes.
  • Slower MA: Provides a broader view of the trend by smoothing out short-term noise. Users can customize the period (how many bars back to calculate), the "mode" (different mathematical ways to calculate the average), and the "shift" (moving the line forward or backward on the chart).

2. Multi-Timeframe Analysis A key feature of this script is its ability to look at different timeframes simultaneously. It can be configured to analyze trends on higher timeframes (like Hourly or Daily) while you are viewing a lower timeframe (like 5-minute charts). This helps traders ensure that a trade aligns with the broader market direction.

3. Crossover Detection and Visualization The script constantly monitors the relationship between the two averages. When it detects a crossover:

  • Visual Markers: It places specific symbols (arrows) on the chart at the exact point of intersection.
  • Dynamic Positioning: To ensure these markers are clearly visible and not buried under the price candles, the script calculates a "Range" based on recent price volatility and offsets the arrows slightly above or below the crossover point.

4. Alert System To prevent traders from having to stare at the screen constantly, the script includes an automated notification system. When a crossover occurs, it can:

  • Trigger a Pop-up Alert message on your platform.
  • Play a Sound file to grab your attention.
  • Send an Email notification (optional).

The logic is designed to be "smart" enough to ensure you only receive one alert per crossover, preventing your screen from being flooded with repeated notifications for the same event.

Summary of User Controls

  • MA Settings: Choose between different calculation styles (SMA, EMA, SSMA, LWMA) and adjust lengths.
  • Visuals: Toggle whether the moving average lines themselves are visible on your chart or if you only want to see the crossover arrows.
  • Notifications: Customize how you want to be notified (Sound, Pop-up, or Email).
  • Timeframe: Select which specific timeframe the indicator should "watch" for crossovers.
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It issuies visual alerts to the screenIt sends emailsIt plays sound alerts
13 Views
0 Downloads
0 Favorites
ma_2MACross_shift_SigAlert_mtf
//+--------------------------------------------------------------------------+
//|                                                3 MA Cross with alert.mq4 |
//|                                                                   mladen |
//+--------------------------------------------------------------------------+
//mod2009fxtsd 2macross shift etc
#property copyright "mladen"
#property link      "mladenfx@gmail.com"

#property indicator_chart_window
#property indicator_buffers 8
#property indicator_color1 SkyBlue
#property indicator_color2 DarkOrange
#property indicator_color3 DodgerBlue
#property indicator_color4 Red
#property indicator_color5 Lime
#property indicator_color6 Green
#property indicator_color7 Lime
#property indicator_color8 YellowGreen
#property indicator_width1 0
#property indicator_width2 0
#property indicator_width3 1
#property indicator_width4 1

//
//
//
//
//

extern int    FasterMA         =    5;
extern int    FasterShift      =    0;
extern string _fmode           = "Fast mamode0=SMA,1=EMA,2=SSMA,3=LWMA";
extern int    FasterMode       =    1;
//extern int MediumMA          =   21;
//extern int MediumShift       =    0;
//extern int MediumMode        =    1;
extern int    SlowerMA         =   11;
extern int    SlowerShift      =    0;
extern string _smode           = "Slow mamode0=SMA,1=EMA,2=SSMA,3=LWMA";
extern int    SlowerMode       =    0;
extern bool   showMAs          = true;
extern bool   crossesOnCurrent = true;
extern bool   alertsOn         = true;
extern bool   alertsMessage    = true;
extern bool   alertsSound      = true;
extern bool   alertsEmail      = false;
extern int    TimeFrame        = 0;
extern string note_TimeFrames_ = "M1;5,15,30,60H1;240H4;1440D1;10080W1;43200MN|0-currentTF";


//
//
//
//
//

double CrossUp[];
double CrossDown[];
double CrossWUp[];
double CrossWDown[];
double ma1[];
double ma2[];
double ma1s[];
double ma2s[];


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int init()
{
   if(FasterShift||SlowerShift!=0)  {
   SetIndexBuffer(0, CrossUp);    SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, 233);
   SetIndexBuffer(1, CrossDown);  SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, 234);
                                    }
   SetIndexBuffer(2, CrossWUp);   SetIndexStyle(2, DRAW_ARROW); SetIndexArrow(2, 241);
   SetIndexBuffer(3, CrossWDown); SetIndexStyle(3, DRAW_ARROW); SetIndexArrow(3, 242);
   SetIndexBuffer(4,ma1);
   SetIndexBuffer(5,ma2);
   SetIndexBuffer(6,ma1s);
   SetIndexBuffer(7,ma2s);
   SetIndexShift(6,FasterShift);
   SetIndexShift(7,SlowerShift);
   if (showMAs)
   {
      SetIndexStyle(4,DRAW_NONE);
      SetIndexStyle(5,DRAW_NONE);
      SetIndexStyle(6,DRAW_LINE);
      SetIndexStyle(7,DRAW_LINE);
      SetIndexEmptyValue(4,0.00);
      SetIndexEmptyValue(5,0.00);
      SetIndexEmptyValue(6,0.00);
      SetIndexEmptyValue(7,0.00);
   }      
   else
   {
      SetIndexStyle(4,DRAW_NONE);
      SetIndexStyle(5,DRAW_NONE);
      SetIndexStyle(6,DRAW_NONE);
      SetIndexStyle(7,DRAW_NONE);
   }      

   SetIndexLabel(0,"maCrossUp");
   SetIndexLabel(1,"maCrossDn");
   SetIndexLabel(2,"BarTimeOfCrossUp");
   SetIndexLabel(3,"BarTimeOfCrossDn");
   
   switch(TimeFrame)
   {
   case 1: string TimeFrameStr = "M1" ;  break;
   case 5     :   TimeFrameStr = "M5" ;  break;
   case 15    :   TimeFrameStr = "M15";  break;
   case 30    :   TimeFrameStr = "M30";  break;
   case 60    :   TimeFrameStr = "H1" ;  break;
   case 240   :   TimeFrameStr = "H4" ;  break;
   case 1440  :   TimeFrameStr = "D1" ;  break;
   case 10080 :   TimeFrameStr = "W1" ;  break;
   case 43200 :   TimeFrameStr = "MN1";  break;
   default :      TimeFrameStr = "TF0";
   }

   TimeFrame = MathMax(TimeFrame,Period());
   IndicatorShortName("2Ma Cross Alerta Mtf("+TimeFrameStr+")");

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

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
//

int start()
{ 
   int    limit, i; 
   int    counted_bars=IndicatorCounted();
   double fasterMAnow, fasterMAprevious;
   double slowerMAnow, slowerMAprevious;
   double FasterShift1, SlowerShift1;
   

   if(counted_bars<0) return(-1);
   if(counted_bars>0) counted_bars--;
           limit=Bars-counted_bars;
           if (TimeFrame != Period()) limit = MathMax(limit,TimeFrame/Period());

//          if (FasterShift < 0) limit = MathMax(limit,-FasterShift);
//          if (SlowerShift < 0) limit = MathMax(limit,-SlowerShift);


       FasterShift1=0.0;   SlowerShift1=0.0; 
       
   if (FasterShift>SlowerShift)  FasterShift1=FasterShift-SlowerShift; 
   else
   if (FasterShift<SlowerShift)  SlowerShift1=SlowerShift-FasterShift; 
   
   
   double delshift=MathMin(FasterShift,SlowerShift);
   
   SetIndexShift(0,delshift);   SetIndexShift(1,delshift);


      if (FasterShift||FasterShift1< 0) limit = MathMax(limit,-MathMin(FasterShift,FasterShift1));
      if (SlowerShift||SlowerShift1< 0) limit = MathMax(limit,-MathMin(SlowerShift,SlowerShift1));






   //
   //
   //
   //
   //
   //

   
   for(i = limit; i >=0; i--)
   {
   int y = iBarShift(NULL,TimeFrame,Time[i]);
         
      ma1[i]  = iMA(NULL, TimeFrame, FasterMA, FasterShift1, FasterMode, PRICE_CLOSE, y);
      ma2[i]  = iMA(NULL, TimeFrame, SlowerMA, SlowerShift1, SlowerMode, PRICE_CLOSE, y);
      ma1s[i] = iMA(NULL, TimeFrame, FasterMA, 0, FasterMode, PRICE_CLOSE, y);
      ma2s[i] = iMA(NULL, TimeFrame, SlowerMA, 0, SlowerMode, PRICE_CLOSE, y);

         if (crossesOnCurrent==false && i==0) continue;
         
      //
      //
      //
      //
      //
         
         fasterMAnow      = ma1[i];
         fasterMAprevious = ma1[i+1];
         slowerMAnow      = ma2[i];
         slowerMAprevious = ma2[i+1];
      
      //
      //
      //
      //
      //
      
      int    crossID=0;
      double curr;
      double prev;
      double point;
      while (true)
         {
            if (fasterMAnow > 0 && slowerMAnow > 0)
               {
                  curr  =  fasterMAnow      - slowerMAnow;
                  prev  =  fasterMAprevious - slowerMAprevious;
                  point = (fasterMAnow      + fasterMAprevious)/2;
                     if (curr*prev<=0) { crossID=2; break; }
               }
               break;
         }
      
         //
         //
         //
         //
         //
         
         CrossUp[i]    = EMPTY_VALUE;
         CrossDown[i]  = EMPTY_VALUE;
         CrossWUp[i]   = EMPTY_VALUE;
         CrossWDown[i] = EMPTY_VALUE;
         if (crossID>0)
         {
            if (alertsOn)
            if ((i==0 && crossesOnCurrent==true) || (i==1 && crossesOnCurrent==false))
            {
                        if(curr>0) doAlert("Fast MA crossed Slow MA UP");
                        else       doAlert("Fast MA crossed Slow MA DOWN"); 
             
            }               

            //
            //
            //
            //
            //
            
            double Range = 0.0;
            for (int counter=i ;counter<=i+9;counter++) Range += MathAbs(High[counter]-Low[counter]);
                                                        Range /= 10;

            //
            //
            //
            //
            //
            



               if (curr>0)    {
                     CrossWUp[i]  = point - Range*0.5;
                     CrossUp[i]   = point - Range*0.85;
                                    }
               else           {
                     CrossWDown[i] = point + Range*0.5;
                     CrossDown[i] = point + Range*0.85;             
                                    }

         }               

   }   
   return(0);
 }


//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
//
//
//
//
 
void doAlert(string doWhat)
{
   static string   previousAlert="nothing";
   static datetime previousTime;
   string message;
   
      if (previousAlert != doWhat || previousTime != Time[0]) {
          previousAlert  = doWhat;
          previousTime   = Time[0];

          //
          //
          //
          //
          //

          message =  StringConcatenate(Symbol()," at ",TimeToStr(TimeLocal(),TIME_SECONDS)," ",doWhat);
             if (alertsMessage) Alert(message);
             if (alertsEmail)   SendMail(StringConcatenate(Symbol(),"3 MA line crossing"),message);
             if (alertsSound)   PlaySound("alert2.wav");
      }
}


Comments