//ZigZag2 #property indicator_chart_window #property indicator_buffers 4 #property indicator_color1 OrangeRed #property indicator_color3 Green #property indicator_color4 Red //---- input parameters extern int Q = 122; // Количество баров в расчетах. Расчет справа налево, от первого или нулевого бара. Если Q = 0, то // в расчетах будут использоваться все бары. extern int N = 2; // Минимальное количество ближайших баров справа от проверяемого бара и удовлетворяющих условию // быть ниже или выше проверяемого бара для образования фрактала. extern int Allowance = 4; // Сумма чисел Allowance и N показывает какое количество баров слева от проверяемого // бара имеющего индекс i будет проверяться на условие образование фрактала имеющего индекс i. // Это скорей подгоночный параметр так, как алгоритм расчета эталонного индикатора фракталов мне не известен. extern bool ShowFractals = false; // Показывать фракталы: ShowFractals >= true. extern bool UseZeroBar = false; // Использование нулевого бара в расчетах: UseZeroBar >= true. extern bool Show_6_Last_Ext_ZigZag = false; // Показать значения последних 6 экстремумов ZigZag и их индексы в комментариях: // Show_6_Last_Ext_ZigZag >= true. extern bool Show_6_Last_Fractals = false; // Показать значения последних 6 фракталов вверх и вниз и их индексы в комментариях: // Show_6_Last_Fractals >= true. extern int TurnEconomy = 1; // Производить расчеты количество раз = TurnEconomy, после открытия нового бара. extern int SpacePoints = 3; // Расстояние в пипсах между значком фрактала и экстремумом бара //================================================================================================================== double X[10000]; // Массив для значений максимумов зигзага, (число в квадратных скобках показывает размер масива, // или какое количество данных можно загрузить. Это число можно изменять) double Y[10000]; // Массив для значений минимумов зигзага int E[10000]; // Массив индексов для максимумов зигзага int F[10000]; // Массив индексов для минимумов зигзага double U[10000]; // Массив для значений фракталов вверх double D[10000]; // Массив для значений фракталов вниз int H[10000]; // Массив индексов для фракталов вверх int G[10000]; // Массив индексов для фракталов вниз double Buffer0[]; double Buffer1[]; double Buffer2[]; double Buffer3[]; datetime Newtime; double points; int k; int re; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int init() { //---- indicators IndicatorBuffers( 4 ); IndicatorDigits( Digits ); SetIndexBuffer( 0, Buffer0 ); SetIndexStyle( 0, DRAW_ZIGZAG ); SetIndexBuffer( 1, Buffer1 ); SetIndexStyle( 1, DRAW_ZIGZAG ); SetIndexBuffer( 2, Buffer2 ); SetIndexStyle( 2,DRAW_ARROW ); SetIndexArrow( 2,217 ); SetIndexBuffer( 3, Buffer3 ); SetIndexStyle( 3,DRAW_ARROW ); SetIndexArrow( 3,218 ); //---- name for DataWindow and indicator subwindow label IndicatorShortName( "ZigZag2" ); SetIndexLabel( 2, "Fractal Up" ); SetIndexLabel( 3, "Fractal Down" ); if ( UseZeroBar == true ) k = 1; if ( Q > Bars || Q == 0 ) Q = Bars; points = SpacePoints * Point; //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int start() { //---- datetime time = Time[0]; if ( Newtime == time && TurnEconomy < re ) return(0); if ( Newtime != time ) re = 1; re++; // счетчик тиков для условия TurnEconomy < re Newtime = time; int c = 2; int limit, e, f, w, u, q1, v1; double s, g; int counted_bars = IndicatorCounted( ); //---- последний посчитанный бар будет пересчитан if ( counted_bars > 0 ) counted_bars--; limit = Q-counted_bars-1; //---- основной цикл int i = N + 1 - k; for ( i = i; i < limit; i++ ) { Buffer0[i] = EMPTY_VALUE; // заполняем пустотой Buffer1[i] = EMPTY_VALUE; Buffer2[i] = EMPTY_VALUE; Buffer3[i] = EMPTY_VALUE; double high = High[i]; double low = Low[i]; int q = 0; int v = 0; int b1 = 0; int b2 = 0; int b3 = 0; int b4 = 0; int c1 = 0; int c2 = 0; //-------------------------------------- Исследуем бары справа от проверяемого на данный момент бара и имеющий индекс равный i for ( int z = 1; z < N + 1; z++ ) { //---------для фракталов вверх if ( high > High[i - z] ) // если максимум правого бара ниже проверяемого бара, { q++; // то включим счетчик баров правее от проверяемого бара имеющие максимумы ниже чем максимум проверяемого бара if ( q == N ) // если q = N то сохраним на память об этом придав c1 значение 1 необходимого для { // условия if ( b1 == 0 && b2 == 0 && c1 == 1 ) начала поиска баров левее от проверяемого и которые c1 = 1; // имеют максимумы ниже максимума проверяемого бара с индексом i } } else // еще вариант { if ( high <= High[i - z] ) // если до нарушения условия z < N + 1 в цикле for ( int z = 1; z < N + 1; z++ ) какой нибудь { // из правых баров имеющий индекс i-z выше или равен максимуму проверяемого бара имеющего индекс i q = N + 1; // то добавим к переменной q некоторое число единиц для того чтобы условие if ( q == N ) ,а вместе } // с ним и условие if ( b1 == 0 && b2 == 0 && c1 == 1 ) никогда не были выполнены до следующего проверяемого } // бара задаваемого циклом for ( i = i; i < limit; i++ ) //---------для фракталов вниз if ( low < Low[i - z] ) // если минимум правого бара выше проверяемого бара, { v++; // то включим счетчик баров правее от проверяемого бара имеющие минимумы выше чем минимум проверяемого бара if ( v == N ) // если v = N, то сохраним на память об этом придав c2 значение 1 необходимого для { // условия if ( b3 == 0 && b4 == 0 && c2 == 1 ) начала поиска баров левее от проверяемого и которые c2 = 1; // имеют минимумы выше минимума проверяемого бара с индексом i } } else // еще вариант { if ( low >= Low[i - z] ) // если до нарушения условия z < N + 1 в цикле for ( int z = 1; z < N + 1; z++ ) какой нибудь { // из правых баров имеющий индекс i-z ниже или равен минимуму проверяемого бара имеющего индекс i v = N + 1; // то добавим к переменной q некоторое число единиц для того чтобы условие if ( v == N ),а вместе } // с ним и условие if ( b3 == 0 && b4 == 0 && c2 == 1 ) никогда не были выполнены до следующего проверяемого } // бара задаваемого циклом for ( i = i; i < limit; i++ ) } // закрывающая скобка для цикла for ( int z = 1; z < N + 1; z++ ) //-------------------------------- Теперь исследуем бары слева от проверяемого на данный момент бара и имеющий индекс равный i q = 0; // подготовим переменные q и v для цикла for ( z = 1; z < N + 1 + Allowance; z++ ) обнулив их v = 0; for ( z = 1; z < N + 1 + Allowance; z++ ) { if ( b1 == 0 && b2 == 0 && c1 == 1 ) // При сохранении этого условия поиск левых баров имеющих максимумы ниже чем { // максимум проверяемого бара с индексом i будет продолжаться if ( high > High[i + z] ) { q++; // счетчик левых баров у которых максимумы ниже максимума проверяемого бара if ( q == N ) { if ( ShowFractals == true || Show_6_Last_Fractals == true ) { q1++; // счетчик фракталов вверх U[q1] = high; // массив значений фракталов вверх H[q1] = i; // массив индексов для фракталов вверх Buffer2[i] = high + points; //если q = N , то очередной фрактал вверх найден и имеет индекс i и тогда } // прекратим поиск до следующего проверяемого бара задаваемым циклом for ( i = i; i < limit; i++ ) b1 = 1; //нарушив условие if ( b1 == 0 && b2 == 0 && c1 == 1 ) добавив к b1 единицу //===================================================== Поиск очередного миксимума ZigZag, или блок зигзага if ( c != 0 ) // если образовался минимум зигзага когда с = 1 и когда достигнуто условие if ( q == N ) { // или b1 = 1, то есть появился новый фрактал вверх, то идентифицируем этот фрактал пока // как временный максимума зигзага, e = i; s = high; Buffer0[e] = high; // помещаяя значение этого фрактала в буфер Buffer0[i] индикатора и массив X[] w++; X[w] = high; E[w] = i; // а также кладем индекс бара соответствующему этому фракталу в массив E[] } if ( c == 0 && s < high ) // если свежий фрактал выше последнего максимума зигзага и между { // ними нет минимума зигзага когда с = 0 то Buffer0[e] = EMPTY_VALUE; // удалим значение последнего максимума из буфера Buffer0[e] s = high; // соответствующее последнему индексу е заменив его пустым значением e = i; Buffer0[i] = high; // в обмен на новое значение фрактала соответствующему текущему индексу i X[w] = high; // не забыв при этом поместить это знчение в массив X[] максимумов зигзага E[w] = i; // а также не забыв поместить индекс нового фрактала в массив E[] } c = 0; // теперь ждем колена зигзага вниз нарушив условие if ( c != 0 ) //================================================================ Граница поиска очередного максимума ZigZag. } // закрывающая скобка для условия if ( q == N ) } // закрывающая скобка для условия if ( high > High[i + z] ) else // еще вариант { if ( high < High[i + z] ) // если максимум проверяемого бара ниже максимума бара рассположенного левее { // от проверяемого бара,то прекратим просмотр влево до следующего проверяемого бара b2 = 1; //задаваемым циклом for( i = i; i < limit; i++ ) нарушив условие if ( b1 == 0 && b2 == 0 && c1 == 1 ) } // добавив к b2 единицу } if ( high == High[i + z] ) // если максимумы ближайшего бара слева и проверяемого бара имеющего индекс i { // равны, то q = 0; // сбросим на 0 счетчик q++ для последнего условия нахождения фрактала вверх if ( q == N ) } // и начнем считать заново до тех пор пока сохраняется условие z < N + 1 + Allowance // в цикле for ( z = 1; z < N + 1 + Allowance; z++ ) } // закрывающая скобка для условия if ( b1 == 0 && b2 == 0 && c1 == 1 ) //--------------------------------------------------------------------- Поиск фракталов вниз. if ( b3 == 0 && b4 == 0 && c2 == 1 ) // При сохранении этого условия поиск левых баров имеющих минимумы выше чем { // минимум проверяемого бара с индексом i будет продолжаться if ( low < Low[i + z] ) { v++; // счетчик левых баров у которых минимумы выше минимума проверяемого бара if ( v == N ) { if ( ShowFractals == true || Show_6_Last_Fractals == true ) { v1++; // счетчик фракталов вниз D[v1] = low; // массив значений фракталов вниз G[v1] = i; // массив индексов для фракталов вниз Buffer3[i] = low - points; // если v = N , то очередной фрактал вниз найден и имеет индекс i и тогда } // прекратим поиск до следующего проверяемого бара задаваемым циклом for ( i = i; i < limit; i++ ) b3 = 1; //нарушив условие ( b3 == 0 && b4 == 0 && c2 == 1 ) добавив к b3 единицу //======================================================================= Поиск очередного минимума ZigZag if ( c != 1 )// если образовался максимум зигзага когда с = 0 и когда достигнуто условие if ( v == N ) { // или b3 = 1, то есть появился новый фрактал вниз, то идентифицируем этот фрактал пока // как временный минимум зигзага, f = i; g = low; Buffer1[i] = low; // помещаяя значение этого фрактала в буфер Buffer1[i] индикатора и массив Y[] u++; Y[u] = low; F[u] = i; // а также кладем индекс бара соответствующему этому фракталу в массив F[] } if ( c == 1 && g > low ) // если свежий фрактал ниже последнего минимума зигзага и между { // ними нет максимума зигзага когда c = 0, то Buffer1[f] = EMPTY_VALUE; // удалим значение последнего минимума из буфера Buffer1[f] g = low; // соответствующее последнему индексу f заменив его пустым значением f = i; Buffer1[i] = low; // в обмен на новое значение фрактала соответствующему текущему индексу i Y[u] = low; // не забыв при этом поместить это знчение в массив Y[] минимумов зигзага F[u] = i; // а также не забыв поместить индекс нового фрактала в массив F[] } c = 1; // теперь ждем колена зигзага вверх нарушив условие if ( c != 1 ) //===================================================================== Граница поиска очередного минимума ZigZag } // закрывающая скобка для условия if ( v == N ) } // закрывающая скобка для условия if ( low < Low[i + z] ) else // еще вариант { if ( low > Low[i + z] ) // если минимум проверяемого бара выше минимума бара рассположенного левее { // от проверяемого бара,то прекратим просмотр влево до следующего проверяемого бара b4 = 1; //задаваемым циклом for( i = i; i < limit; i++ ) нарушив условие if ( b3 == 0 && b4 == 0 && c2 == 1 ) } // добавив к b4 единицу } if ( low == Low[i + z] ) // если минимумы ближайшего бара слева и проверяемого бара имеющего индекс i { // равны, то v = 0; // сбросим на 0 счетчик v++ для последнего условия нахождения фрактала вниз if ( v == N ) } // и начнем считать заново до тех пор пока сохраняется условие z < N + 1 + Allowance // в цикле for ( z = 1; z < N + 1 + Allowance; z++ ) } // закрывающая скобка для условия if ( b3 == 0 && b4 == 0 && c2 == 1 ) if ( b1 == 1 && b2 == 1 && b3 == 1 && b4 == 1 ) { break; // обрыв цикла for ( z = 1; z < N + 1 + Allowance; z++ ) } } // закрывающая скобка для цикла for ( z = 1; z < N + 1 + Allowance; z++ ) } // закрывающая скобка для цикла for ( i = i; i < limit; i++ ) //---------------------------------------------------------------------------------------------- Комментарии string text = " "; if ( Show_6_Last_Ext_ZigZag == true ) { text = StringConcatenate( " ZigZag Maxs: ",X[1]," [ "+E[1]+" ] ", X[2]," [ "+E[2]+" ] ", X[3]," [ "+E[3]+" ] ",X[4]," [ "+E[4]+" ] ",X[5]," [ "+E[5]+" ] ",X[6], " [ "+E[6]+" ]", "\n\n ZigZag Mins: ",Y[1]," [ "+F[1]+" ] ", Y[2]," [ "+F[2]+" ] ", Y[3]," [ "+F[3]+" ] ",Y[4]," [ "+F[4]+" ] ",Y[5]," [ "+F[5]+" ] ",Y[6], " [ "+F[6]+" ] " ); } else { if ( Show_6_Last_Fractals == true ) { text = StringConcatenate( " Fractals Up: ",U[1]," [ "+H[1]+" ] ", U[2]," [ "+H[2]+" ] ", U[3]," [ "+H[3]+" ] ",U[4]," [ "+H[4]+" ] ",U[5]," [ "+H[5]+" ] ",U[6], " [ "+H[6]+" ]", "\n\n Fractals Down: ",D[1]," [ "+G[1]+" ] ", D[2]," [ "+G[2]+" ] ", D[3]," [ "+G[3]+" ] ",D[4]," [ "+G[4]+" ] ",D[5]," [ "+G[5]+" ] ",D[6], " [ "+G[6]+" ] " ); } } Comment( text ); return(0); } //+------------------------------------------------------------------+