//+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int BarsAmount=120; int TrendDirectionDefinition(string Symv, int tf, int begin_index) { if (tf != Period())if (Symv != Symbol() ) int start_bar = iBarShift(Symv, tf, // Определим индекс свечи на заданном Time[begin_index]);// ..таймфрейме, которая соответствует // ..свече №i текущего таймфрейма else // В противном случае начальный бар.. start_bar = begin_index; // ..будет равен бару begin_index double Y1 = 0, Y2 = 0; // Значения цен, соответствующие.. // ..правому и левому концам отрезка double deviation = CalcDeviation(tf, // Получим значение отклонения и цен.. start_bar, // ..концов отрезка start_bar+BarsAmount-1, Y1, Y2); if (deviation <= 0) // Если отклонение неположительно, то return(0); // ..возращаем ошибку if (Y1 > Y2) // Правое окончание отрезка выше.. return(1); // ..левого - тренд восходящий else // В противном случае тренд нисходящий return(-1); } bool trend_regressia(int open, string Symv, int TF){ BarsAmount=390*30; BarsAmount = BarsAmount / TF; if (open == TrendDirectionDefinition(Symv,TF, 1) ) { // Alert("Большая регрессия в противоположную сторону направлена "+Symv); return (true); } return (false); } double CalcDeviation(int tf, int bar1, int bar2, double &y1, double &y2) { // - 1 - == Инициализация переменных ==================================================== int N = bar2 - bar1 + 1; // Количество баров для расчета if (N <= 0) return(0); // Если количество баров не является.. // ..натуральным числом, то это ошибка double sumy = 0, // Сумма значений функции sumx = 0.0, // Сумма аргументов функции sumxy = 0.0, // Сумма произведения аргументов и.. // ..значений sumx2 = 0.0; // Сумма квадратов аргументов функции // - 1 - == Окончание блока ============================================================= // - 2 - == Нахождение необходимых сумм ================================================= for (int i = bar1; i <= bar2; i++) // С бара bar1 до бара с индексом bar2 { double _close = GetClose(tf, i); // Получим значение цены закрытия бара if (_close < 0) // Если не удалось получить цену, то.. return(-i); // ..вернем ошибку sumy += _close; // Суммируем значения функции sumxy += _close*i; // Сумма произведений аргументов и.. // ..значений функции sumx += i; // Сумма аргументов sumx2 += i*i; // Сумма квадратов аргументов } // - 2 - == Окончание блока ============================================================= // - 3 - == Вычисление коэффициентов К и В ============================================== double c = sumx2*N - sumx*sumx; // Знаменатель формулы нахождения.. // ..коэффициента k if (c == 0.0) return(0); // Знаменатель не может быть равен.. // ..нулю double K = (sumxy*N - sumx*sumy)/c; // Нахождение значения коэффициента K double B = (1.0/N)*(sumy - K*sumx); // Коэффициент B // - 3 - == Окончание блока ============================================================= // - 4 - == Определение величины максимального отклонения =============================== double max = 0; // Максимальное отклонение for (i = bar1; i <= bar2; i++) // Пройдем по всем участку баров { double Y = K*i + B; // Значение линии регрессии на баре i _close = GetClose(tf, i); // Получим значение цены закрытия бара // Проверка ошибки не требуется, т.к. // ..в предыдущем цикле ошибки не было max = MathMax(max, MathAbs(_close - Y)); // Рассчитываем отклонение цены.. // ..закрытия от линии и выбираем.. // ..максимальное } // - 4 - == Окончание блока ============================================================= // - 5 - == Расчет значений линии на крайних барах ====================================== y1 = K*bar1 + B; // Значение линии на баре bar1 y2 = K*bar2 + B; // Значение линии на баре bar2 // - 5 - == Окончание блока ============================================================= return(max); // Вернем величину отклонения } //+-------------------------------------------------------------------------------------+ //| Получение цены закрытия бара таймфрейма, отличного от текущего | //+-------------------------------------------------------------------------------------+ double GetClose(int tf, int index) { int cnt = 0; // Счетчик обращений к таймсерии while (cnt < 120) // Максимальное кол-во обращений - 120 { double res = iClose(NULL, tf, index); // Получаем цену закрытия нужного бара if (GetLastError() != 4066) // Если после обращения к таймсерии не break; // ..возникла ошибка "Запрошенные.. // ..исторические данные в состоянии.. // ..обновления", то выходим из цикла Comment("Ожидаются данные для бара ", index, " таймфрейма ", TFToString(tf), "..."); cnt++; // Иначе увеличиваем счетчик обращений Sleep(1000); // ..и делаем паузу в 1 сек } Comment(""); if (cnt < 120) // Если удалось получить данные, то.. return(res); // ..вернем содержимое res else // Иначе вернем ошибку return(-1); } //+-------------------------------------------------------------------------------------+ //| Преобразование численного значения периода графика в строку вида "M1" | //+-------------------------------------------------------------------------------------+ string TFToString(int tf) { switch (tf) { case PERIOD_M1: return("M1"); case PERIOD_M5: return("M5"); case PERIOD_M15: return("M15"); case PERIOD_M30: return("M30"); case PERIOD_H1: return("H1"); case PERIOD_H4: return("H4"); case PERIOD_D1: return("D1"); case PERIOD_W1: return("W1"); case PERIOD_MN1: return("MN1"); } return("таймфрейм не определен"); //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+