Особенности языка mql5, тонкости и приёмы работы - страница 31
Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Ты вообще код глядел, который показываю? А запускал его?
Я спрашивал не о том как заполнить буфер индикатора, а о том, почему если брать значения от АО не с текущего бара, то возвращаются пустые значения.
Это понял - нет истории - она подгружается, и пока она подгружается АО с неродного тф возвращает ошибку "нет данных".
Вопрос теперь стоит так: как узнать что история по нужному тф полностью загружена чтобы не заходить в цикл индикатора?
Если в индикаторе использовать CopyBuffer для получения данных с другого индикатора, то нужно:
Не хотите переворачивать индикаторный буфер - сделайте так (временно): AO(0) - это для понимания, как получить ИЗ ИНДИКАТОРА ЗНАЧЕНИЯ ДРУГОГО ИНДИКАТОРА. Возможно один или два раза выскочит ошибка - но это пока не построится таймсерия, а потом значения будут отдаваться стабильно.
Если в индикаторе использовать CopyBuffer для получения данных с другого индикатора, то нужно:
Не хотите переворачивать индикаторный буфер - сделайте так (временно): AO(0) - это для понимания, как получить ИЗ ИНДИКАТОРА ЗНАЧЕНИЯ ДРУГОГО ИНДИКАТОРА. Возможно один или два раза выскочит ошибка - но это пока не построится таймсерия, а потом значения будут отдаваться стабильно.
1. В моём коде это есть, и было оно сразу:
2. Так оно и есть.
3. shift равен индексу цикла i. А цикл идёт от начала исторических данных (rates_total-1) к концу (к текущим данным)
Другой вопрос, что нужно высчитать эти данные применительно к неродному тф чтобы не получать данные с отсутствующих баров. И нужно определять перед циклом, что история с нужного тф полностью синхронизирована.
1. В моём коде это есть, и было оно сразу:
2. Так оно и есть.
3. shift равен индексу цикла i. А цикл идёт от начала исторических данных (rates_total-1) к концу (к текущим данным)
Другой вопрос, что нужно высчитать эти данные применительно к неродному тф чтобы не получать данные с отсутствующих баров. И нужно определять перед циклом, что история с нужного тф полностью синхронизирована.
Переделайте цикл обращения к AO: поставьте от "0" и до какого-то значения (сейчас от какого-то значения до нуля). Когда пойдут ошибки - сразу сравните: кол-во рассчитанных баров ("limit_p") и rates_total текущего индикатора.
Добавлено: и вот эти строки стирают все старания рассчитанного "limit" (если обращаемся к неродному таймфрейму):
грубо говоря сначала (при обращении к неродному таймфрейму) "limit" стал равен 156, а ниже БАЦ! и "limit" уже стал "154566666666"
Пробовали синхронизацию? Также разработчики советуют поддерживать актуальность данных нужных ТФ/символа через таймер.
Нет, не пробовал ещё. Про поддержку актуальности данных видел, помню-знаю.
Но изначально нужно выходить из OnCalculate() если данные по заданному тф и текущему ещё не синхронизированы.
Про текущий понятно:
Про заданный - нужно проверять его Bars() - их количество вместо rates_total.
А вот с limit ещё не сообразил - его на текущем тф можно проверить так (как пример из не этого индикатора):
Но в этом тестовом индикаторе данные получаем как с текущего тф (на нём идёт отображение расчётов в OnCalculate()), так и с заданного - для получения данных АО с заданного тф.
Пока не склеилось в уме как красиво обсчитать все необходимые данные по количеству баров - ведь цикл на текущем тф стоит начинать с бара, соответствующего времени бара истории с самыми первыми существующими данными либо текущего тф, либо заданного - где их меньше - с того бара и начинаем цикл. При этом ещё и limit должен верно просчитываться чтобы отлавливать появление нового бара, что должно приводить к полному пересчёту, либо к пересчёту только текущего бара (в зависимости от того, что произошло - открытие нового бара, либо подгрузка истории).
Может быть, я по своему обыкновению стараюсь сразу всё продумать, и думаю много лишнего...
Переделайте цикл обращения к AO: поставьте от "0" и до какого-то значения (сейчас от какого-то значения до нуля). Когда пойдут ошибки - сразу сравните: кол-во рассчитанных баров ("limit_p") и rates_total текущего индикатора.
Добавлено: и вот эти строки стирают все старания рассчитанного "limit" (если обращаемся к неродному таймфрейму):
грубо говоря сначала (при обращении к неродному таймфрейму) "limit" стал равен 156, а ниже БАЦ! и "limit" уже стал "154566666666"
Да, про это я сразу написал что напортачил тут второпях.
Но цикл переделывать точно не буду - есть достаточно сложный индикатор, в котором всё построено на просчёте истории от начала к концу - проще пересчитать лимиты и добиться нормального получения данных, нежели переписать полностью весь индикатор - всю его логику.
Нет, не пробовал ещё. Про поддержку актуальности данных видел, помню-знаю.
Но изначально нужно выходить из OnCalculate() если данные по заданному тф и текущему ещё не синхронизированы.
Про текущий понятно:
Все не совсем так. При начальной загрузке терминала с индикатором можете получить не то, что ожидаете. В течение дня и при обрывах связи - тоже могут быть косяки.
Про выход из OnCalculate(): первый запрос Bars() делаете на этапе инициализации, дальше в OnCalculate() проверяете синхронизации текущего и нужного ТФ-ов. Если нет синхронизации - выход.
Да, про это я сразу написал что напортачил тут второпях.
Но цикл переделывать точно не буду - есть достаточно сложный индикатор, в котором всё построено на просчёте истории от начала к концу - проще пересчитать лимиты и добиться нормального получения данных, нежели переписать полностью весь индикатор - всю его логику.
Артём, что значит "от начала к концу"?
А думаешь переворачивать все массивы лучший выход?
Зачем
ArraySetAsSeries(Buffer,true);
если копируешь всего 1 значение?
В функцию CopyBuffer() при копировании не текущего ТФ лучше передать время нужного бара. Иначе будет копироваться не тот бар который хочешь.
1. Артём, что значит "от начала к концу"?
2. А думаешь переворачивать все массивы лучший выход?
3. Зачем
4. если копируешь всего 1 значение?
В функцию CopyBuffer() при копировании не текущего ТФ лучше передать время нужного бара. Иначе будет копироваться не тот бар который хочешь.
1. Начало исторических данных - самый первый бар в истории, имеющий наименьшее время открытия, конец исторических данных - текущий бар.
2. С четвёрки на пятёрку переписываю.
3. Ну потому, что в Buffer[] записываются данные в цикле от rates_total-1 до 0. Если не делать его как таймсерию, то отображение будет на графике задом-наперёд.
4. Копирую в один момент времени одно значение, соответствующее данным бара i заданного тф.
ЗЫ. Смотри как лаконично и легко получать данные не текущего тф в mql4, и они получаются успешно, и всё работает как задумано. И как странно получать данные индикатора в mql5, и они не получаются никак - всегда ошибка 4806 если в функцию получения данных АО передать таймфрейм, не соответствующий таймфрейму графика, на котором работает индикатор.
При этом в OnInit() создаётся хэндл индикатора с соответствующим выбранному в настройках тф, с которого нужно получать данные:
handle_ao=iAO(symbol,periodForWork);
Т.е., всегда, в любой момент времени, как бы мы не переключали тф, хэндл создаётся с нужным (выбранным в настройках) тф. Но данные АО можно получить лишь при совпадении выбранного тф в настройках и текущего тф. Если они не совпадают, то всегда возвращается ноль из функции.
Вопрос: ПОЧЕМУ?
1. Начало исторических данных - самый первый бар в истории, имеющий наименьшее время открытия, конец исторических данных - текущий бар.
2. С четвёрки на пятёрку переписываю.
3. Ну потому, что в Buffer[] записываются данные в цикле от rates_total-1 до 0. Если не делать его как таймсерию, то отображение будет на графике задом-наперёд.
4. Копирую в один момент времени одно значение, соответствующее данным бара i заданного тф.
ЗЫ. Смотри как лаконично и легко получать данные не текущего тф в mql4, и они получаются успешно, и всё работает как задумано. И как странно получать данные индикатора в mql5, и они не получаются никак - всегда ошибка 4806 если в функцию получения данных АО передать таймфрейм, не соответствующий таймфрейму графика, на котором работает индикатор.
При этом в OnInit() создаётся хэндл индикатора с соответствующим выбранному в настройках тф, с которого нужно получать данные:
Т.е., всегда, в любой момент времени, как бы мы не переключали тф, хэндл создаётся с нужным (выбранным в настройках) тф. Но данные АО можно получить лишь при совпадении выбранного тф в настройках и текущего тф. Если они не совпадают, то всегда возвращается ноль из функции.
Вопрос: ПОЧЕМУ?
1. Просто уточнение. Теперь понятно что говорим об одном и том-же.
2. Это я понял, но не соглашусь что для этого обязательно переворачивать массивы. Разве обязательно иметь один индикатор для двух терминалов??? Почти так-же как сделать 2в1 косу и топор.
3. Buffer[] как я понял используется приёмником в функции CopyBuffer() для получения всего 1 значения индикатора.
4. На самое главное ты не обратил внимания. Начало копирования значения индикатора надо определять не индексом бара, а временем i-того бара.