//+------------------------------------------------------------------+ //| EMMA.mq4 | //| Extremums Market Moving Average | //| Copyright © 2010, Анатолий Сергеев | //| mql.sergeev@yandex.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2010, Анатолий Сергеев" #property link "mql.sergeev@yandex.ru" #property indicator_chart_window #property indicator_buffers 1 #property indicator_color1 Blue //+------------------------------------------------------------------+ extern double EMMA_Deviation_in_Percent = 0.1; //Фильтрация изгибов скользящего среднего, отклонение в процентах. //+------------------------------------------------------------------+ extern int EMMA_Mode = 0; //Режим работы индикатора //PRICE_CLOSE 0 По ценам закрытия //PRICE_HIGH/LOW 1 По ценам макс./мин. //+------------------------------------------------------------------+ extern bool EMMA_Redraw = true; //ВКЛ./ВЫКЛ. перерисовки //+------------------------------------------------------------------+ extern int MA_Period = 18; //Период усреднения для вычисления скользящего среднего. //+------------------------------------------------------------------+ extern int MA_Method = 0; //Метод усреднения скользящего среднего. Может быть любым из значений методов скользящего среднего (Moving Average): /*MODE_SMA 0 Простое скользящее среднее MODE_EMA 1 Экспоненциальное скользящее среднее MODE_SMMA 2 Сглаженное скользящее среднее MODE_LWMA 3 Линейно-взвешенное скользящее среднее */ //+------------------------------------------------------------------+ extern int MA_Applied_Price = 0; //Используемая цена скользящего среднего. Может быть любой из ценовых констант: /*PRICE_CLOSE 0 Цена закрытия PRICE_OPEN 1 Цена открытия PRICE_HIGH 2 Максимальная цена PRICE_LOW 3 Минимальная цена PRICE_MEDIAN 4 Средняя цена, (high+low)/2 PRICE_TYPICAL 5 Типичная цена, (high+low+close)/3 PRICE_WEIGHTED 6 Взвешенная цена закрытия, (high+low+close+close)/4 */ //+------------------------------------------------------------------+ extern int Maximum_History = 500; //Ограничение истории для расчетов, если 0 то расчет всей истории //+------------------------------------------------------------------+ extern bool Manager_Murrey = false; //Менеджер индикатора Murrey_Math_Line v2 //+------------------------------------------------------------------+ extern bool Signal = false; //ВКЛ./ВЫКЛ. оповещения алерт //+------------------------------------------------------------------+ extern bool Fibo = false; //ВКЛ./ВЫКЛ. Уровни Фибоначчи. //+------------------------------------------------------------------+ extern bool Fibo_Fan = false; //ВКЛ./ВЫКЛ. Веер Фибоначчи. //+------------------------------------------------------------------+ extern bool Regression_Channel = false; //ВКЛ./ВЫКЛ. Канал линейной регрессии. //+------------------------------------------------------------------+ extern bool StdDevChennel = false; //ВКЛ./ВЫКЛ. Канал стандартных отклонений. //+------------------------------------------------------------------+ extern bool TrafficLight = false; //+------------------------------------------------------------------+ extern string TrafficLight_initialization = "|0/3-Red|1/3-Yellow|2/3-LawnGreen|"; //+------------------------------------------------------------------+ extern int TrafficLight_width_line = 2; //+------------------------------------------------------------------+ double EMMABuffer[]; //Индикаторний массив double ima; double save_Price; datetime home_Time; int position; int shift; int ctrl = -1; bool flag; bool flag_history; string TLDate [][2]; //+------------------------------------------------------------------+ //| EMMA initialization function | //+------------------------------------------------------------------+ int init(){ IndicatorBuffers(1); IndicatorDigits(MarketInfo(Symbol(),MODE_DIGITS)); SetIndexStyle(0,DRAW_SECTION); SetIndexBuffer(0,EMMABuffer); SetIndexEmptyValue(0,0.0); IndicatorShortName("EMMA("+DoubleToStr(EMMA_Deviation_in_Percent, 4)+","+MA_Period+")"); if(MA_Applied_Price > 6 || MA_Applied_Price < 0)MA_Applied_Price = 0; // if(EMMA_Mode > 1 || EMMA_Mode < 0)EMMA_Mode = 0; // Блок проверки корректности введенных параметров if(MA_Method > 3 || MA_Method < 0)MA_Method = 0; // if(MA_Period < 2)MA_Period = 18; // EMMA_Deviation_in_Percent /= 100; if(TrafficLight && EMMA_Redraw)initTrafficLight(); } //+------------------------------------------------------------------+ //| EMMA | //+------------------------------------------------------------------+ int start(){ if(Bars-IndicatorCounted()-1 > 1)recount(); //При "обновлении" истории, очистить все, и начать построение заново if(Maximum_History == 0){ //Если история не ограничена shift = Bars-IndicatorCounted()-1; //Однократный пересчет всей | Далее только 0 бар }else{ //Если ограничена if(!flag_history){ shift = Maximum_History; //Однократный пересчет всей (ограниченной) home_Time = Time[Maximum_History + 1]; //Если история ограничена, то задается начальная дата поиска flag_history = true; }else{ shift = Bars-IndicatorCounted()-1; //Далее только 0 бар } } for(; shift >= 1; shift--){ //Цикл по непосчитанным барам ima = iMA(NULL, 0, MA_Period, 0, MA_Method, MA_Applied_Price, shift); //+-------------------------------------------------------------------------------------------+ if(ctrl != 0 && !flag && getTop() != -1){ //Поиск точки перелома пика save_Price = getTop(); flag = true; ctrl = 0; } if(ctrl == 0 && flag && ima <= save_Price - save_Price * EMMA_Deviation_in_Percent){ //Фильтрация точки перелома пика search(0); //Поиск экстремума пика flag = false; position = 1; //top } if(ctrl == 0 && flag && ima >= save_Price){ //Сброс фильтра flag = false; ctrl = 1; } //+-------------------------------------------------------------------------------------------+ if(ctrl != 1 && !flag && getBottom() != -1){ //Поиск точки перелома впадины save_Price = getBottom(); flag = true; ctrl = 1; } if(ctrl == 1 && flag && ima >= save_Price + save_Price * EMMA_Deviation_in_Percent){ //Фильтрация точки перелома впадины search(1); //Поиск экстремума впадины flag = false; position = 2; //bottom } if(ctrl == 1 && flag && ima <= save_Price){ //Сброс фильтра flag = false; ctrl = 0; } //+-------------------------------------------------------------------------------------------+ reDraw(); //redraw } manageMurrey(); //manager signal(); //alert fibo(); //fibonacci fiboFan(); //fibonacci fan regressionChannel(); //regression channal stdDevChennel(); //standart deviation channal trafficLight(); //color indication } //+------------------------------------------------------------------+ //| Search extremums | //+------------------------------------------------------------------+ void search(int type, bool write = true){ int searchShift; if(type == 0){ switch(EMMA_Mode){ case 0: searchShift = iHighest(NULL, 0, MODE_CLOSE, iBarShift(NULL, 0, home_Time)-shift, shift); EMMABuffer[searchShift] = Close[searchShift]; break; case 1: searchShift = iHighest(NULL, 0, MODE_HIGH, iBarShift(NULL, 0, home_Time)-shift, shift); EMMABuffer[searchShift] = High[searchShift]; break; } }else{ switch(EMMA_Mode){ case 0: searchShift = iLowest(NULL, 0, MODE_CLOSE, iBarShift(NULL, 0, home_Time)-shift, shift); EMMABuffer[searchShift] = Close[searchShift]; break; case 1: searchShift = iLowest(NULL, 0, MODE_LOW, iBarShift(NULL, 0, home_Time)-shift, shift); EMMABuffer[searchShift] = Low[searchShift]; break; } } if(write)home_Time = Time[searchShift]; } //+------------------------------------------------------------------+ //| Search top | //+------------------------------------------------------------------+ double getTop(){ double previous = iMA(NULL, 0, MA_Period, 0, MA_Method, MA_Applied_Price, shift + 1); if(ima < previous)return(previous); return(-1); } //+------------------------------------------------------------------+ //| Search bottom | //+------------------------------------------------------------------+ double getBottom(){ double previous = iMA(NULL, 0, MA_Period, 0, MA_Method, MA_Applied_Price, shift + 1); if(ima > previous)return(previous); return(-1); } //+------------------------------------------------------------------+ //| Manager Murrey | //+------------------------------------------------------------------+ void manageMurrey(){ if(ObjectFind("MML_StartBar") != -1 && Manager_Murrey){ ObjectSet("MML_StartBar", OBJPROP_TIME1, getTime()); ObjectSet("MML_StartBar", OBJPROP_PRICE1, getDate()); WindowRedraw(); } } //+------------------------------------------------------------------+ //| Alert | //+------------------------------------------------------------------+ void signal(){ static double price; if(!Signal)return; if(position == 1 && price != getDate()){ if(EMMA_Redraw)Alert(Symbol()," Новая впадина.");else Alert(Symbol()," Новый пик."); } if(position == 2 && price != getDate()){ if(EMMA_Redraw)Alert(Symbol()," Новый пик.");else Alert(Symbol()," Новая впадина."); } price = getDate(); } //+------------------------------------------------------------------+ //| Redraw | //+------------------------------------------------------------------+ void reDraw(){ if(!EMMA_Redraw)return; if(!iBarShift(NULL, 0, home_Time)-1 > shift)return; for(int loop = iBarShift(NULL, 0, home_Time)-1; loop > shift; loop--)EMMABuffer[loop] = 0.0; if(position == 2)search(0, false); if(position == 1)search(1, false); } //+------------------------------------------------------------------+ //| getDate | //+------------------------------------------------------------------+ double getDate(bool next = false){ for(int loop = shift;loop < Bars;loop++){ if(EMMABuffer[loop] != 0){ if(next){ next = false; continue; } return(EMMABuffer[loop]); } } } //+------------------------------------------------------------------+ //| getTime | //+------------------------------------------------------------------+ datetime getTime(bool next = false){ for(int loop = shift;loop < Bars;loop++){ if(EMMABuffer[loop] != 0){ if(next){ next = false; continue; } return(Time[loop]); } } } //+------------------------------------------------------------------+ //| Fibo | //+------------------------------------------------------------------+ void fibo(){ if(!Fibo)return; if(ObjectFind("EMMA_FIBO") != -1){ ObjectSet("EMMA_FIBO", OBJPROP_TIME1, getTime(true)); ObjectSet("EMMA_FIBO", OBJPROP_PRICE1, getDate(true)); ObjectSet("EMMA_FIBO", OBJPROP_TIME2, getTime()); ObjectSet("EMMA_FIBO", OBJPROP_PRICE2, getDate()); WindowRedraw(); }else{ ObjectCreate("EMMA_FIBO", OBJ_FIBO, 0, getTime(true), getDate(true), getTime(), getDate()); ObjectSet("EMMA_FIBO", OBJPROP_COLOR, Black); ObjectSet("EMMA_FIBO", OBJPROP_LEVELCOLOR, Black); } } //+------------------------------------------------------------------+ //| Fibo Fan | //+------------------------------------------------------------------+ void fiboFan(){ if(!Fibo_Fan)return; if(ObjectFind("EMMA_FIBO_FAN") != -1){ ObjectSet("EMMA_FIBO_FAN", OBJPROP_TIME1, getTime(true)); ObjectSet("EMMA_FIBO_FAN", OBJPROP_PRICE1, getDate(true)); ObjectSet("EMMA_FIBO_FAN", OBJPROP_TIME2, getTime()); ObjectSet("EMMA_FIBO_FAN", OBJPROP_PRICE2, getDate()); WindowRedraw(); }else{ ObjectCreate("EMMA_FIBO_FAN", OBJ_FIBOFAN, 0, getTime(true), getDate(true), getTime(), getDate()); ObjectSet("EMMA_FIBO_FAN", OBJPROP_COLOR, Black); ObjectSet("EMMA_FIBO_FAN", OBJPROP_LEVELCOLOR, Black); } } //+------------------------------------------------------------------+ //| Regression Channel | //+------------------------------------------------------------------+ void regressionChannel(){ if(!Regression_Channel)return; if(ObjectFind("EMMA_Regression_Channel") != -1){ ObjectSet("EMMA_Regression_Channel", OBJPROP_TIME1, getTime(true)); ObjectSet("EMMA_Regression_Channel", OBJPROP_PRICE1, getDate(true)); ObjectSet("EMMA_Regression_Channel", OBJPROP_TIME2, getTime()); ObjectSet("EMMA_Regression_Channel", OBJPROP_PRICE2, getDate()); WindowRedraw(); }else{ ObjectCreate("EMMA_Regression_Channel", OBJ_REGRESSION, 0, getTime(true), getDate(true), getTime(), getDate()); ObjectSet("EMMA_Regression_Channel", OBJPROP_COLOR, Black); } } //+------------------------------------------------------------------+ //| Standart Deviation Chennel | //+------------------------------------------------------------------+ void stdDevChennel(){ if(!StdDevChennel)return; if(ObjectFind("EMMA_StdDevChennel") != -1){ ObjectSet("EMMA_StdDevChennel", OBJPROP_TIME1, getTime(true)); ObjectSet("EMMA_StdDevChennel", OBJPROP_PRICE1, getDate(true)); ObjectSet("EMMA_StdDevChennel", OBJPROP_TIME2, getTime()); ObjectSet("EMMA_StdDevChennel", OBJPROP_PRICE2, getDate()); WindowRedraw(); }else{ ObjectCreate("EMMA_StdDevChennel", OBJ_STDDEVCHANNEL, 0, getTime(true), getDate(true), getTime(), getDate()); ObjectSet("EMMA_StdDevChennel", OBJPROP_COLOR, Black); } } //+------------------------------------------------------------------+ //| TrafficLight | //+------------------------------------------------------------------+ void trafficLight(){ if(!(TrafficLight && EMMA_Redraw))return; if(ObjectFind("EMMA_TrafficLight") != -1){ ObjectSet("EMMA_TrafficLight", OBJPROP_TIME1, getTime(true)); ObjectSet("EMMA_TrafficLight", OBJPROP_PRICE1, getDate(true)); ObjectSet("EMMA_TrafficLight", OBJPROP_TIME2, getTime()); ObjectSet("EMMA_TrafficLight", OBJPROP_PRICE2, getDate()); ObjectSet("EMMA_TrafficLight", OBJPROP_COLOR, getTrafficLightColor()); WindowRedraw(); }else{ ObjectCreate("EMMA_TrafficLight", OBJ_TREND, 0, getTime(true), getDate(true), getTime(), getDate()); ObjectSet("EMMA_TrafficLight", OBJPROP_WIDTH, TrafficLight_width_line); ObjectSet("EMMA_TrafficLight", OBJPROP_RAY, false); } } //+------------------------------------------------------------------+ //| initTrafficLight | //+------------------------------------------------------------------+ color initTrafficLight(){ int start, a, b, c; for(int l = 0; l < StringLen(TrafficLight_initialization); l++){ a = StringFind(TrafficLight_initialization, "|", start); b = StringFind(TrafficLight_initialization, "/", start); c = StringFind(TrafficLight_initialization, "-", start); if(c == -1)break; ArrayResize(TLDate, l+1); TLDate[l][0] = (EMMA_Deviation_in_Percent/StrToInteger(StringSubstr(TrafficLight_initialization, b+1, c-b-1)))*StrToInteger(StringSubstr(TrafficLight_initialization, a+1, b-a-1)); start = c+1; TLDate[l][1] = StringSubstr(TrafficLight_initialization, c+1, StringFind(TrafficLight_initialization, "|", start)-c-1); } } //+------------------------------------------------------------------+ //| getTrafficLightColor | //+------------------------------------------------------------------+ color getTrafficLightColor(){ string colors; if(StrToDouble(TLDate[0][0]) == 0){ colors = TLDate[0][1]; } for(int pos = 0; pos < ArraySize(TLDate)/2; pos++){ if(position == 1){ //search bottom if(ima >= save_Price + save_Price * StrToDouble(TLDate[pos][0]))colors = TLDate[pos][1]; }else{ //search top if(ima <= save_Price - save_Price * StrToDouble(TLDate[pos][0]))colors = TLDate[pos][1]; } } return(getColor(colors)); } //+------------------------------------------------------------------+ //| fStrToColor | //+------------------------------------------------------------------+ color getColor(string title){ color arrayColors[] = { Black, DarkGreen, DarkSlateGray, Olive, Green, Teal, Navy, Purple, Maroon, Indigo, MidnightBlue, DarkBlue, DarkOliveGreen, SaddleBrown, ForestGreen, OliveDrab, SeaGreen, DarkGoldenrod, DarkSlateBlue, Sienna, MediumBlue, Brown, DarkTurquoise, DimGray, LightSeaGreen, DarkViolet, FireBrick, MediumVioletRed, MediumSeaGreen, Chocolate, Crimson, SteelBlue, Goldenrod, MediumSpringGreen, LawnGreen, CadetBlue, DarkOrchid, YellowGreen, LimeGreen, OrangeRed, DarkOrange, Orange, Gold, Yellow, Chartreuse, Lime, SpringGreen, Aqua, DeepSkyBlue, Blue, Magenta, Red, Gray, SlateGray, Peru, BlueViolet, LightSlateGray, DeepPink, MediumTurquoise, DodgerBlue, Turquoise, RoyalBlue, SlateBlue, DarkKhaki, IndianRed, MediumOrchid, GreenYellow, MediumAquamarine, DarkSeaGreen, Tomato, RosyBrown, Orchid, MediumPurple, PaleVioletRed, Coral, CornflowerBlue, DarkGray, SandyBrown, MediumSlateBlue, Tan, DarkSalmon, BurlyWood, HotPink, Salmon, Violet, LightCoral, SkyBlue, LightSalmon, Plum, Khaki, LightGreen, Aquamarine, Silver, LightSkyBlue, LightSteelBlue, LightBlue, PaleGreen, Thistle, PowderBlue, PaleGoldenrod, PaleTurquoise, LightGray, Wheat, NavajoWhite, Moccasin, LightPink, Gainsboro, PeachPuff, Pink, Bisque, LightGoldenrod, BlanchedAlmond, LemonChiffon, Beige, AntiqueWhite, PapayaWhip, Cornsilk, LightYellow, LightCyan, Linen, Lavender, MistyRose, OldLace, WhiteSmoke, Seashell, Ivory, Honeydew, AliceBlue, LavenderBlush, MintCream, Snow, White }; string arrayTitle[] = { "Black", "DarkGreen", "DarkSlateGray", "Olive", "Green", "Teal", "Navy", "Purple", "Maroon", "Indigo", "MidnightBlue", "DarkBlue", "DarkOliveGreen", "SaddleBrown", "ForestGreen", "OliveDrab", "SeaGreen", "DarkGoldenrod", "DarkSlateBlue", "Sienna", "MediumBlue", "Brown", "DarkTurquoise", "DimGray", "LightSeaGreen", "DarkViolet", "FireBrick", "MediumVioletRed", "MediumSeaGreen", "Chocolate", "Crimson", "SteelBlue", "Goldenrod", "MediumSpringGreen", "LawnGreen", "CadetBlue", "DarkOrchid", "YellowGreen", "LimeGreen", "OrangeRed", "DarkOrange", "Orange", "Gold", "Yellow", "Chartreuse", "Lime", "SpringGreen", "Aqua", "DeepSkyBlue", "Blue", "Magenta", "Red", "Gray", "SlateGray", "Peru", "BlueViolet", "LightSlateGray", "DeepPink", "MediumTurquoise", "DodgerBlue", "Turquoise", "RoyalBlue", "SlateBlue", "DarkKhaki", "IndianRed", "MediumOrchid", "GreenYellow", "MediumAquamarine", "DarkSeaGreen", "Tomato", "RosyBrown", "Orchid", "MediumPurple", "PaleVioletRed", "Coral", "CornflowerBlue", "DarkGray", "SandyBrown", "MediumSlateBlue", "Tan", "DarkSalmon", "BurlyWood", "HotPink", "Salmon", "Violet", "LightCoral", "SkyBlue", "LightSalmon", "Plum", "Khaki", "LightGreen", "Aquamarine", "Silver", "LightSkyBlue", "LightSteelBlue", "LightBlue", "PaleGreen", "Thistle", "PowderBlue", "PaleGoldenrod", "PaleTurquoise", "LightGray", "Wheat", "NavajoWhite", "Moccasin", "LightPink", "Gainsboro", "PeachPuff", "Pink", "Bisque", "LightGoldenrod", "BlanchedAlmond", "LemonChiffon", "Beige", "AntiqueWhite", "PapayaWhip", "Cornsilk", "LightYellow", "LightCyan", "Linen", "Lavender", "MistyRose", "OldLace", "WhiteSmoke", "Seashell", "Ivory", "Honeydew", "AliceBlue", "LavenderBlush", "MintCream", "Snow", "White" }; for(int loop = 0;loop < ArraySize(arrayTitle); loop++)if(title == arrayTitle[loop])return(arrayColors[loop]); return(CLR_NONE); } //+------------------------------------------------------------------+ //| EMMA Recount | //+------------------------------------------------------------------+ void recount(){ ArrayInitialize(EMMABuffer,0.0); flag_history = false; flag = false; ctrl = -1; save_Price = 0; ima = 0; home_Time = 0; position = 0; shift = 0; } //+------------------------------------------------------------------+ //| EMMA deinitialization function | //+------------------------------------------------------------------+ int deinit(){ if(ObjectFind("EMMA_FIBO") != -1)ObjectDelete("EMMA_FIBO"); if(ObjectFind("EMMA_FIBO_FAN") != -1)ObjectDelete("EMMA_FIBO_FAN"); if(ObjectFind("EMMA_Regression_Channel") != -1)ObjectDelete("EMMA_Regression_Channel"); if(ObjectFind("EMMA_StdDevChennel") != -1)ObjectDelete("EMMA_StdDevChennel"); if(ObjectFind("EMMA_TrafficLight") != -1)ObjectDelete("EMMA_TrafficLight"); } //+------------------------------------------------------------------+