Что возвращают функции Lowest и Highest - страница 5

 
Candid, сейчас нормально.
Klot, интересный вариант.

Если Ваши варианты зигзагов покажут интересные результаты, можно их в своей разработке применять?

Конечно можно, я с интересом слежу за разработкой и мне очень нравиться Ваша работа.
 
Спасибо.
 
2 nen:
Ещё относительно "опций". Сейчас одно из условий переключения экстремумов: текущий лоу выше текущего минимума больше, чем на ExtDeviation пунктов (аналогично для максимума). При необходимости код позволяет достаточно легко реализовать другие варианты.
Ну и, вслед за klot'ом, хочу добавить, что мой нынешний интерес к зигзагу вызван исключительно интересом к Вашей разработке.
 
Ещё раз поправил исходный код - вчера обнаружил что на минутках правило первого значащего бара иногда не соблюдается. Для проверки правда часа полтора онлайна всего оставалось, но похоже дело было в сравнении double c нулём.
 
Ещё баг: переключать экстремумы можно только при окончании бара, иначе получается разница между реал-таймом и историей. Исправляется несложно. Исходный код в ветке пока не корректировал - пусть новая версия ещё на минутках покрутится.
 
Candid, сделал 45 версию индикатора ZUP: http://onix-trade.net/forum/index.php?s=&showtopic=118&view=findpost&p=117997
В ней в качестве внешнего зигзага включил и твой зигзаг. Как появится устойчиво работающая версия, поменяю.
 
Пока проблем не видно, вот исправленный вариант кода:
//+------------------------------------------------------------------+
//|                                                      CZigZag.mq4 |
//|                                         Copyright © 2006, Candid |
//|                                                   likh@yandex.ru |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2006, Candid"
#property link      "likh@yandex.ru"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_color1 Navy

//---- indicator parameters
extern int ExtDepth=12;
extern int ExtDeviation=5;
//extern int ExtBackstep=3;

int    shift;
double res=0;
int i;
double CurMax,CurMin;
int CurMaxPos,CurMinPos;
int CurMaxBar,CurMinBar;
double hPoint;
double mhPoint;
double EDev;
int MaxDist,MinDist;
bool FirstRun;
bool AfterMax,AfterMin;
int BarTime;

//---- indicator buffers
double ZigZag[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int init() {
//---- indicators
   SetIndexStyle(0,DRAW_SECTION);
//---- indicator buffers mapping
   SetIndexBuffer(0,ZigZag);
   SetIndexEmptyValue(0,0.0);
//---- indicator short name
   IndicatorShortName("ZigZag("+ExtDepth+","+ExtDeviation+")");
   
   FirstRun = true;
//----
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit() {
//----
   
//----
  return(0);
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int start() {
  int counted_bars=IndicatorCounted();
  int fBar;
  
  if (FirstRun) {
    hPoint = 0.5*Point;
    mhPoint = -hPoint;
    EDev = (ExtDeviation+0.5)*Point;
    AfterMax = true;
    AfterMin = true;
    fBar = Bars-1;
    CurMax = High[fBar];
    CurMaxBar = 1;
    CurMin = Low[fBar];
    CurMinBar = 1;
    MaxDist = 0;
    MinDist = 0;
    BarTime = 0;
    FirstRun = false;
  }


//----
  fBar = Bars-counted_bars-1;
  if (fBar > Bars-2) fBar = Bars-2;
  for(shift=fBar; shift>=0; shift--) {
    if (BarTime!=Time[shift]) {
      BarTime=Time[shift];
      if (res > hPoint ) {
        MaxDist = Bars-CurMaxBar-shift+1;
        MinDist = Bars-CurMinBar-shift+1;
        if ((MaxDist>ExtDepth && MinDist>ExtDepth) || res > EDev) {
          if (AfterMax) {
            AfterMax = false;
            AfterMin = true;
            CurMaxBar = CurMinBar+1;
            CurMaxPos = Bars-CurMaxBar;
            CurMax = High[CurMaxPos];
            for (i=CurMaxPos-1;i>=shift;i--) {
              if (High[i] > CurMax+hPoint) {
                CurMaxBar = Bars-i;
                CurMax = High[i];
              }
            }  //  for (i=CurMaxPos-1;i>=shift;i--)
            ZigZag[Bars-CurMaxBar] = CurMax;
          } else {  //  if (AfterMax)
            AfterMin = false;
            AfterMax = true;
            CurMinBar = CurMaxBar+1;
            CurMinPos = Bars-CurMinBar;
            CurMin = Low[CurMinPos];
            for (i=CurMinPos-1;i>=shift;i--) {
              if (Low[i] < CurMin-hPoint) {
                CurMinBar = Bars-i;
                CurMin = Low[i];
              }
            }  //  for (i=CurMinPos-1;i>=shift;i--)
            ZigZag[Bars-CurMinBar] = CurMin;
          }  //  else if (AfterMax)    
        }  //  if ((MaxDist>ExtDepth && MinDist>ExtDepth) || res > EDev)
      }  //  if (res > hPoint )
    }  //  if (BarTime!=Time[0])
    if (AfterMax) {
      res = Low[shift]-CurMin;
      if (res < mhPoint) {
        ZigZag[Bars-CurMinBar] = 0;
        CurMin = Low[shift];
        CurMinBar = Bars-shift; 
        ZigZag[Bars-CurMinBar] = CurMin;
      }  //  if (res < mhPoint)
    }  //  if (AfterMax) 
    if (AfterMin) {
      res = CurMax-High[shift];
      if (res < mhPoint) {
        ZigZag[Bars-CurMaxBar] = 0;
        CurMax = High[shift];
        CurMaxBar = Bars-shift; 
        ZigZag[Bars-CurMaxBar] = CurMax;
      }  //  if (res < mhPoint)
    }  //  if (AfterMin) 
  }  //  for(shift=fBar; shift>=0; shift--)
//----
  return(0);
}
//+------------------------------------------------------------------+


К вопросу об особенностях разных зигзагов. Главный признак этого зигзага - всё делается за один проход, повторный просмотр исторических данных делается только при фиксации экстремума, и только для данных после этого экстремума. То есть он должен быть довольно быстрым. Особенности отрисовки конечно будут зависеть от критериев фиксации экстремума, но тут легко реализовать самые разные опции. К примеру, я уже делал варианты с переключением по проценту от предыдущего хода, по отходу High от минимума (соответственно Low от максимума) и с привязкой переключения к среднему размеру бара.

 
Вот ещё проблема с индикатором: я обнаружил излом на своём зигзаге (крестик курсора на картинке). Время излома соответствует времени выключения терминала, цена - времени его нового включения.


Для прояснения некоторых возникших подозрений я вставил в код такой Print:
if (shift<5) Print ("shift=",shift,", Bars=",Bars,", Time[shift]=",TimeToStr(Time[shift],TIME_DATE|TIME_MINUTES),", High[shift]=",High[shift],", Low[shift]=",Low[shift]);


После этого терминал был закрыт и снова запущен через несколько минут. И вот фрагмент лога:

2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=0, Bars=38233, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=1, Bars=38233, Time[shift]=2006.10.31 22:50, High[shift]=1.2763, Low[shift]=1.2762
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=2, Bars=38233, Time[shift]=2006.10.31 22:49, High[shift]=1.2763, Low[shift]=1.2763
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=3, Bars=38233, Time[shift]=2006.10.31 22:47, High[shift]=1.2763, Low[shift]=1.2762
2006.10.31 23:58:26	CZZ2 EURUSD,M1: shift=4, Bars=38233, Time[shift]=2006.10.31 22:45, High[shift]=1.2763, Low[shift]=1.2762
2006.10.31 23:58:25	CZZ2 EURUSD,M1: shift=0, Bars=38230, Time[shift]=2006.10.31 22:51, High[shift]=1.2763, Low[shift]=1.2763
2006.10.31 23:58:25	CZZ2 EURUSD,M1: shift=1, Bars=38230, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762
2006.10.31 23:58:23	CZZ2 EURUSD,M1: shift=0, Bars=38229, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762
2006.10.31 23:58:22	CZZ2 EURUSD,M1: shift=0, Bars=38229, Time[shift]=2006.10.31 22:45, High[shift]=1.2762, Low[shift]=1.2762


Видно, что в 23:58:23 история ещё не подкачивалась, а к 23:58:25 подкачан 1 последний бар. И только к 2006.10.31 23:58:26 докачаны все промежуточные бары.
Вопрос к разработчикам: это штатная последовательность подкачки? И если да, то какой в этом смысл? Понятно, что желательно пораньше иметь текущее значение цены. Но запланированное существование в течение некоторого времени дыры в истории по сути означает гарантированный сбой индикаторов на это время. Не безопаснее ли для пользователя отложить расчёт индикаторов до полной подкачки истории? Или хотя бы после полной подкачки инициализировать их заново?

 
Насчёт "инициализировать заново" это зря я написал, это по сути заметание следов уже будет :)
 
С такой подкачкой истории знаком. У меня сделана проверка первых пять переломов загзага И пересчет индикатора ZUP.
Причина обращения: