Форум » Консультации по программированию » MQL4 Zig-Zag не делается мультитаймфреймным » Ответить

MQL4 Zig-Zag не делается мультитаймфреймным

hoz: Я позаимствовал у Игоря Зиг-зага из статьи, которая называлась как-то так... "Идеальный зиг-заг". Привёл в читабельный вид. И хотел было сделать ещё некоторые вещи с ним, как заметил, что у меня не получается сделать этот зиг-заг МТФ. Версия Зиг-зага, которая коректно отображает экстремумы называется ZigZagHighLow.mq4. Версия МТФ Зиг-зага называется ZZ.mq4, Коды прилагаю в сообщению. У второго индикатора имеются вводные параметры: Символ и Таймфрейм. Кроме как замены 3 функции я больше ничего не менял. По сути, должно было, как я понимаю, получить то, что мне нужно. Но не получилось.. В индикаторе ZZ.mq4 используется библиотека-прокладка GetTimeSeriesData.mq4. Она удобно для получения данных из таймсерий. В индикаторе ZZ.mq4 я заменил лишь данные таймсерий т.е. High[index] и High[index + 1], Low[index], Low[index + 1] и Bars, на соответственно методы сегодня написанной библиотеки, которую я проверил уже: getBarHighPrice(index, i_tf, i_instrument), getBarLowPrice(index, i_tf, i_instrument) и getTotalHistoryBars(i_tf, i_instrument). Так вот Зиг-заг рисуется какой-то левый. У меня такое ощущение, что он экстремумы рисует со сдвигом. Но почему вопрос. Ведь я получил количество баров с оответствующего таймфрейма, а так же цены максимальные и минимальные беру тоже с того же таймфрейма. Что не так? Ссылка на имеющийся код

Ответов - 22, стр: 1 2 All

Scriptong: hoz пишет: Я перенёс цикл из функции ZigZag в функцию processBar Не понимаю, что от этого изменилось? Разве что можно поговорить о разной производительности. Возможно, Ваш способ чуток быстрее. Но он хуже читается. Наличие буфера g_ZZTimeBuf для меня как было, так и остается загадкой. В индикаторе он не используется. Даже если допустить, что он нужен для чтения данных индикатора из советника или другого индикатора, то все равно получаем масло масленое: запрашиваем значение, записанное в ячейке под индексом barIndex, в которой записано время открытия этого бара. Спрашивается: зачем для этого индикатор, если можно было напрямую взять время открытия бара, если его индекс нам известен?

hoz: Scriptong пишет: Наличие буфера g_ZZTimeBuf для меня как было, так и остается загадкой. В индикаторе он не используется. Даже если допустить, что он нужен для чтения данных индикатора из советника или другого индикатора, то все равно получаем масло масленое: запрашиваем значение, записанное в ячейке под индексом barIndex, в которой записано время открытия этого бара. Спрашивается: зачем для этого индикатор, если можно было напрямую взять время открытия бара, если его индекс нам известен? Да, изначально думал передавать его в совок. Но теперь думаю, что это лишнее видимо. Получается по циклу пробегаем по барам, которые нам интересные. В цикле, соответственно, вызываем в iCustom наш зиг-заг и там же мы передаёт индексы бара, на котором ищем экстремум, соответственно, если iCustom вернёт не пустое значение, значим экстремум есть, а значит и время можно получить у этого бара (экстремума) и др. нужные данные. Я прав? Получается, я буфер лишним добавил. Scriptong пишет: Не понимаю, что от этого изменилось? Разве что можно поговорить о разной производительности. Возможно, Ваш способ чуток быстрее. Но он хуже читается. Изменилось, то, что, если бы пришлось оставить буфер времени, иначе не получилось у меня переделать индикатор так, что бы время всё-таки сохранялось. Это видно в методе processBar. Там есть блок: if (stZZProperty.trend == TREND_DIR_NONE) { ENUM_TREND_DIR eNewTrend = getTrend(barIndex); if (eNewTrend == TREND_DIR_NONE) return; stZZProperty.setData(eNewTrend, barIndex, (eNewTrend == TREND_DIR_UPWARD)? iHigh(NULL, i_TF, barIndex) : iLow(NULL, i_TF, barIndex), iTime(NULL, i_TF, barIndex)); showOrDeleteExtremum(stZZProperty, stZZProperty.price); return; У меня такое ощущение, что мой вариант медленнее. Нужно будет замерить скорость. Если это так, то верну как и было.

Scriptong: hoz пишет: Да, изначально думал передавать его в совок. Но теперь думаю, что это лишнее видимо. Получается по циклу пробегаем по барам, которые нам интересные. В цикле, соответственно, вызываем в iCustom наш зиг-заг и там же мы передаёт индексы бара, на котором ищем экстремум, соответственно, если iCustom вернёт не пустое значение, значим экстремум есть, а значит и время можно получить у этого бара (экстремума) и др. нужные данные. Я прав? Получается, я буфер лишним добавил. Да. Я именно об этом. Если известен индекс бара экстремума, то автоматически известно и время его открытия. hoz пишет: У меня такое ощущение, что мой вариант медленнее. Нужно будет замерить скорость. Если это так, то верну как и было. Там разница будет едва заметна. Достаточно сложно определить. А потому результаты получатся как с преобладанием одной, так и другой стороны. Я бы не заморачивался.


hoz: Scriptong пишет: Там разница будет едва заметна. Достаточно сложно определить. А потому результаты получатся как с преобладанием одной, так и другой стороны. Я бы не заморачивался. Что-то с терминалом было. Другой устаонвил, теперь всё быстро. Вот график построения зиг-зага. График открыт М30, а в инпут-параметры индикатора передаю Н1, соответственно: Так вот я на скрине описал текущий трабл индюка. Метод getTrend() я переписал как вижу сейчас. Особо ничего не поменялось, но так нужно. Хотя, видимо нужно будет ещё что-то дописать. В getTrend() же дописал условие, что бы если от текущего бара прошло менее n-баров, тренд сохранялся прежним т.е. триггера на изменение тренда ещё нет. Вот я думаю, что нужно это как-то исправить. Думаю, но ещё не решил.. На данный момент, вот что имеется Кстати, я сравнил то, что отображает ваш вариант индикатора и мой. Так вот в данном случает, находясь на М30 и рисуя по Н1 разницы нет. Получается, какяк изначально имеется.

Scriptong: hoz пишет: Получается, какяк изначально имеется. Это не баг, а недостаток информации. Дело в том, что располагая только свечной информацией, невозможно достоверно установить последовательность возникновения экстремумов. Поэтому на свечах, поглощающих предыдущие свечи (максимум выше предыдущего максимума и минимум ниже предыдущего минимума) всегда будут появляться подобные проблемы. Чтобы их устранить 100% (не выдвигая предположений типа: на медвежьей свече минимум всегда позже максимума, а на бычьей - всегда раньше), нужно анализировать меньший ТФ, а в случае графика М1 - тиковую историю. Вот тогда ZigZag будет на 100% достоверным. Только вот вопрос: а нужно ли это для индикатора, являющегося тестерным Граалем? P. S. Плюс есть еще одна проблема. Даже располагая всей необходимой информацией, сталкиваемся с невозможностью отображения двух экстремумов ZZ на одном баре (по крайней мере при использовании индикаторных буферов). Чтобы отобразить на одном баре два экстремума, понадобится либо задействование еще одного индикаторного буфера, либо переход к отображению данных при помощи трендовых линий.

hoz: Scriptong пишет: Это не баг, а недостаток информации. Дело в том, что располагая только свечной информацией, невозможно достоверно установить последовательность возникновения экстремумов. Поэтому на свечах, поглощающих предыдущие свечи (максимум выше предыдущего максимума и минимум ниже предыдущего минимума) всегда будут появляться подобные проблемы. Чтобы их устранить 100% (не выдвигая предположений типа: на медвежьей свече минимум всегда позже максимума, а на бычьей - всегда раньше), нужно анализировать меньший ТФ, а в случае графика М1 - тиковую историю. Вот тогда ZigZag будет на 100% достоверным. Только вот вопрос: а нужно ли это для индикатора, являющегося тестерным Граалем? По сути да, я здесь не прав. Scriptong пишет: P. S. Плюс есть еще одна проблема. Даже располагая всей необходимой информацией, сталкиваемся с невозможностью отображения двух экстремумов ZZ на одном баре (по крайней мере при использовании индикаторных буферов). Чтобы отобразить на одном баре два экстремума, понадобится либо задействование еще одного индикаторного буфера, либо переход к отображению данных при помощи трендовых линий. Если будет не 1 буфер, то отобразиться же всё. У меня есть такой зиг-заг. Тока он написал кривовато, и руки до него не добрались пока что. Хотя он рмсует несколько зиг-загов на одном графике и у него соответственно столько же буферов. Кстати, возник ещё один интересный момент. Я добавил сюда метод: int getLastNoEmptyValueIndex(int index) { while (index < iBars(NULL, i_TF)) { if (g_ZZPriceBuf[index] != EMPTY_VALUE) return index; Print("index = ", index); index++; } return index; } Этот метод я использую в методе getTrend() для того, что бы узнать индекс последнего сформированного экстремума. ENUM_TREND_DIR getTrend(ZZProperty& stZZProperty, int barIndex) { int lastZZBarIndex = getLastNoEmptyValueIndex(barIndex); if ((lastZZBarIndex - barIndex) < 3) return stZZProperty.trend; // Новая свеча выше предыдущей if (iHigh(NULL, i_TF, barIndex) > iHigh(NULL, i_TF, barIndex + 1)) { return TREND_DIR_UPWARD; } // Новая свеча ниже предыдущей if (iLow(NULL, i_TF, barIndex) < iLow(NULL, i_TF, barIndex + 1)) { return TREND_DIR_DOWNWARD; } return TREND_DIR_NONE; } Это нужно, что бы зиг-заг не искал экстремум на баре, если последний сформированный экстремум находится на растоянии N-баров. Фильтр нужен, что бы на каждом баре не рисовались экстремумы, как это иногда бывает.. Так вот возникает ошибка в строке 92 у меня: 2018.04.07 12:28:17.132 2018.02.19 18:00:00 ZZ_mtf AUDUSDm,M30: array out of range in 'ZZ_mtf.mq4' (92,21) Ошибка в строке кода: if (g_ZZPriceBuf[index] != EMPTY_VALUE) Я так понял, здесь придётся для этой задачи сделать массив буфера динамическим? (если, конечно, это возможно. Вижу, что, вроде как, размер массива g_ZZPriceBuf меньше, чем g_ZZPriceBuf[index] на индексе в цикле. Вот код

hoz: Scriptong пишет: Это не баг, а недостаток информации. Дело в том, что располагая только свечной информацией, невозможно достоверно установить последовательность возникновения экстремумов. Поэтому на свечах, поглощающих предыдущие свечи (максимум выше предыдущего максимума и минимум ниже предыдущего минимума) всегда будут появляться подобные проблемы. Чтобы их устранить 100% (не выдвигая предположений типа: на медвежьей свече минимум всегда позже максимума, а на бычьей - всегда раньше), нужно анализировать меньший ТФ, а в случае графика М1 - тиковую историю. Вот тогда ZigZag будет на 100% достоверным. Только вот вопрос: а нужно ли это для индикатора, являющегося тестерным Граалем? По сути да, я здесь не прав. Scriptong пишет: P. S. Плюс есть еще одна проблема. Даже располагая всей необходимой информацией, сталкиваемся с невозможностью отображения двух экстремумов ZZ на одном баре (по крайней мере при использовании индикаторных буферов). Чтобы отобразить на одном баре два экстремума, понадобится либо задействование еще одного индикаторного буфера, либо переход к отображению данных при помощи трендовых линий. Если будет не 1 буфер, то отобразиться же всё. У меня есть такой зиг-заг. Тока он написал кривовато, и руки до него не добрались пока что. Хотя он рмсует несколько зиг-загов на одном графике и у него соответственно столько же буферов. Кстати, возник ещё один интересный момент. Я добавил сюда метод: int getLastNoEmptyValueIndex(int index) { while (index < iBars(NULL, i_TF)) { if (g_ZZPriceBuf[index] != EMPTY_VALUE) return index; Print("index = ", index); index++; } return index; } Этот метод я использую в методе getTrend() для того, что бы узнать индекс последнего сформированного экстремума. ENUM_TREND_DIR getTrend(ZZProperty& stZZProperty, int barIndex) { int lastZZBarIndex = getLastNoEmptyValueIndex(barIndex); if ((lastZZBarIndex - barIndex) < 3) return stZZProperty.trend; // Новая свеча выше предыдущей if (iHigh(NULL, i_TF, barIndex) > iHigh(NULL, i_TF, barIndex + 1)) { return TREND_DIR_UPWARD; } // Новая свеча ниже предыдущей if (iLow(NULL, i_TF, barIndex) < iLow(NULL, i_TF, barIndex + 1)) { return TREND_DIR_DOWNWARD; } return TREND_DIR_NONE; } Это нужно, что бы зиг-заг не искал экстремум на баре, если последний сформированный экстремум находится на растоянии N-баров. Фильтр нужен, что бы на каждом баре не рисовались экстремумы, как это иногда бывает.. Так вот возникает ошибка в строке 92 у меня: 2018.04.07 12:28:17.132 2018.02.19 18:00:00 ZZ_mtf AUDUSDm,M30: array out of range in 'ZZ_mtf.mq4' (92,21) Ошибка в строке кода: if (g_ZZPriceBuf[index] != EMPTY_VALUE) Я так понял, здесь придётся для этой задачи сделать массив буфера динамическим? (если, конечно, это возможно. Вижу, что, вроде как, размер массива g_ZZPriceBuf меньше, чем g_ZZPriceBuf[index] на индексе в цикле. Вот код



полная версия страницы