azzx_larry6





// ---------------------------------------------------------------------------
//  Ïîèñê ýêñòðåìóìîâ ïî Ëàððè Âèëüÿìñó
//
//  Îïèñàíèå ïàðàìåòðîâ:
//
//   LimitForShowLabel - Ìèíèìàëüíûé óðîâåíü îòîáðàæåíèÿ ìåòîê
//   MinimalLineLevel  - Ìèíèìàëüíûé óðîâåíü äëÿ ëèíèé çèãçàãà
//   MaximalLineLevel  - Ìàêñèìàëüíûé óðîâåíü äëÿ ëèíèé çàèãçàãà
//   OptimizeZigZag    - Îïòèìèçàöèÿ çèãçàãà 
//                       (óáèðàåì ïîäðÿä èäóùèå ìèíèìóìû èëè ìàêñèìóìû)
//   ColorMaximum      - Öâåò ìåòîê ìàêñèìóìîâ
//   ColorMinimum      - Öâåò ìåòîê ìèíèìóìîâ
//   ColorLines        - Öâåò ëèíèé çèãçàãà
//   OffsetForMaximums - Ñìåùåíèå ìåòîê äëÿ ìàêñèìóìîâ â ïóíêòàõ
//   OffsetForMinimums - Ñìåùåíèå ìåòîê äëÿ ìèíèìóìîâ â ïóíêòàõ
//
//  Âåðñèÿ 2 - Äîáàâëåíî ïîñòðîåíèå ëèíèé çèãçàãà ïî íàéäåííûì ýêñòðåìóìàì
//  Âåðñèÿ 3 - Ïàðàìåòð îãðàíè÷åíèÿ îòðèñîâêè ëèíèé çèãçàãà íàìåðÿííî 
//             çàäðàí - îí îñîáî è íå íóæåí â áîëüøèíñòâå ñëó÷àåâ. 
//             Äîïîëíèòåëüíî äîáàâëåí ïîëåçíûé ôëàã - îòðèñîâêà òîëüêî
//             ïåðâîãî óðîâíÿ ýêñòðåìóìîâ.
//             Ââåäåíà ìîäèôèêàöèÿ â àëãîðèòì - ò.ê. îáíàðóæèëîñü, ÷òî ÷àñòî
//             âñòðå÷àåòñÿ òàêîé îñîáûé ñëó÷àé - ýêñòðåìóì âûäåëÿåòñÿ, äàæå
//             åñëè ñ îäíîé ñòîðîíû ïðåäûäóùèé ýêñòðåìóì òàêîãî æå óðîâíÿ
//             ìåíüøå, à ñ äðóãîé - áîëüøå èëè ÐÀÂÅÍ òåêóùåìó (ñðàáàòûâàíèå
//             ïî ôðîíòó).
//  Âåðñèÿ 4 - Èç ïîñòðîåíèÿ çèãçàãîâ èñêëþ÷åíû ñëó÷àè òèïà "äâà ìàêñèìóìà,
//             èäóùèå ïîäðÿä". Èñïðàâëåíà îøèáêà ñ âûäåëåíèåì ýêñòðåìóìà,
//             ïîòåíöèàëüíî ñïîñîáíàÿ ïðèâîäèòü ê áåñêîíå÷íîìó öèêëó.
//  Âåðñèÿ 5 - Èñïðàâëåíà ëîãè÷åñêàÿ îøèáêà, äàþùàÿ íåâåðíûé ðåçóëüòàò â
//             ðåäêîì êðàåâîì ñëó÷àå. Ââåäåíû áîëåå ëîãè÷íûå ïàðàìåòðû.
//             Óëó÷øåí îïòèìèçàòîð ëèíèé çèãçàãà.
//  Âåðñèÿ 6 - Èñïðàâëåíà îøèáêà ñ ïîðÿäêîì îòðèñîâêè ëèíèé èçãçàãà. Èç-çà
//             ýòîãî ìîãëè "âûïàñòü" íåêîòîðûå ýêñòðåìóìû.
// ---------------------------------------------------------------------------

#property show_inputs

#define PREFIX_TEXT "t_"
#define PREFIX_LINE "l_"
#define FONT_SIZE    10

extern int   LimitForShowLabel = 1;
extern int   MinimalLineLevel  = 1;
extern int   MaximalLineLevel  = 1;
extern bool  OptimizeZigZag    = true;
extern color ColorMaximum      = C'0,255,0';
extern color ColorMinimum      = C'255,0,0';
extern color ColorLines        = C'255,255,255';
extern int   OffsetForMaximums = 150;
extern int   OffsetForMinimums = 10;

int maximum[], minimum[];

// Èíèöèàëèçàöèÿ
int init() {
  // Ðàçìåðû è ñîäåðæèìîå ìàññèâîâ
  ArrayResize(maximum, Bars);
  ArrayResize(minimum, Bars);
  
  ArrayInitialize(maximum, 0);
  ArrayInitialize(minimum, 0);
  
  // Óäàëåíèå ñòàðûõ îòìåòîê
  ObjectsDeleteAll(0, OBJ_TEXT);
  ObjectsDeleteAll(0, OBJ_TREND);

  return(0);
}

// Òî÷êà âõîäà
int start() {
  int i = 1;
  
  while(pass(i)) i++;
  
  draw_result(i - 1);

  return(0);
}

// Ïðîõîä ïî óðîâíþ
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ýêñòðåìóìû çàäàííîãî óðîâíÿ
bool pass(int level) {
  return(pass_maximum(level) || pass_minimum(level));
}

// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñëåâà
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî
double find_left_maximum(int bar) {
  int i, level = maximum[bar];
  
  for(i = bar + 1; i < Bars; i++) {
    if(maximum[i] >= level) {
      return(High[i]);
    }
  }

  // Äîøëè äî êîíöà èñòîðèè
  return(High[bar] + 1);
}

// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìàêñèìóìà ñïðàâà
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî áîëüøîå ÷èñëî
double find_right_maximum(int bar) {
  int i, level = maximum[bar];
  
  for(i = bar - 1; i >= 0; i--) {
    if(maximum[i] >= level) {
      return(High[i]);
    }
  }

  // Äîøëè äî íà÷àëà èñòîðèè
  return(High[bar] + 1);
}

// Ïðîõîä ïî ìàêñèìóìàì äëÿ óðîâíÿ
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìàêñèìóìû
bool pass_maximum(int level) {
  int i, limit = Bars - 2, prev = level - 1, result = false;
  
  for(i = 1; i < limit; i++) {
    if(maximum[i] == prev) {
      double l = find_left_maximum(i);
      double r = find_right_maximum(i);
    
      if((l <= High[i] && r < High[i]) || (l < High[i] && r <= High[i])) {
        maximum[i] = level;
        result     = true;
      }
    }
  }

  return(result);
}

// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñëåâà
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî
double find_left_minimum(int bar) {
  int i, level = minimum[bar];
  
  for(i = bar + 1; i < Bars; i++) {
    if(minimum[i] >= level) {
      return(Low[i]);
    }
  }

  // Äîøëè äî êîíöà èñòîðèè
  return(Low[bar] - 1);
}

// Ïîèñê ìåíüøåãî èëè ðàâíîãî ìèíèìóìà ñïðàâà
//  ñëó÷àå íåóäà÷è âîçâðàùàåò çàâåäîìî ìåíüøåå ÷èñëî
double find_right_minimum(int bar) {
  int i, level = minimum[bar];
  
  for(i = bar - 1; i >= 0; i--) {
    if(minimum[i] >= level) {
      return(Low[i]);
    }
  }

  // Äîøëè äî íà÷àëà èñòîðèè
  return(Low[bar] - 1);
}

// Ïðîõîä ïî ìèíèìóìàì äëÿ óðîâíÿ
// Âîçâðàùàåò true, åñëè áûëè íàéäåíû ìèíèìóìû
bool pass_minimum(int level) {
  int i, limit = Bars - 2, prev = level - 1, result = false;
  
  for(i = 1; i < limit; i++) {
    if(minimum[i] == prev) {
      double l = find_left_minimum(i);
      double r = find_right_minimum(i);
    
      if((l >= Low[i] && r > Low[i]) || (l > Low[i] && r >= Low[i])) {
        minimum[i] = level;
        result     = true;
      }
    }
  }

  return(result);
}

// Îïòèìèçàöèÿ ìèíèìóìîâ
void optimize_minimums(int bar, int level) {
  int i;
  
  for(i = bar + 1; i < Bars; i++) {
    if(minimum[i] >= level) {
      if(Low[i] < Low[bar]) {
        minimum[bar] = 0;
      } else {
        minimum[i]   = 0;
      }
      
      break;
    }
  }
}

// Îïòèìèçàöèÿ ìàêñèìóìîâ
void optimize_maximums(int bar, int level) {
  int i;
  
  for(i = bar + 1; i < Bars; i++) {
    if(maximum[i] >= level) {
      if(High[i] > High[bar]) {
        maximum[bar] = 0;
      } else {
        maximum[i]   = 0;
      }
      
      break;
    }
  }
}

// Îïòèìèçàöèÿ çèãçàãà äëÿ çàäàííîãî óðîâíÿ
void optimize_level(int level) {
  int i, j = 0;
    
  for(i = Bars - 1; i >= 0; i--) {
    if(maximum[i] >= level) {
      if(j == 1) {
        optimize_maximums(i, level);
      } else {
        j = 1;
      }
    }
      
    if(minimum[i] >= level) {
      if(j == -1) {
        optimize_minimums(i, level);
      } else {
        j = -1;
      }
    }
  }
}

// Ïîñòðîåíèå îòäåëüíîé ëèíèè
void build_line(int level, int bar_to, 
  datetime time_from, double price_from, datetime time_to, double price_to) {

  string n = StringConcatenate(PREFIX_LINE, level, "_", bar_to);

  ObjectCreate(n, OBJ_TREND, 0, time_from, price_from, time_to, price_to);
  ObjectSet(n, OBJPROP_COLOR, ColorLines);
  ObjectSet(n, OBJPROP_RAY,   0);  
}

// Îòðèñîâêà ðåçóëüòàòîâ
// Ïîëó÷àåìûé ïàðàìåòð - íîìåð ïîñëåäíåãî íàéäåííîãî óðîâíÿ
void draw_result(int last_level) {
  int      i, j, k;
  string   n;
  double   prev_price;
  datetime prev_time;
  
  // Îòðèñîâêà öèôð óðîâíåé
  for(i = 0; i < Bars; i++) {
    if(maximum[i] >= LimitForShowLabel) {
      n = StringConcatenate(PREFIX_TEXT, i, "_max_", maximum[i]);
      
      ObjectCreate(n, OBJ_TEXT, 0, Time[i], High[i] + OffsetForMaximums * Point);
      ObjectSet(n, OBJPROP_COLOR, ColorMaximum);
      ObjectSetText(n, "" + maximum[i], FONT_SIZE);
    }

    if(minimum[i] >= LimitForShowLabel) {
      n = StringConcatenate(PREFIX_TEXT, i, "_min_", minimum[i]);
      
      ObjectCreate(n, OBJ_TEXT, 0, Time[i], Low[i] - OffsetForMinimums * Point);
      ObjectSet(n, OBJPROP_COLOR, ColorMinimum);
      ObjectSetText(n, "" + minimum[i], FONT_SIZE);
    }
  }
  
  // Ìàêñèìàëüíûé óðîâåíü ëèíèè ðåàëüíî
  if(last_level > MaximalLineLevel) {
   k = MaximalLineLevel;
  } else {
   k = last_level;
  }
  
  // Îòðèñîâêà ëèíèé çèãçàãà
  for(i = MinimalLineLevel; i <= k; i++) {
    if(OptimizeZigZag) {
      optimize_level(i);
    }
  
    prev_price = -1;
  
    for(j = Bars - 1; j >= 0; j--) {
      if(maximum[j] >= i) {
        if(prev_price > 0) {
          build_line(i, j, prev_time, prev_price, Time[j], High[j]);
        }
        
        prev_time  = Time[j];        
        prev_price = High[j];
      }

      if(minimum[j] >= i) {
        if(prev_price > 0) {
          build_line(i, j, prev_time, prev_price, Time[j], Low[j]);
        }
        
        prev_time  = Time[j];        
        prev_price = Low[j];
      }
    }
  }
}






Sample





Analysis



Market Information Used:

Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Series array that contains open time of each bar


Indicator Curves created:


Indicators Used:



Custom Indicators Used:

Order Management characteristics:

Other Features: