//+---------------------------------------------------------------------+ //| Gliding Channels [CF].mq4 | //| Crazy_Fox [UA] | //| e-mail: crazy_fox@ua.fm | //| ICQ: 529330 | //| ДЛЯ НЕКОММЕРЧЕСКОГО ИСПОЛЬЗОВАНИЯ, ПУБЛИКАЦИЯ РАЗРЕШЕНА ТОЛЬКО С | //| УКАЗАНИЕМ ПЕРВОИСТОЧНИКА (http://www.community.finlist.org) | //| И ИМЕНИ АВТОРА (Crazy_Fox [UA]) | //| РЕДАКТИРОВАНИЕ ИСХОДНОГО КОДА РАЗРЕШАЕТСЯ ТОЛЬКО ПРИ УСЛОВИИ | //| СОХРАНЕНИЯ ДАННОГО ТЕКСТА, АДРЕСОВ И ССЫЛОК. ПРОДАЖА, ИНДИКАТОРА, | //| ОТДЕЛЬНЫХ ЧАСТЕЙ ИСХОДНОГО КОДА, ГРАФИКОВ, ИМ ПОСТРОЕННЫХ ЗАПРЕЩЕНА | //| АВТОР НЕ НЕСЁТ ОТВЕТСТВЕННОСТИ ЗА ВОЗМОЖНЫЕ УБЫТКИ, ПОЛУЧЕННЫЕ | //| В РЕЗУЛЬТАТЕ РАБОТЫ ИНДИКАТОРА | //| Скользящие каналы Баришпольца | //| Каналы строятся по трем последним экстремумам - линия по двум | //| низам и параллельная через вершину, или наоборот, линия по двум | //| вершинам и параллельная по низу. Линии строятся ПО МАКСИМАЛЬНЫМ | //| (МИНИМАЛЬНЫМ) ЗНАЧЕНИЯМ, то есть по теням свечей. Экстремум | //| идентифицируется при не менее 2 свечек до и 2 свечек после его | //| прохождения. То есть для максимума необходимо не менее 2 свечек | //| меньше максимальной свечи до, и не менее 2 свечек меньше максимума | //| - после. Расстояние между соседними экстремумами не ограничивается. | //| Встречаются "групповые экстремумы" - две или даже три свечи с | //| практически одинаковыми максимумами (минимумами). Идентифицируем их | //| как один экстремум, линию канала проводим через верх (низ) правой | //| из них. | //+---------------------------------------------------------------------+ #property copyright "Crazy_Fox [UA]" #property link "http://finlist.ru" #property indicator_chart_window //---- extern int Start_Bar = 2; extern int Line_Width = 2; extern int Num_of_Channels = 1; extern int Sensitivity = 0; extern bool Show_Labels = true; extern bool Channel_as_Ray = true; extern bool Show_Alerts = true; extern color Channel_Color1 = Blue; extern color Channel_Color2 = LightSkyBlue; extern color Channel_Color3 = DeepPink; extern color Channel_Color4 = DodgerBlue; extern color Channel_Color5 = PaleGreen; extern color Channel_Color6 = DarkOrange; extern color Channel_Color7 = DodgerBlue; extern color Channel_Color8 = Yellow; //---- double x1 = 0, y1 = 0, x2 = 0, y2 = 0, x_l = 0, y_l = 0, x_f = 0, y_f = 0, x_m = 0, y_m = 0, step = 0, l_border = 0, h_border=0, Price = 0; bool main_is_up = true, price_at_border = false; int CurrentBar = 0, Extremum[3], TempExtremum[3], Colors[8], f_bar = 0, m_bar = 0, l_bar = 0; //+------------------------------------------------------------------+ //| init | //+------------------------------------------------------------------+ int init() { Colors[0] = Channel_Color1; Colors[1] = Channel_Color2; Colors[2] = Channel_Color3; Colors[3] = Channel_Color4; Colors[4] = Channel_Color5; Colors[5] = Channel_Color6; Colors[6] = Channel_Color7; Colors[7] = Channel_Color8; ArrayInitialize(Extremum, 0); ArrayInitialize(TempExtremum, 0); return(0); } //+------------------------------------------------------------------+ //| deinit | //+------------------------------------------------------------------+ int deinit() { // В цикле удаляем все отрисованные объекты for (int i = 1; i <= Num_of_Channels; i++) { ObjectDelete("Channel_"+i); if(Show_Labels) { ObjectDelete("Extremum_1_" + i); ObjectDelete("Extremum_2_" + i); ObjectDelete("Extremum_3_" + i); } } Comment(" "); ArrayInitialize(Extremum, 0); ArrayInitialize(TempExtremum, 0); return(0); } //+------------------------------------------------------------------+ //| min_ext | //+------------------------------------------------------------------+ int min_ext(int bar) { int find, i, result; result = 0; i = bar; find = 0; while(find != 1) { if((Low[i-2] >= Low[i]) && (Low[i-1] >= Low[i]) && (Low[i] <= Low[i+1]) && (Low[i] <= Low[i+2])) { // Если i меньше либо равно двум близстоящим свечам и соседям этих свечей - // это наш минимум result=i; find++; } i++; } return(result); } //+------------------------------------------------------------------+ //| max_ext | //+------------------------------------------------------------------+ int max_ext(int bar) { int find, i, result; result = 0; i = bar; find = 0; while(find != 1) { if((High[i-2] <= High[i]) && (High[i-1] <= High[i]) && (High[i] >= High[i+1]) && (High[i] >= High[i+2])) { // Если i больше либо равно двум близстоящим свечам и соседям этих свечей - // это наш максимум result=i; find++; } i++; } return(result); } //+------------------------------------------------------------------+ //| find_extremums | //+------------------------------------------------------------------+ void find_extremums(int i) { ArrayInitialize(Extremum, 0); // Ищем первый минимум, определяем координаты Extremum[0] = min_ext(i); y1=Low[Extremum[0]]; x1=Time[Extremum[0]]; // Ищем первый максимум, определяем координаты Extremum[1] = max_ext(i); y2=High[Extremum[1]]; x2=Time[Extremum[1]]; // Если минимум встречается раньше максимума - третья экстремум ищем внизу if(Extremum[0] < Extremum[1]) { // Функция min_ext возвращает номер первого минимума, поиск начинается с Extremum[2] = min_ext(Extremum[1]); y_l = Low[Extremum[2]]; x_l = Time[Extremum[2]]; y_f = y1; x_f = x1; y_m = y2; x_m = x2; f_bar = Extremum[0]; m_bar = Extremum[1]; l_bar = Extremum[2]; main_is_up = false; } if(Extremum[0] > Extremum[1]) { Extremum[2] = max_ext(Extremum[0]); y_l = High[Extremum[2]]; x_l = Time[Extremum[2]]; y_f = y2; x_f = x2; y_m = y1; x_m = x1; f_bar = Extremum[1]; m_bar = Extremum[0]; l_bar = Extremum[2]; main_is_up = true; } if(Extremum[0] == Extremum[1]) if(min_ext(Extremum[0] + 1) < max_ext(Extremum[0] + 2)) { Extremum[2] = min_ext(Extremum[0] + 2); y_l = Low[Extremum[2]]; x_l = Time[Extremum[2]]; y_f = y1; x_f = x1; y_m = y2; x_m = x2; f_bar =Extremum[0]; m_bar = Extremum[1]; l_bar = Extremum[2]; main_is_up = false; } else { Extremum[2] = max_ext(Extremum[0] + 2); y_l = High[Extremum[2]]; x_l = Time[Extremum[2]]; y_f = y2; x_f = x2; y_m = y1; x_m = x1; f_bar = Extremum[0]; m_bar = Extremum[1]; l_bar = Extremum[2]; main_is_up = true; } } //+------------------------------------------------------------------+ //| indicator start function | //+------------------------------------------------------------------+ int start() { int n = 1, c = 0, i = 0; // Счётчик каналов и счётчик цветов if(Start_Bar > 0) CurrentBar = Start_Bar; else CurrentBar = 2; //Текущий бар - 2 (для подтверждения экстремума) ArrayInitialize(TempExtremum, 0); find_extremums(CurrentBar); // На сколько изменяется цена с каждой последующей свечёй step = (y_f - y_l) / (l_bar - f_bar); if(main_is_up) { h_border = High[f_bar] + step*f_bar; l_border = Low [m_bar] + step*m_bar; } else { l_border = Low [f_bar] + step*f_bar; h_border = High[m_bar] + step*m_bar; } // Если достигли верхней границы канала if((Bid >= (h_border - Sensitivity*Point)) && (Bid <= (h_border + Sensitivity*Point))) { if(Show_Alerts) Alert("Верх канала - продажа."); } // Если достигли нижней границы канала if((Ask <= (l_border + Sensitivity*Point)) && (Ask >= (l_border - Sensitivity*Point))) { if(Show_Alerts) Alert("Низ канала - покупка"); } deinit(); Comment("Параметры канала:\nШирина = ", (h_border - l_border) / Point, "; Наклон = ", -step / Point, ";\nВерхняя граница = ", DoubleToStr(h_border, Digits), "; Нижняя граница = ", DoubleToStr(l_border, Digits), ";"); // В цикле от 1 до Num_of_Channels расчитываем экстремумы и рисуем канал с номером N while(n <= Num_of_Channels) { TempExtremum[0] = Extremum[0]; TempExtremum[1] = Extremum[1]; TempExtremum[2] = Extremum[2]; find_extremums(CurrentBar); if((TempExtremum[0] == Extremum[0]) && (TempExtremum[1] == Extremum[1]) && (TempExtremum[2] == Extremum[2])) CurrentBar++; else { //SetIndexStyle(0, DRAW_ARROW); //SetIndexArrow(0, 164); //SetIndexBuffer(0, ExtMapBuffer); //SetIndexEmptyValue(0, 0.0); if(Show_Labels) { ObjectCreate("Extremum_1_" + n, OBJ_ARROW, 0, x1, y1); ObjectSet("Extremum_1_" + n, OBJPROP_COLOR, Colors[c]); ObjectSet("Extremum_1_" + n, OBJPROP_WIDTH, 1); ObjectSet("Extremum_1_" + n, OBJPROP_ARROWCODE, SYMBOL_LEFTPRICE); ObjectSet("Extremum_1_" + n, OBJPROP_STYLE, STYLE_SOLID); ObjectCreate("Extremum_2_" + n, OBJ_ARROW, 0, x2, y2); ObjectSet("Extremum_2_" + n, OBJPROP_COLOR, Colors[c]); ObjectSet("Extremum_2_" + n, OBJPROP_WIDTH, 1); ObjectSet("Extremum_2_" + n, OBJPROP_ARROWCODE, SYMBOL_LEFTPRICE); ObjectSet("Extremum_2_" + n, OBJPROP_STYLE, STYLE_SOLID); ObjectCreate("Extremum_3_" + n, OBJ_ARROW, 0, x_l, y_l); ObjectSet("Extremum_3_" + n, OBJPROP_COLOR, Colors[c]); ObjectSet("Extremum_3_" + n, OBJPROP_WIDTH, 1); ObjectSet("Extremum_3_" + n, OBJPROP_ARROWCODE, SYMBOL_RIGHTPRICE); ObjectSet("Extremum_3_" + n, OBJPROP_STYLE, STYLE_SOLID); } ObjectCreate("Channel_" + n, OBJ_CHANNEL, 0, x_l, y_l, x_f, y_f, x_m, y_m); ObjectSet("Channel_" + n, OBJPROP_COLOR, Colors[c]); ObjectSet("Channel_" + n, OBJPROP_WIDTH, Line_Width); ObjectSet("Channel_" + n, OBJPROP_RAY, Channel_as_Ray); ObjectSet("Channel_" + n, OBJPROP_STYLE, STYLE_SOLID); n++; if(c < 7) c++; else c=0; } CurrentBar++; } return(0); } //+------------------------------------------------------------------+