MA_Crossover_Signal_v3

Download script
Author: Copyright � 2005, Jason Robinson (jnrtrading)
MA_Crossover_Signal_v3

This tool is designed to simplify technical analysis by pinpointing the exact moments when two moving averages intersect on a price chart. In trading, moving averages are commonly used to identify trends; however, when you zoom out or look at large timeframes, the specific point where these lines cross can become difficult to see clearly among the many candles and bars.

Core Functionality

The script automates the detection of "crossovers"—a primary signal used by traders to determine potential shifts in market momentum. Instead of requiring you to manually squint at two overlapping lines to find a transition, the tool identifies these specific moments and places a visual marker (an arrow) directly on the chart at the point of intersection.

How the Logic Works

The script follows a systematic three-step process to identify these signals:

  1. Moving Average Calculation: The tool monitors two different moving averages simultaneously. You can customize the speed of these averages (the "periods") and the type of calculation used (such as Simple, Exponential, Smoothed, or Linear Weighted). One is typically set as a "faster" average to react quickly to price changes, while the other acts as a "slower" trend indicator.
  2. Trend Comparison: The logic constantly compares the position of the faster moving average against the slower one across three consecutive points in time: the current bar, the previous bar, and the following bar.
  3. Signal Identification:
    • Upward Cross (Bullish): If the faster average was below the slower average in the past but has moved above it in the current moment, the tool registers an upward crossover and places a marker below the price candle.
    • Downward Cross (Bearish): If the faster average was above the slower average in the past but has dropped below it in the current moment, the tool registers a downward crossover and places a marker above the price candle.

Dynamic Positioning

To ensure that these markers do not clutter the actual price action, the script calculates the "Range" of the market (the distance between highs and lows) over a short window. It then uses this calculation to automatically offset the arrows slightly above or below the candles. This ensures that the signals remain visible and organized, providing a clean visual guide for identifying trend reversals without obstructing your view of the price bars.

Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1
14 Views
0 Downloads
0 Favorites
MA_Crossover_Signal_v3
//+------------------------------------------------------------------+
//|                                         EMA-Crossover_Signal.mq4 |
//|         Copyright © 2005, Jason Robinson (jnrtrading)            |
//|                   http://www.jnrtading.co.uk                     |
//+------------------------------------------------------------------+

/*
  +------------------------------------------------------------------+
  | Allows you to enter two ema periods and it will then show you at |
  | Which point they crossed over. It is more usful on the shorter   |
  | periods that get obscured by the bars / candlesticks and when    |
  | the zoom level is out. Also allows you then to remove the emas   |
  | from the chart. (emas are initially set at 5 and 6)              |
  +------------------------------------------------------------------+
*/   
#property copyright "Copyright © 2005, Jason Robinson (jnrtrading)"
#property link      "http://www.jnrtrading.co.uk"

#property indicator_chart_window
#property indicator_buffers 2
#property indicator_color1 DodgerBlue
#property indicator_color2 Red

double CrossUp[];
double CrossDown[];
extern int FasterMode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern int FasterMA =   13;
extern int SlowerMode = 1; //0=sma, 1=ema, 2=smma, 3=lwma
extern int SlowerMA =   25;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, EMPTY);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, CrossUp);
   SetIndexStyle(1, DRAW_ARROW, EMPTY);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, CrossDown);
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- 

//----
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
   int limit, i, counter;
   double fasterMAnow, slowerMAnow, fasterMAprevious, slowerMAprevious, fasterMAafter, slowerMAafter;
   double Range, AvgRange;
   int counted_bars=IndicatorCounted();
//---- check for possible errors
   if(counted_bars<0) return(-1);
//---- last counted bar will be recounted
   if(counted_bars>0) counted_bars--;

   limit=Bars-counted_bars;
   
   for(i = 0; i <= limit; i++) {
   
      counter=i;
      Range=0;
      AvgRange=0;
      for (counter=i ;counter<=i+9;counter++)
      {
         AvgRange=AvgRange+MathAbs(High[counter]-Low[counter]);
      }
      Range=AvgRange/10;
       
      fasterMAnow = iMA(NULL, 0, FasterMA, 0, FasterMode, PRICE_CLOSE, i);
      fasterMAprevious = iMA(NULL, 0, FasterMA, 0, FasterMode, PRICE_CLOSE, i+1);
      fasterMAafter = iMA(NULL, 0, FasterMA, 0, FasterMode, PRICE_CLOSE, i-1);

      slowerMAnow = iMA(NULL, 0, SlowerMA, 0, SlowerMode, PRICE_CLOSE, i);
      slowerMAprevious = iMA(NULL, 0, SlowerMA, 0, SlowerMode, PRICE_CLOSE, i+1);
      slowerMAafter = iMA(NULL, 0, SlowerMA, 0, SlowerMode, PRICE_CLOSE, i-1);
      
      if ((fasterMAnow > slowerMAnow) && (fasterMAprevious < slowerMAprevious) && (fasterMAafter > slowerMAafter)) {
         CrossUp[i] = Low[i] - Range*0.5;
      }
      else if ((fasterMAnow < slowerMAnow) && (fasterMAprevious > slowerMAprevious) && (fasterMAafter < slowerMAafter)) {
         CrossDown[i] = High[i] + Range*0.5;
      }
   }
   return(0);
}

Comments