Ты вообще код глядел, который показываю? А запускал его?
Я спрашивал не о том как заполнить буфер индикатора, а о том, почему если брать значения от АО не с текущего бара, то возвращаются пустые значения. Это понял - нет истории - она подгружается, и пока она подгружается АО с неродного тф возвращает ошибку "нет данных".
Вопрос теперь стоит так: как узнать что история по нужному тф полностью загружена чтобы не заходить в цикл индикатора?
Если в индикаторе использовать CopyBuffer для получения данных с другого индикатора, то нужно:
Перевернуть свой индикаторный буфер так, чтобы самый правый бар на графике соответствовал индексу "0" в индикаторном буфере.
Таким образом "текущий бар" в индикаторе "iMTF_AO.mq5" - это будет самый ПРАВЫЙ БАР на графике и он будет соответствовать индексу "0" в индикаторном буфере "Buffer[]"
И чтобы получить "текущий бар" с индикатора (CopyBuffer(handle,0,shift,1,array)) параметр "shift" должен быть равен "0".
Не хотите переворачивать индикаторный буфер - сделайте так (временно): AO(0) - это для понимания, как получить ИЗ ИНДИКАТОРА ЗНАЧЕНИЯ ДРУГОГО ИНДИКАТОРА. Возможно один или два раза выскочит ошибка - но это пока не построится таймсерия, а потом значения будут отдаваться стабильно.
Если в индикаторе использовать CopyBuffer для получения данных с другого индикатора, то нужно:
Перевернуть свой индикаторный буфер так, чтобы самый правый бар на графике соответствовал индексу "0" в индикаторном буфере.
Таким образом "текущий бар" в индикаторе "iMTF_AO.mq5" - это будет самый ПРАВЫЙ БАР на графике и он будет соответствовать индексу "0" в индикаторном буфере "Buffer[]"
И чтобы получить "текущий бар" с индикатора (CopyBuffer(handle,0,shift,1,array)) параметр "shift" должен быть равен "0".
Не хотите переворачивать индикаторный буфер - сделайте так (временно): AO(0) - это для понимания, как получить ИЗ ИНДИКАТОРА ЗНАЧЕНИЯ ДРУГОГО ИНДИКАТОРА. Возможно один или два раза выскочит ошибка - но это пока не построится таймсерия, а потом значения будут отдаваться стабильно.
1. В моём коде это есть, и было оно сразу:
ArraySetAsSeries(Buffer,true);int bars=Bars(NULL,PeriodForWork);
datetime time_limit=GetTime(Symbol(),PeriodForWork,bars-1);
int limit_p=GetBarShift(Symbol(),Period(),time_limit);
if(rates_total<1) return(0);
2. Так оно и есть.
3. shift равен индексу цикла i. А цикл идёт от начала исторических данных (rates_total-1) к концу (к текущим данным)
Другой вопрос, что нужно высчитать эти данные применительно к неродному тф чтобы не получать данные с отсутствующих баров. И нужно определять перед циклом, что история с нужного тф полностью синхронизирована.
3. shift равен индексу цикла i. А цикл идёт от начала исторических данных (rates_total-1) к концу (к текущим данным)
Другой вопрос, что нужно высчитать эти данные применительно к неродному тф чтобы не получать данные с отсутствующих баров. И нужно определять перед циклом, что история с нужного тф полностью синхронизирована.
Переделайте цикл обращения к AO: поставьте от "0" и до какого-то значения (сейчас от какого-то значения до нуля). Когда пойдут ошибки - сразу сравните: кол-во рассчитанных баров ("limit_p") и rates_total текущего индикатора.
Добавлено: и вот эти строки стирают все старания рассчитанного "limit" (если обращаемся к неродному таймфрейму):
if(limit>1)
{
limit=rates_total-1;
}
грубо говоря сначала (при обращении к неродному таймфрейму) "limit" стал равен 156, а ниже БАЦ! и "limit" уже стал "154566666666"
Но в этом тестовом индикаторе данные получаем как с текущего тф (на нём идёт отображение расчётов в OnCalculate()), так и с заданного - для получения данных АО с заданного тф.
Пока не склеилось в уме как красиво обсчитать все необходимые данные по количеству баров - ведь цикл на текущем тф стоит начинать с бара, соответствующего времени бара истории с самыми первыми существующими данными либо текущего тф, либо заданного - где их меньше - с того бара и начинаем цикл. При этом ещё и limit должен верно просчитываться чтобы отлавливать появление нового бара, что должно приводить к полному пересчёту, либо к пересчёту только текущего бара (в зависимости от того, что произошло - открытие нового бара, либо подгрузка истории).
Может быть, я по своему обыкновению стараюсь сразу всё продумать, и думаю много лишнего...
Переделайте цикл обращения к AO: поставьте от "0" и до какого-то значения (сейчас от какого-то значения до нуля). Когда пойдут ошибки - сразу сравните: кол-во рассчитанных баров ("limit_p") и rates_total текущего индикатора.
Добавлено: и вот эти строки стирают все старания рассчитанного "limit" (если обращаемся к неродному таймфрейму):
грубо говоря сначала (при обращении к неродному таймфрейму) "limit" стал равен 156, а ниже БАЦ! и "limit" уже стал "154566666666"
Да, про это я сразу написал что напортачил тут второпях.
Но цикл переделывать точно не буду - есть достаточно сложный индикатор, в котором всё построено на просчёте истории от начала к концу - проще пересчитать лимиты и добиться нормального получения данных, нежели переписать полностью весь индикатор - всю его логику.
Нет, не пробовал ещё. Про поддержку актуальности данных видел, помню-знаю.
Но изначально нужно выходить из OnCalculate() если данные по заданному тф и текущему ещё не синхронизированы.
Про текущий понятно:
Все не совсем так. При начальной загрузке терминала с индикатором можете получить не то, что ожидаете. В течение дня и при обрывах связи - тоже могут быть косяки.
Про выход из OnCalculate(): первый запрос Bars() делаете на этапе инициализации, дальше в OnCalculate() проверяете синхронизации текущего и нужного ТФ-ов. Если нет синхронизации - выход.
Да, про это я сразу написал что напортачил тут второпях.
Но цикл переделывать точно не буду - есть достаточно сложный индикатор, в котором всё построено на просчёте истории от начала к концу - проще пересчитать лимиты и добиться нормального получения данных, нежели переписать полностью весь индикатор - всю его логику.
Артём, что значит "от начала к концу"?
А думаешь переворачивать все массивы лучший выход?
Зачем
ArraySetAsSeries(Buffer,true);
если копируешь всего 1 значение?
В функцию CopyBuffer() при копировании не текущего ТФ лучше передать время нужного бара. Иначе будет копироваться не тот бар который хочешь.
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-того бара.
intCopyBuffer(
int indicator_handle, // handle индикатора int buffer_num, // номер буфера индикатора datetime start_time, // с какой даты int count, // сколько копируем double buffer[] // массив, куда будут скопированы данные
);
Ты вообще код глядел, который показываю? А запускал его?
Я спрашивал не о том как заполнить буфер индикатора, а о том, почему если брать значения от АО не с текущего бара, то возвращаются пустые значения.
Это понял - нет истории - она подгружается, и пока она подгружается АО с неродного тф возвращает ошибку "нет данных".
Вопрос теперь стоит так: как узнать что история по нужному тф полностью загружена чтобы не заходить в цикл индикатора?
Если в индикаторе использовать 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-того бара.