Ответить
21.12.2012, 23:11
Аватар для hoz
hoz hoz вне форума Активный участник
Регистрация: 01.04.2011 / Сообщений: 532
Поблагодарили 112 раз(а) / Репутация: 111
  • Отправить сообщение для hoz с помощью ICQ

По умолчанию А давайте разберём это zig-zag!

Решил я освоить индикатор zig-zag. По-сколько дефолтовый вариант данного индюка включённого в стандартную поставку с МТ4 я не особо въехал, я погуглив нашёл один из вариантов с комментами...Начал его штудировать, но тут тоже возникли нюансы. Выношу первый вариант данного zig-zag'а, который строится канкретно по закрытию. Попутно у меня есть огромное желание разобрать его по полочкам. Да я думаю это будет полезно не только мне, а многим присуствующим!

Вот данный код:

Скрытый текст

PHP код:
#property copyright "Scriptong"
#property link "http://autograf.dp.ua"

#property indicator_chart_window                   // Индикатор выводится в окне графика
#property indicator_buffers 1                      // используется 1 буфер индикатора
#property indicator_color1 Blue                    // Цвет отображения данных 1-го буфера

#property indicator_width1 1                       // Толщина линий 1-го буфера

double ZZBuf[];                                    // Буфер экстремумов
double UpDnBuf[];                                  // Буфер признака текущего тренда
                                                   
#define NO_TREND        0                          // Нет тренда
#define TREND_UP        1                          // Восходящий тренд
#define TREND_DOWN     -1                          // Нисходящий тренд      

//+-------------------------------------------------------------------------------------+
//| Custom indicator initialization function                                            |
//+-------------------------------------------------------------------------------------+
int init()
{
   
IndicatorBuffers(2);
// - 1 - == Проверка корректности значений настроечных параметров индикатора ============
   
string name WindowExpertName();
// - 1 - == Окончание блока =============================================================

// - 2 - == Связывание буферов с индексами, определение стилей ==========================
   
SetIndexBuffer(0ZZBuf);                       // Первый буфер - экстремумы
   
SetIndexStyle(0DRAW_SECTION);                 // В виде линии между непустыми..
                                                   // ..значениями

   
SetIndexBuffer(1UpDnBuf);                     // Второй буфер - признак тренда
   
SetIndexStyle(1DRAW_NONE);                    // Не отображается
// - 2 - == Окончание блока =============================================================

   
return(0);
}
  
//+-------------------------------------------------------------------------------------+
//| Custom indicator deinitialization function                                          |
//+-------------------------------------------------------------------------------------+
int deinit()
{
   return(
0);
}
  
//+-------------------------------------------------------------------------------------+
//| Определение индекса бара, с которого необходимо производить перерасчет              |
//+-------------------------------------------------------------------------------------+
int GetRecalcIndex()
{
   
int counted_bars IndicatorCounted();
   if (
counted_bars == 0)                          // Кол-во посчитанных баров - 0. Будут
   
{                                               // ..пересчитаны все буфера с самого..
      
ArrayInitialize(ZZBufEMPTY_VALUE);         // ..начала. Очистка буферов
      
ArrayInitialize(UpDnBuf0);
      return(
Bars 2);                            // Начинаем со второго бара истории
   
}
   return(
Bars counted_bars 1);                // Начинаем с нового бара
}

//+-------------------------------------------------------------------------------------+
//| Определение тенденции по соотношению указанной и предыдущей свечей                  |
//+-------------------------------------------------------------------------------------+
int GetTrend(int index)
{
// - 1 - == Закрытие новой свечи выше максимума предыдущей ==============================
   
if (Close[index] > High[index+1])
      return(
TREND_UP);                            // Рост
// - 1 - == Окончание блока =============================================================

// - 2 - == Закрытие новой свечи ниже минимума предыдущей ===============================
   
if (Close[index] < Low[index+1])
      return(
TREND_DOWN);                          // Падение
// - 2 - == Окончание блока =============================================================

   
return(NO_TREND);                               // Если свеча не пробита - нет тренда
}
//+-------------------------------------------------------------------------------------+
//| Поиск последнего элемента ZZBuf с непустым значением                                |
//+-------------------------------------------------------------------------------------+
int GetLastIndexNoEmptyValue(int index)
{
   while (
ZZBuf[index] == EMPTY_VALUE && index Bars)// Поиск по графику справа налево
      
index++;                                     // Пока не будет найден экстремум или
                                                   // ..пока не достигнем конца истории
   
return(index);                                  // Индекс бара с непустым значением..
                                                   // ..зиг-зага
}

//+-------------------------------------------------------------------------------------+
//| Сравнение последнего максимума с новым максимумом                                   |
//+-------------------------------------------------------------------------------------+
void CheckHigh(int index)
{
   
int cnt GetLastIndexNoEmptyValue(index);      // Найдем последний непустой элемент..
                                                   // ..зиг-зага
   
if (cnt == Bars)                                // Если элемент не найден (достигнут..
   
{                                               // ..конец истории), то максимумом..
      
ZZBuf[index] = High[index];                  // ..считается текущий максимум
      
return;
   }

   if (
High[index] > ZZBuf[cnt])                   // Элемент найден. Сравним его..
   
{                                               // ..значение с новым максимумом. Если
      
ZZBuf[cnt] = EMPTY_VALUE;                    // ..новый максимум выше, то..
      
ZZBuf[index] = High[index];                  // ..предыдущий максимум уничтожается,
                                                   // ..а новый сохраняется
   
}
}
//+-------------------------------------------------------------------------------------+
//| Сравнение последнего минимума с новым минимумом                                     |
//+-------------------------------------------------------------------------------------+
void CheckLow(int index)
{
   
int cnt GetLastIndexNoEmptyValue(index);      // Найдем последний непустой элемент..
                                                   // ..зиг-зага
   
if (cnt == Bars)                                // Если элемент не найден (достигнут..
   
{                                               // ..конец истории), то минимумом..
      
ZZBuf[index] = Low[index];                   // ..считается текущий минимум
      
return;
   }
   
   if (
Low[index] < ZZBuf[cnt])                    // Элемент найден. Сравним его..
   
{                                               // ..значение с новым минимумом. Если
      
ZZBuf[cnt] = EMPTY_VALUE;                    // ..новый минимум ниже, то..
      
ZZBuf[index] = Low[index];                   // ..предыдущий минимум уничтожается,
                                                   // ..а новый сохраняется
   
}
}
//+-------------------------------------------------------------------------------------+
//| Смена тренда или его продолжение при отсутствии нового сигнала                      |
//+-------------------------------------------------------------------------------------+
void TrendChange(int trendint i)
{
// - 1 - == Тренд изменился с нисходящего на восходящий =================================
   
UpDnBuf[i] = trend;                             // Сохранение признака направления
   
if (trend == TREND_UP)                          // Тренд изменился на восходящий
   
{
      
CheckLow(i);                                 // Проверка появления нового минимума
      
if (ZZBuf[i] != EMPTY_VALUE)                 // Если минимум обновлен, то максимум
         
ZZBuf[i-1] = High[i];                     // ..переносим на следующий бар
      
else                                         // Если минимум не обновлен, то..
         
ZZBuf[i] = High[i];                       // ..максимум отображается на текущем
      
return;                                      // ..баре
   
}
// - 1 - == Окончание блока =============================================================

// - 2 - == Тренд изменился с восходящего на нисходящий =================================
   
CheckHigh(i);                                   // Проверка появления нового максимума
   
if (ZZBuf[i] != EMPTY_VALUE)                    // Если максимум обновлен, то минимум
      
ZZBuf[i-1] = Low[i];                         // ..отображается на следующем баре
   
else                                            // Если максимум не обновлен, то..
      
ZZBuf[i] = Low[i];                           // ..минимум отображается на текущем..
                                                   // ..баре
// - 2 - == Окончание блока =============================================================
}

//+-------------------------------------------------------------------------------------+
//| Расчет значений индикатора                                                          |
//+-------------------------------------------------------------------------------------+
void ZigZag(int limit)
{
   for (
int i limit0i--)                 // По всем новым барам
   
{
      
int trend GetTrend(i);                     // Получение направления на баре i
      
if (trend != UpDnBuf[i+1] && trend != 0)     // Направление на текущем баре..
      
{                                            // ..отличается от направления на..
         
TrendChange(trendi);                    // ..предыдущем баре.
         
continue;
      }
      
      
UpDnBuf[i] = UpDnBuf[i+1];                   // Направление не изменяется
      
if (UpDnBuf[i] == TREND_UP)                  // Сохранение восходящего тренда
      
{
         
CheckHigh(i);                             // Обновление максимума
         
continue;
      }
         
      if (
UpDnBuf[i] == TREND_DOWN)                // Сохранение нисходящего тренда
         
CheckLow(i);                              // Обновление минимума
   
}
}

//+-------------------------------------------------------------------------------------+
//| Custom indicator iteration function                                                 |
//+-------------------------------------------------------------------------------------+
int start()
{
   
int limit GetRecalcIndex();                   // Определим первый расчетный бар
   
   
ZigZag(limit);                                  // Расчет значений индикатора
   
   
return(0);

[свернуть]



В функции ZigZag(int limit) цикл идёт по убывающей. По логике, чтоб исключить перерисовку нужно наоборот идти слева направо... т.е. я думаю, правильнее будет так:

PHP код:
for (int i 0limiti++) 

В чём загвоздка? Кто что думает по этому поводу?

Идём дальше. В старте объявлены 2 функции: GetRecalcIndex() и ZigZag(limit)

В функции ZigZag(limit) в строке:

PHP код:
 if (trend != UpDnBuf[i+1] && trend != 0

Проверяется условие:

PHP код:
trend != UpDnBuf[i+1

Откуда программа в этот момент будет знать какое значение имеет данный буфер, ведь по сути нигде об этом в коде по ходу работы кода не упоминается...

А присвоится значение данному буферу только в функции TrendChange(int trend, int i)

Но в данный момент она ещё не вызывается..

Последний раз редактировалось NSerega; 22.12.2012 в 01:05.
22.12.2012, 07:46
Аватар для ale002
ale002 ale002 вне форума ::: __,,,^._.^,,,__ :::
Регистрация: 28.02.2010 / Сообщений: 1,246
Поблагодарили 2,510 раз(а) / Репутация: 2536
Это вопросы не про зигзаг - ответами должны быть ссылки на соотв статьи в учебнике MQL или в справке MT4. Правильнее было бы этим занимаццо в топике про изучение языка, котор ведёт диавольский просветитель Evil. И правильнее таки с учебника и начать, иначе вы много чего возьмётесь усовершенствовать, напрасно убивая собственное время

И еще, не по теме, но просто полезный принцип, который оч помогает жить. Особенно кодерам. Не стоит браться за что-то лишь тока потому что ты можешь это сделать/переделать
22.12.2012, 11:10
Аватар для hoz
hoz hoz вне форума Активный участник
Регистрация: 01.04.2011 / Сообщений: 532
Поблагодарили 112 раз(а) / Репутация: 111
  • Отправить сообщение для hoz с помощью ICQ
Это вопросы не про зигзаг - ответами должны быть ссылки на соотв статьи в учебнике MQL или в справке MT4. Правильнее было бы этим занимаццо в топике про изучение языка, котор ведёт диавольский просветитель Evil. И правильнее таки с учебника и начать, иначе вы много чего возьмётесь усовершенствовать, напрасно убивая собственное время

И еще, не по теме, но просто полезный принцип, который оч помогает жить. Особенно кодерам. Не стоит браться за что-то лишь тока потому что ты можешь это сделать/переделать

Я тот недальновидный учебник уже несколько раз перечитал. Там практических приёмов нет вовсе, только теория.
Теорию читаешь, всё понятно, а вот открываешь код и понимаешь, что что-то не понятно тут. Вот потом я и написал сюда вопрос, чтоб в основной ветке не путаться.
Надеюсь на более канкретные ответы, а не - читай учебник.. что читать? Всё в подряд читать нет резона, т.к. я уже многое знаю. Но есть непонятки ещё, потому и спрашиваю.
Надеюсь на помощь.
22.12.2012, 11:58
Аватар для ale002
ale002 ale002 вне форума ::: __,,,^._.^,,,__ :::
Регистрация: 28.02.2010 / Сообщений: 1,246
Поблагодарили 2,510 раз(а) / Репутация: 2536
Надеюсь на более канкретные ответы, а не - читай учебник.. что читать? Всё в подряд читать нет резона, т.к. я уже многое знаю.
Ах батенька, да вас ещё и учиться нужно научить.. Берёте любой свой вопрос:

По логике, чтоб исключить перерисовку нужно наоборот идти слева направо... т.е. я думаю, правильнее будет так
Не надо додумывать "по логике", прочтите таки в учебнике как нумеруются тайм-серии в MQL4 - от прошлого к настоящему или наоборот

Откуда программа в этот момент будет знать какое значение имеет данный буфер, ведь по сути нигде об этом в коде по ходу работы кода не упоминается...
Прочтите об области видимости переменных (глобальных, суперглобальных и локальных) и к которому из них относятся буферные массивы

Надеюсь на помощь.
Надеюсь кто-то вам поможет, звиняйте что влез, не удержалсо, виноват, исправлюсь
22.12.2012, 12:45
Аватар для hoz
hoz hoz вне форума Активный участник
Регистрация: 01.04.2011 / Сообщений: 532
Поблагодарили 112 раз(а) / Репутация: 111
  • Отправить сообщение для hoz с помощью ICQ
Не надо додумывать "по логике", прочтите таки в учебнике как нумеруются тайм-серии в MQL4 - от прошлого к настоящему или наоборот
Вообще-то, если читать "учебник", то нумерация последовательности однотипных элементов (таймсерий) начинается с нуля. НО. Никто не сказал, что нуль должен быть настоящим! Это значит, что я могу нуль сделать каким-то баром прошлый, а самый последний захочу пронумерую последним значением цикла. Тут мы формально перебирает цикл, я думаю, что можно перебрать его с любой стороны. Если нет, поправьте, и обоснуйте, программист должен думать, а не тупо читать учебник и зубрить..




Я понимаю, и знаю, что первым баром вообще в таймсерии является нулевой бар, но тут же не та ситуация. Здесь мы лишь задаём цикл и всё!

Прочтите об области видимости переменных (глобальных, суперглобальных и локальных) и к которому из них относятся буферные массивы
Причём тут область видимости. На тот момент, буфер ещё ничего не содержит. Поэтому у него не может быть никакого значения. Вот это я имел ввиду! А про область видимости я прекрасно понимаю..

Надеюсь кто-то вам поможет, звиняйте что влез, не удержалсо, виноват, исправлюсь

Зачем тогда форум, если все друг друга будут сторонкой обходить.. Давайте тогда нос воротить друг от друга!? Если кто-то это всё понимает, ХОТЯ Я СОМНЕВАЮСЬ, ЧТО БОЛЬШИНСТВО ИЗ ЗДЕСЬ ПРИСУСТВУЮЩИХ ЭТО ПОНИМАЕТ, то это не значит, что всем это просто понять.

Последний раз редактировалось hoz; 22.12.2012 в 12:48.
23.12.2012, 10:01
Аватар для hoz
hoz hoz вне форума Активный участник
Регистрация: 01.04.2011 / Сообщений: 532
Поблагодарили 112 раз(а) / Репутация: 111
  • Отправить сообщение для hoz с помощью ICQ
В общем-то пока всякие гуру и те кто на них косит проходили мимо я уже сам понял в чём дело. Больше помощь не требуется...
Ответить

Метки
zig-zag, код, разбор


Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Trackbacks are Выкл.
Pingbacks are Выкл.
Refbacks are Выкл.



Текущее время: 17:32. Часовой пояс GMT.


Перевод: zCarot
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
SEO by vBSEO