//+------------------------------------------------------------------+ //| MA_with_canal.mq4 | //| Copyright © 2009, Бугаев Даниил Владимирович | //| e-mail: buga1922@mail.ru | //+------------------------------------------------------------------+ #property copyright "Copyright © 2009, Бугаев Даниил Владимирович" #property link "mailto:buga1922@mail.ru" #property indicator_chart_window // Строим индикатор в главном окне #property indicator_buffers 3 // Количество используемых буферов = 3 #property indicator_color1 Red // Цвет 1-ой линии - красный #property indicator_color2 Red // Цвет 2-ой линии - красный #property indicator_color3 Red // Цвет 3-ей линии - красный #property indicator_width3 2 // Толщина третьей линии - 2 // Массивы для хранения значений индикатора double Buffer1[], Buffer2[], Buffer3[]; // Задаваемые пользователем переменные extern double ma_canal = 2; // Коэффициент используемый для рассчета ширины канала (ma_canal*средний_размер_свечи) extern int ma_period = 21, // Период для рассчета скользящей средней ma_method=3, // Метод рассчета средней 0-простая SMA, 1-экспотенциальная EMA, 2-сглаженная SMMA, // 3-линейно-взвешенная LWMA ma_cena=0; // Цены по которым строится МА 0-цена закрытия, 1-цена открытия, 2-максимальная, 3-минимальная, // 4-средняя, 5-типичная, 6-взвешенная цена закрытия // Переменные для отображения настроек индикатора string ma_method_str,ma_cena_str; //---ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ---// // Функция, помогающая вывести настройки индикатора void PARAMETRY() { switch(ma_method) { case 0: ma_method_str = "простая средняя (SMA)"; break; case 1: ma_method_str = "экспотенциальная средняя (EMA)"; break; case 2: ma_method_str = "сглаженная средняя (SMMA)"; break; case 3: ma_method_str = "линейно-взвешенная средняя (LWMA)"; break; default: ma_method_str = "введен некорректный параметр"; break; } switch(ma_cena) { case 0: ma_cena_str = "цена закрытия (PRICE_CLOSE)"; break; case 1: ma_cena_str = "цена открытия (PRICE_OPEN)"; break; case 2: ma_cena_str = "максимальная цена (PRICE_HIGH)"; break; case 3: ma_cena_str = "минимальная цена (PRICE_LOW)"; break; case 4: ma_cena_str = "средняя цена (PRICE_MEDIAN)"; break; case 5: ma_cena_str = "типичная цена (PRICE_TYPICAL)"; break; case 6: ma_cena_str = "взвешенная цена закрытия (PRICE_WEIGHTED)"; break; default: ma_cena_str = "введен некорректный параметр"; break; } } // Функция выполняет проверку на корректность введенных параметров, // в случае необходимости выводит ошибку. Возвращает true, если все параметры корректны. bool PROVERKA() { // Удаляем существующие сообщения об ошибке ObjectDelete("error"); ObjectDelete("advice"); return(true); // Производим проверку на наличие ошибок if ( ma_canal < 0) { VYVOD(": Измените параметр ma_canal.","Параметр должен быть положительным");return(false); } else { if ( ( ma_period < 0) || ( ma_period > Bars-2) ) { VYVOD(": Измените параметр ma_period.","Значение параметра должно принадлежать диапазону [0;"+(Bars-2)+"]");return(false); } else { if ( ( ma_method < 0) || ( ma_method > 3) ) { VYVOD(": Измените параметр ma_method.","Значение параметра должно принадлежать диапазону [0;3]");return(false); } else { if ( ( ma_cena < 0) || ( ma_cena > 6) ) { VYVOD(": Измените параметр ma_cena.","Значение параметра должно принадлежать диапазону [0;6]");return(false); } } } } } // Функция выводит информацию относительно некорректных параметрах индикатора void VYVOD(string error, string advice) { ObjectCreate ( "error", OBJ_LABEL,0,0,0); // Создаем метку, которая будет сообщать о // некорректных заданных параметрах ObjectSetText ( "error", "Индикатор MA_with_canal"+error,12,"Arial", Red); // Задаем текст метки об ошибке ObjectSet ( "error", OBJPROP_CORNER, 1); // Задаем угол привязки метки (правый верхний) ObjectSet ( "error", OBJPROP_XDISTANCE,15); // Задаем сдвиг относительно метки по горизонтали ObjectSet ( "error", OBJPROP_YDISTANCE,15); // Задаем сдвиг относительно метки по вертикали ObjectCreate ( "advice", OBJ_LABEL,0,0,0); // Создаем метку, которая будет сообщать рекомендации // о допустимом диапазоне параметров ObjectSetText ( "advice", advice,12,"Arial", Red); // Задаем текст метки с рекомендациями ObjectSet ( "advice", OBJPROP_CORNER, 1); // Задаем угол привязки метки (правый верхний) ObjectSet ( "advice", OBJPROP_XDISTANCE,15); // Задаем сдвиг относительно метки по горизонтали ObjectSet ( "advice", OBJPROP_YDISTANCE,40); // Задаем сдвиг относительно метки по вертикали } double canal(int lag) { int i; double sum=0; for (i=lag; i<=lag+ma_period; i++) sum=sum+(High[i]-Low[i]); return(sum/ma_period*ma_canal); } // Функция производит рассчет значений индикатора void RASSCHET() { double MA; int counted_bars = IndicatorCounted(); if(counted_bars < 0) return(-1); if(counted_bars > 0) counted_bars--; int bars = Bars - counted_bars; if(counted_bars==0) bars-=1+ma_period; while ( bars > 0 ) { MA=iMA(Symbol(),0,ma_period,0,ma_method,ma_cena,bars); Buffer1[bars]=( MA + canal(bars)); Buffer2[bars]=( MA - canal(bars)); Buffer3[bars]=MA; bars--; } } // Функция инициализации void init() { // Устанавливаем стиль отрисовки - простая линия,стиль линии - сплошная, для всех линий индикатора SetIndexStyle (0, DRAW_LINE, STYLE_SOLID); SetIndexStyle (1, DRAW_LINE, STYLE_SOLID); SetIndexStyle (2, DRAW_LINE, STYLE_SOLID); // Связываем массивы Buffer с буферами пользовательского индикатора SetIndexBuffer (0, Buffer1); SetIndexBuffer (1, Buffer2); SetIndexBuffer (2, Buffer3); // Задаем имя линий индикатора SetIndexLabel (0, "high_limit"); SetIndexLabel (1, "low_limit"); SetIndexLabel (2, "MA"); // Задаем короткое имя индикатора IndicatorShortName("MA_with_canal ("+ma_period+";"+ DoubleToStr(ma_canal,1)+")"); PARAMETRY(); // Определяем каким способом производится рассчет скользящей средней } // Функция деинициализации void deinit() { // Удаляем выведенные комментарии и сообщение об ошибке Comment(""); ObjectDelete("error"); ObjectDelete("advice"); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ void start() { if ( PROVERKA() == true) { RASSCHET(); } Comment("Индикатор MA_with_canal\nПериод скользящей средней="+ma_period+ "; Коэффициент для рассчета канала="+DoubleToStr(ma_canal,1)+ "\nДля рассчета МА использовалась "+ma_cena_str+ "\nМетод вычисления скользящей средней - "+ma_method_str+ "\nФактическая ширина канала="+DoubleToStr(canal(0),4)); } //+------------------------------------------------------------------+