EMAAnglezeroalert for EJ_4h
Download scriptThis tool is designed to help traders visualize the momentum and direction of a trend by measuring the "steepness" or angle of an Exponential Moving Average (EMA). Instead of just looking at where the price is, this indicator focuses on how aggressively the average is moving.
Core Functionality
The script calculates the slope of the EMA over a specific distance. By comparing the value of the EMA at a starting point in the past to its current value, it determines if the market is trending upwards, downwards, or if it issideways (flat).
Visual Indicators
The logic translates these mathematical angles into three distinct visual states represented by colored histograms:
- Green (Upward Trend): When the angle of the EMA is positive and exceeds a specific threshold, the histogram turns green. This indicates a strong upward movement.
- Red (Downward Trend): When the angle of the EMA is negative and falls below the negative threshold, the histogram turns red. This indicates a strong downward movement.
- Yellow (Neutral/Flat Zone): If the angle of the EMA is very small—meaning it is "near zero"—the indicator identifies this as a period of consolidation or lack of trend. The histogram will appear yellow in this state.
Key Features & Logic
- Customizable Sensitivity: Users can define how steep a move must be to trigger a "trend" signal via the AngleThreshold setting. This allows you to filter out minor fluctuations and focus only on significant moves.
- Dynamic Scaling: The script automatically adjusts its calculations based on the currency pair being traded. For example, it recognizes "JPY" pairs and adjusts the scaling factor so that the visual output remains consistent across different markets.
- Automated Notifications: The logic includes a built-in alert system. When the trend shifts (e.g., moving from a flat/yellow state into a green or red state), the script can trigger:
- On-screen pop-up alerts.
- Audible sound notifications.
- Email alerts sent directly to the user.
- Smart Alert Handling: To prevent the system from spamming multiple notifications for the same move, the script uses "Global Variables" to track when an alert has been fired, ensuring you only receive one notification per significant trend change.
Summary for Traders
This indicator acts as a momentum filter. It helps you identify when a market is truly moving with strength (Green/Red) versus when it is simply drifting without direction (Yellow), allowing for more informed entries based on the "tilt" of the average price.
//+------------------------------------------------------------------+
//| EMAAngle.mq4 |
//| jpkfox |
//| |
//| You can use this indicator to measure when the EMA angle is |
//| "near zero". AngleTreshold determines when the angle for the |
//| EMA is "about zero": This is when the value is between |
//| [-AngleTreshold, AngleTreshold] (or when the histogram is red). |
//| EMAPeriod: EMA period |
//| AngleTreshold: The angle value is "about zero" when it is |
//| between the values [-AngleTreshold, AngleTreshold]. |
//| StartEMAShift: The starting point to calculate the |
//| angle. This is a shift value to the left from the |
//| observation point. Should be StartEMAShift > EndEMAShift. |
//| StartEMAShift: The ending point to calculate the |
//| angle. This is a shift value to the left from the |
//| observation point. Should be StartEMAShift > EndEMAShift. |
//| |
//| 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 |
//| |
//+------------------------------------------------------------------+
#property copyright "jpkfox"
#property link "http://www.strategybuilderfx.com/forums/showthread.php?t=15274&page=1&pp=8"
//---- 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 bool DoAlert = true;
extern int EMAPeriod=55;
extern double AngleTreshold=0.2;
extern int StartEMAShift=8;
extern int EndEMAShift=0;
extern int SoundON=1;
extern int EmailON=0;
extern int soundon2=0;
//---- indicator buffers
double UpBuffer[];
double DownBuffer[];
double ZeroBuffer[];
int trend, old_trend = 0;
//+------------------------------------------------------------------+
//| 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!");
//---- name for DataWindow and indicator subwindow label
IndicatorShortName("EMAAngleZero("+EMAPeriod+","+AngleTreshold+","+StartEMAShift+","+EndEMAShift+")");
//---- initialization done
return(0);
}
//+------------------------------------------------------------------+
//| The angle for EMA |
//+------------------------------------------------------------------+
int start()
{
double fEndMA, fStartMA;
double fAngle, mFactor, dFactor;
int nLimit, i;
int nCountedBars;
double angle;
int ShiftDif;
string Sym;
double tmp=0;
if(EndEMAShift >= StartEMAShift)
{
Print("Error: EndEMAShift >= StartEMAShift");
StartEMAShift = 6;
EndEMAShift = 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 = 10000.0;
Sym = StringSubstr(Symbol(),3,3);
if (Sym == "JPY") mFactor = 100.0;
ShiftDif = StartEMAShift-EndEMAShift;
mFactor /= ShiftDif;
//---- main loop
for(i=0; i<nLimit; i++)
{
fEndMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+EndEMAShift);
fStartMA=iMA(NULL,0,EMAPeriod,0,MODE_EMA,PRICE_MEDIAN,i+StartEMAShift);
// 10000.0 : Multiply by 10000 so that the fAngle is not too small
// for the indicator Window.
fAngle = mFactor * (fEndMA - fStartMA)/2.0;
// fAngle = MathArctan(fAngle)/dFactor;
DownBuffer[i] = 0.0;
UpBuffer[i] = 0.0;
ZeroBuffer[i] = 0.0;
if(fAngle > AngleTreshold)
{
UpBuffer[i] = fAngle;
trend = 1;
if (trend != old_trend && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+Period()) ){
if (SoundON==1){ Alert("EJ_4H Alert at ",Ask,", Date=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime())," Symbol=",Symbol()," Period=",Period());
if (soundon2==1){
PlaySound("C:\Program Files\Interbank FX Trader 4\sounds\alert.wav");}}
if (EmailON==1) SendMail("SELL signal alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
tmp = CurTime() + (Period()-MathMod(Minute(),Period()))*60;
GlobalVariableSet("AlertTime"+Symbol()+Period(),tmp);
GlobalVariableSet("SignalType"+Symbol()+Period(),OP_BUY);
}
old_trend = trend;
}
else if (fAngle < -AngleTreshold)
{
DownBuffer[i] = fAngle;
trend = -1;
if (trend != old_trend && CurTime() > GlobalVariableGet("AlertTime"+Symbol()+Period()) ){
if (SoundON==1){ Alert("EJ_4H Alert at ",Ask,", Date=",TimeToStr(CurTime(),TIME_DATE)," ",TimeHour(CurTime()),":",TimeMinute(CurTime())," Symbol=",Symbol()," Period=",Period());
if (soundon2==1){
PlaySound("C:\Program Files\Interbank FX Trader 4\sounds\alert.wav");}}
if (EmailON==1) SendMail("SELL signal alert","SELL signal at Ask="+DoubleToStr(Ask,4)+", Bid="+DoubleToStr(Bid,4)+", Date="+TimeToStr(CurTime(),TIME_DATE)+" "+TimeHour(CurTime())+":"+TimeMinute(CurTime())+" Symbol="+Symbol()+" Period="+Period());
tmp = CurTime() + (Period()-MathMod(Minute(),Period()))*60;
GlobalVariableSet("AlertTime"+Symbol()+Period(),tmp);
GlobalVariableSet("SignalType"+Symbol()+Period(),OP_BUY);
}
old_trend = trend;
}
else ZeroBuffer[i] = fAngle;
}
return(0);
}
//+------------------------------------------------------------------+
Comments