//+----------------------------------------------------------------------------- //| MATrendDetector.mq4 //| Lukasz Szelag (lukasz74nj@gmail.com) //| http://www.forexabyss.com //| //| A custom indicator for trend detection based on a technique that employs //| exponential moving averages by checking if moving averages are aligned in //| the proper order, as determined by the following conditions: //| //| Uptrend conditions: //| //| EMA(10) > EMA(20) > EMA(50) > EMA(200) //| //| Downtrend conditions: //| //| EMA(10) < EMA(20) < EMA(50) < EMA(200) //| //| For every bar that satisfies either conditions little arrow is shown //| pointing either upward or downward depending on the trend direction. In //| addition, a bigger arrow or “No Trend” text is shown in the upper left //| corner that corresponds to conditions calculated for the current (zero) bar. //| //| Date Version Comments //| 1/30/2009 1.0 Initial version. //| 2/12/2009 1.1 Draw main trend indicator for the zero bar only. //| 2/22/2009 1.2 Added error handling, refactored main loop. //| //| 3/03/2009 1.3 In deinit(), delete only the object created by this //| indicator instead of all objects. //+----------------------------------------------------------------------------- #property copyright "Lukasz Szelag (lukasz74nj@gmail.com)" #property link "http://www.forexabyss.com" #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Green #property indicator_color2 Red //+----------------------------------------------------------------------------- //| Constants. //+----------------------------------------------------------------------------- #define TREND_UP_ARROW 236 #define TREND_DOWN_ARROW 238 #define TREND_OBJ_NAME "Trend" //+----------------------------------------------------------------------------- //| Global variables. //+----------------------------------------------------------------------------- double buf0[], buf1[]; //+----------------------------------------------------------------------------- //| Indicator initialization special function. //+----------------------------------------------------------------------------- int init() { IndicatorShortName("MATrendDetector"); // uptrend indicator arrow SetIndexBuffer(0, buf0); SetIndexStyle(0, DRAW_ARROW); SetIndexArrow(0, TREND_UP_ARROW); SetIndexEmptyValue(0, EMPTY_VALUE); // downtrend indicator arrow SetIndexBuffer(1, buf1); SetIndexStyle(1, DRAW_ARROW); SetIndexArrow(1, TREND_DOWN_ARROW); SetIndexEmptyValue(1, EMPTY_VALUE); // main trend indicator for the current (zero) bar ObjectCreate(TREND_OBJ_NAME, OBJ_LABEL, 0, 0, 0, 0, 0); ObjectSet(TREND_OBJ_NAME, OBJPROP_XDISTANCE, 20); ObjectSet(TREND_OBJ_NAME, OBJPROP_YDISTANCE, 20); ObjectSetText(TREND_OBJ_NAME, " ", 20, "Wingdings"); return(0); } //+----------------------------------------------------------------------------- //| Indicator deinitialization special function. //+----------------------------------------------------------------------------- int deinit() { ObjectDelete(TREND_OBJ_NAME); return(0); } //+----------------------------------------------------------------------------- //| Indicator start special function. //+----------------------------------------------------------------------------- int start() { // not enough bars for calculations if (Bars < 200) { return(0); } int countedBars = IndicatorCounted(); // check for possible errors if (countedBars < 0) { return(-1); } // index of the first uncounted bar int firstIndex = Bars - countedBars - 1; double ema10, ema20, ema50, ema200; for(int i = firstIndex; i >= 0; i--) { ema10 = iMA(NULL, 0, 10, 0, MODE_EMA, PRICE_CLOSE, i); ema20 = iMA(NULL, 0, 20, 0, MODE_EMA, PRICE_CLOSE, i); ema50 = iMA(NULL, 0, 50, 0, MODE_EMA, PRICE_CLOSE, i); ema200 = iMA(NULL, 0, 200, 0, MODE_EMA, PRICE_CLOSE, i); // if moving averages are aligned in the proper order for an uptrend if ((ema10 > ema20) && (ema20 > ema50) && (ema50 > ema200)) { // if current (zero) bar if (i == 0) { ObjectSetText(TREND_OBJ_NAME, CharToStr(TREND_UP_ARROW), 20, "Wingdings", Green); } buf0[i] = High[i] + 5 * Point; buf1[i] = EMPTY_VALUE; } // if moving averages are aligned in the proper order for a downtrend else if ((ema10 < ema20) && (ema20 < ema50) && (ema50 < ema200)) { // if current (zero) bar if (i == 0) { ObjectSetText(TREND_OBJ_NAME, CharToStr(TREND_DOWN_ARROW), 20, "Wingdings", Red); } buf0[i] = EMPTY_VALUE; buf1[i] = Low[i] - 5 * Point; } // no trend else { // if current (zero) bar if (i == 0) { ObjectSetText(TREND_OBJ_NAME, "No Trend", 15, "Tahoma", Blue); } buf0[i] = EMPTY_VALUE; buf1[i] = EMPTY_VALUE; } } return(0); }