Для наглядности кусок кода с которым возникают проблемы (лишнее поубирал):
int ChannelDataPeriod = 21; void Channel() { double high, low; RefreshRates(); while(ChannelDataPeriod>=0) { high = iHigh(NULL,PERIOD_M15,ChannelDataPeriod); low = iLow(NULL,PERIOD_M15,ChannelDataPeriod); } }
Проверяйте, что возвращают функции iHigh и iLow (ссылки на документацию по MQL5, но то же самое справедливо и для MQL4). До тех пор, пока возвращается ошибка, происходит подгрузка данных.
Спасибо, если всё происходит в цикле while, я правильно понимаю, что нужно сделать так чтобы циклы продолжали работу, пока ошибка не будет исправлена:
int ExamplePeriod = 21; void Example() { while(ExamplePeriod>=0) { ResetLastError(); high = iHigh(NULL,PERIOD_M15,ExamplePeriod); if(GetLastError()!=0) continue; ///////// Повторяем цикл если ошибка low = iLow(NULL,PERIOD_M15,ExamplePeriod); if(GetLastError()!=0) continue; ///////// Повторяем цикл если ошибка k = ExamplePeriod-1+ChannelPeriod; while(k>=ExamplePeriod) { price=iHigh(NULL,PERIOD_M15,k); if(GetLastError()!=0) continue; ///////// Повторяем цикл если ошибка if(high<price) high=price; price=iLow(NULL,PERIOD_M15,k); if(GetLastError()!=0) continue; ///////// Повторяем цикл если ошибка if(low>price) low=price; k--; } UpBuffer[ExamplePeriod] = high; DnBuffer[ExamplePeriod] = low; MdBuffer[ExamplePeriod] = (high+low)/2; ExamplePeriod--; } }
Спасибо, если всё происходит в цикле while, я правильно понимаю, что нужно сделать так чтобы циклы продолжали работу, пока ошибка не будет исправлена:
Нет, нужно отдать управление терминалу. Загрузка данных происходит неопределенное время. Поэтому ожидать окончание загрузки нужно либо по приходу нового тика (по запуску OnTick()), либо в таймере (OnTimer()). Я обычно не заморачиваюсь с таймером, но для некоторых задач может потребоваться именно он. К примеру, если рынок закрыт, то следующий OnTick советник получит только с началом сессии.
Также, чтобы не проверять то, что вернула каждая из функций-таймсерий всегда и везде, можно использовать вызов функции IsTFDataReady() в начале OnTick().
Нет, нужно отдать управление терминалу. Загрузка данных происходит неопределенное время. Поэтому ожидать окончание загрузки нужно либо по приходу нового тика (по запуску OnTick()), либо в таймере (OnTimer()). Я обычно не заморачиваюсь с таймером, но для некоторых задач может потребоваться именно он. К примеру, если рынок закрыт, то следующий OnTick советник получит только с началом сессии.
Также, чтобы не проверять то, что вернула каждая из функций-таймсерий всегда и везде, можно использовать вызов функции IsTFDataReady() в начале OnTick().
Вышеописанная функция вызывается только при открытии сделок, а сами сделки открываются не на тиках, а на новых барах.
Тогда получается как-то так?
bool IsTFDataReady() { iTime(NULL, PERIOD_M15, 1); return GetLastError() == ERR_NO_ERROR; } void OnTick() { if(IsTFDataReady() == true) if(NewBar==true) Example(); } int ExamplePeriod = 21; void Example() { while(ExamplePeriod>=0) { high = iHigh(NULL,PERIOD_M15,ExamplePeriod); low = iLow(NULL,PERIOD_M15,ExamplePeriod); k = ExamplePeriod-1+ChannelPeriod; while(k>=ExamplePeriod) { price=iHigh(NULL,PERIOD_M15,k); if(high<price) high=price; price=iLow(NULL,PERIOD_M15,k); if(low>price) low=price; k--; } UpBuffer[ExamplePeriod] = high; DnBuffer[ExamplePeriod] = low; MdBuffer[ExamplePeriod] = (high+low)/2; ExamplePeriod--; } }
Нет, нужно отдать управление терминалу. Загрузка данных происходит неопределенное время. Поэтому ожидать окончание загрузки нужно либо по приходу нового тика (по запуску OnTick()), либо в таймере (OnTimer()). Я обычно не заморачиваюсь с таймером, но для некоторых задач может потребоваться именно он. К примеру, если рынок закрыт, то следующий OnTick советник получит только с началом сессии.
Также, чтобы не проверять то, что вернула каждая из функций-таймсерий всегда и везде, можно использовать вызов функции IsTFDataReady() в начале OnTick().
Или же так:
bool IsTFDataReady() { iTime(NULL, PERIOD_M15, 1); return GetLastError() == ERR_NO_ERROR; } int ExamplePeriod = 21; void Example() { int check=-1; while(check < 1) check = IsTFDataReady(); while(ExamplePeriod>=0) { high = iHigh(NULL,PERIOD_M15,ExamplePeriod); low = iLow(NULL,PERIOD_M15,ExamplePeriod); k = ExamplePeriod-1+ChannelPeriod; while(k>=ExamplePeriod) { price=iHigh(NULL,PERIOD_M15,k); if(high<price) high=price; price=iLow(NULL,PERIOD_M15,k); if(low>price) low=price; k--; } UpBuffer[ExamplePeriod] = high; DnBuffer[ExamplePeriod] = low; MdBuffer[ExamplePeriod] = (high+low)/2; ExamplePeriod--; } }
Второй вариант:
bool IsTFDataReady(int shift) { iTime(NULL, PERIOD_M15, shift); return GetLastError() == ERR_NO_ERROR; } int ExamplePeriod = 21; void Example() { int check=-1; while(check < 1) check = IsTFDataReady(ExamplePeriod); while(ExamplePeriod>=0) { high = iHigh(NULL,PERIOD_M15,ExamplePeriod); low = iLow(NULL,PERIOD_M15,ExamplePeriod); k = ExamplePeriod-1+ChannelPeriod; while(k>=ExamplePeriod) { price=iHigh(NULL,PERIOD_M15,k); if(high<price) high=price; price=iLow(NULL,PERIOD_M15,k); if(low>price) low=price; k--; } UpBuffer[ExamplePeriod] = high; DnBuffer[ExamplePeriod] = low; MdBuffer[ExamplePeriod] = (high+low)/2; ExamplePeriod--; } }
Третий вариант:
bool IsTFDataReady(int shift) { iTime(NULL, PERIOD_M15, shift); return GetLastError() == ERR_NO_ERROR; } int ExamplePeriod = 21; void Example() { int check=-1; while(check < 1) for(int z=0; z<=ExamplePeriod; z++) { if(IsTFDataReady(z)==0) break; check = IsTFDataReady(z); } while(ExamplePeriod>=0) { high = iHigh(NULL,PERIOD_M15,ExamplePeriod); low = iLow(NULL,PERIOD_M15,ExamplePeriod); k = ExamplePeriod-1+ChannelPeriod; while(k>=ExamplePeriod) { price=iHigh(NULL,PERIOD_M15,k); if(high<price) high=price; price=iLow(NULL,PERIOD_M15,k); if(low>price) low=price; k--; } UpBuffer[ExamplePeriod] = high; DnBuffer[ExamplePeriod] = low; MdBuffer[ExamplePeriod] = (high+low)/2; ExamplePeriod--; } }
Вышеописанная функция вызывается только при открытии сделок, а сами сделки открываются не на тиках, а на новых барах.
Тогда получается как-то так?
На мой взгляд, первый вариант наиболее надежный.
На мой взгляд, первый вариант наиболее надежный.
Спасибо, я пока остановился на этом варианте:
bool IsTFDataReady(int shift) { iTime(NULL, ExamplePeriod, shift); return GetLastError() == ERR_NO_ERROR; } ---------------------------------------------- for(int z=0; z<=ExamplePeriod; z++) { int check=-1; while(check < 1) check = IsTFDataReady(PERIOD_M15,z); } ---------------------------------------------- цикл расчета
Пару дней потестирую его, а там будет видно :) Все равно исходя из первого варианта мы получаем только предыдущий бар, а мне нужно получить несколько баров...
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Здравствуйте, столкнулся с такой проблемой:
Есть советник, который рассчитывает iHigh/iLow по M15. Если он установлен на чарт М15 или же в терминале просто открыт чарт М15, то всё корректно. Если же устанавливаем на любой другой чарт и в терминале нет открытого М15, то расчет происходит некорректно. При чем в тестере проблем не возникает - только при работе в реале. Уже сломал голову что делать :( Я так понимаю нужно как-то запросить историю баров через переменную Bars для M15?