trendtest_OHLC

Author: Copyright � 2005, Jason Robinson (jnrtrading)
trendtest_OHLC

This script is designed as a visual aid for traders who use Moving Averages (MA) to identify trends. Its primary purpose is to pinpoint the exact moment when two different moving averages cross each other, making it easier to spot trend changes that might be difficult to see on a crowded chart or when zoomed out.

How the Logic Works

The script functions by tracking two distinct moving averages: a "Faster" one and a "Slower" one. By comparing these two lines against each other, the tool identifies specific shifts in market momentum.

1. Trend Detection (Crossovers) The core logic monitors the relationship between the two moving averages over time. It looks for three specific conditions to confirm a crossover:

  • Upward Cross: The script detects when the Faster Moving Average moves from below the Slower Moving Average to above it. When this happens, it identifies a potential bullish (upward) trend.
  • Downward Cross: Conversely, it detects when the Faster Moving Average drops from above the Slower Moving Average to below it, identifying a potential bearish (downward) trend.

2. Visual Signaling Instead of just showing lines, the script places specific visual markers on the chart:

  • Upward Signals: When an upward cross is confirmed, a marker is placed slightly below the price candle.
  • Downward Signals: When a downward cross is confirmed, a marker is placed slightly above the price candle.
  • The distance of these markers from the candle is automatically adjusted based on recent market volatility (the "range" of previous bars), ensuring the markers remain visible and don't overlap with the price action.

3. Audio Alerts To ensure traders don't miss a move while away from the screen, the script includes an integrated sound notification system. It plays a specific sound file when a new crossover occurs, providing an immediate audible cue of the trend shift.

4. Customization and Clarity The tool offers several layers of flexibility:

  • Moving Average Types: Users can choose between different calculation methods (such as Simple, Exponential, Smooth, or Linear Weighted) for both the fast and slow averages.
  • Price Source: You can specify which price data the averages should calculate based on (e.g., Open, Close, High, or Low prices).
  • Chart Cleanliness: Because the logic handles the calculation of the crosses automatically, traders have the option to remove the moving average lines from their main chart entirely, keeping the workspace clean while still receiving the visual and audio crossover signals.
Indicators Used
Moving average indicator
Miscellaneous
Implements a curve of type %1It plays sound alerts
11 Views
0 Downloads
0 Favorites
trendtest_OHLC
//+------------------------------------------------------------------+
//|                                         EMA-Crossover_Signal.mq4 |
//|         Copyright © 2005, Jason Robinson (jnrtrading)            |
//|                   http://www.jnrtading.co.uk                     |
//+------------------------------------------------------------------+

/*
  +------------------------------------------------------------------+
  | Allows you to enter two ma 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.               |
  +------------------------------------------------------------------+
*/   
#property copyright "Copyright © 2005, Jason Robinson (jnrtrading)"
#property link      "http://www.jnrtrading.co.uk"

#property  indicator_separate_window
#property indicator_buffers 6
#property indicator_color1 Yellow
#property indicator_color2 SkyBlue
#property indicator_color3 Red
#property indicator_color4 White

//---- input parameters
/*************************************************************************
---------------------------------------
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. 
You must use the numeric value of the Applied Price that you want to use
when you set the 'applied_price' value with the indicator inputs.
---------------------------------------
**************************************************************************/

double CrossUp[];
double CrossDown[];
extern int FasterMode = 3; //0=sma, 1=ema, 2=smma, 3=lwma
extern int FasterMA =   3;
extern int Faster_applied_price=PRICE_OPEN;
extern int SlowerMode = 3; //0=sma, 1=ema, 2=smma, 3=lwma
extern int SlowerMA =   3;
extern int Slower_applied_price=PRICE_CLOSE;
double ExtMapBuffer1[];
double ExtMapBuffer2[];
extern bool SoundON=true;
double alertTag;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init()
  {
//---- indicators
   SetIndexStyle(0, DRAW_ARROW, STYLE_SOLID,3);
   SetIndexArrow(0, 233);
   SetIndexBuffer(0, CrossUp);
   SetIndexStyle(1, DRAW_ARROW, STYLE_SOLID,3);
   SetIndexArrow(1, 234);
   SetIndexBuffer(1, CrossDown);
   //---- indicators
   SetIndexStyle(2,DRAW_LINE);
   SetIndexBuffer(2,ExtMapBuffer1);
   SetIndexStyle(3,DRAW_LINE);
   SetIndexBuffer(3,ExtMapBuffer2);
//----
//----
   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();
   int counted_bars1=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;
         if (SoundON==true && alertTag!=Time[0]){
  //     Alert("EMA Cross Trend going UP on ",Symbol(),Period());
        PlaySound("trendup.wav");
        alertTag = Time[0];}
      }
      else if ((fasterMAnow < slowerMAnow) && (fasterMAprevious > 
slowerMAprevious) && (fasterMAafter < slowerMAafter)) {
         CrossDown[i] = High[i] + Range*0.5;
         if (SoundON==true && alertTag!=Time[0]){
  //        Alert("EMA Cross Trend going Down on ",Symbol(),Period());
          PlaySound("trendn.wav");
          alertTag = Time[0];
        }
      }
   }


//---- check for possible errors
   if (counted_bars1<0) return(-1);
//---- last counted bar will be recounted
   if (counted_bars1>0) counted_bars1--;
   
   int pos=Bars-counted_bars1;
   
     
 
   while(pos>=0)
     {
         ExtMapBuffer1[pos]= iMA(NULL,0,FasterMA,0,FasterMode,Faster_applied_price,pos);

         ExtMapBuffer2[pos]= iMA(NULL,0,SlowerMA,0,SlowerMode,Slower_applied_price,pos);

         
         pos--;
     }
//----      

   return(0);
}


       

Comments