Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1188

 
Ivan_Invanov:
Вообще судя по вашему ответу, Вы сами не очень понимаете, как работает программа. Раз кажется, что это глупый вопрос. Да как и предыдущий комментатор думает, что она останавливается. Просто по опыту программирования в других языках думаю, что она выполняет в цикле своё тело, и когда событие приходит, она в него ныряет. Если программа выполняет в цикле своё тело, то это объясняет, почему так написана программа.

Программа с приходом события "новый тик" запускается в обработчике OnTick(), выполняется до конца и останавливается. С приходом нового тика всё повторяется сначала. Если за время выполнения программы пришёл следующий тик, а программа ещё не завершила обработку прошлого тика (всё ещё работает), то этот тик пропускается.

Программы на MQL не зацикленные. Имеют три точки входа - OnInit(), OnDeinit() и OnTick()

При запуске выполняется OnInit(), затем при поступлении тика - OnTick(), при завершении работы - OnDeinit().

Есть ещё другие обработчики. Но вам лучше просто открыть справку, чем просить её сюда кого-нибудь продублировать.

Документация по MQL5: Программы MQL5
Документация по MQL5: Программы MQL5
  • www.mql5.com
Для того чтобы mql5-программа могла работать, она должна быть скомпилирована (кнопка "Компилировать" или клавиша F7). Компиляция должна пройти без ошибок (допускаются предупреждения, которые необходимо проанализировать). При этом в соответствующей директории Эксперты, пользовательские индикаторы и скрипты прикрепляются к одному из открытых...
 

Здравствуйте. Работая над своим индикатором обнаружил сбой при перезапуске терминала. На основе этого бага я сделал небольшой исходник для его тестирования:

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+

class Loader {
private:
  string symbol;
  ENUM_TIMEFRAMES timeframe;

public:  
  Loader(): symbol(Symbol()), timeframe(Period()) 
  {
    Print(__FUNCTION__ + " symbol: " + symbol + " timeframe: " + EnumToString(timeframe));
    ResetLastError();
    Print(__FUNCTION__ + " bars: " + (string)iBars(symbol, timeframe)); // Данный вызов iBars() даёт 0 при перезапуске терминала
    Print(__FUNCTION__ + " Error: " + (string)GetLastError());
    Print(__FUNCTION__ + " bars (2): " + (string)iBars(Symbol(), Period())); // Этот же вызов iBars() работает нормально
  }
};

Loader * loader;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit() {
//--- indicator buffers mapping
  loader = new Loader();
//---
  return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnDeinit(const int reason) {
  delete loader;
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[]
) {
  return(rates_total);
}

Если данный пример бросить на график (или же это первый запуск терминала после запуска системы) то всё работает нормально. В журнале пишет следующее:

2020.06.24 21:05:50.773 Loader::Loader symbol: EURUSD timeframe: PERIOD_H1

2020.06.24 21:05:50.773 Loader::Loader bars: 140433

2020.06.24 21:05:50.773 Loader::Loader Error: 0

2020.06.24 21:05:50.773 Loader::Loader bars (2): 140433


Но если я перезапускаю терминал с данным индикатором, то получаю ошибку:

2020.06.24 21:07:34.963 Loader::Loader symbol: EURUSD timeframe: PERIOD_H1

2020.06.24 21:07:34.963 Loader::Loader bars: 0

2020.06.24 21:07:34.963 Loader::Loader Error: 4401

2020.06.24 21:07:34.964 Loader::Loader bars (2): 140433

Символ и таймфрейм нормально проинициализировались

2020.06.24 21:07:34.963 Loader::Loader symbol: EURUSD timeframe: PERIOD_H1

Но iBars(symbol, timeframe) почему-то дает 0

2020.06.24 21:07:34.963 Loader::Loader bars: 0

При этом появляется ошибка 4401.

Но iBars(Symbol(), Period()) отрабатывает отлично.

2020.06.24 21:07:34.964 Loader::Loader bars (2): 140433

Хоть symbol = Symbol(), а timeframe = Period() согласно сообщениям в журнале (даже во время лага, при перезапуске терминала). Как iBars(symbol, timeframe), с абсолютно корректными symbol и timeframe может давать ноль, в то время как iBars(Symbol(), Period()) нормально отрабатывает, если параметры в функциях, согласно журналу, одинаковые?

Запуск платформы - Для продвинутых пользователей - Справка по MetaTrader 5
Запуск платформы - Для продвинутых пользователей - Справка по MetaTrader 5
  • www.metatrader5.com
По завершении установки в меню "Пуск" создается группа программ торговой платформы, а на рабочем столе дополнительно помещается ярлык программы. Используйте их для запуска. Нельзя запускать одновременно две копии платформы из одной директории. Чтобы одновременно запустить несколько копий, установите соответствующее количество программ в разные...
Файлы:
Test.mq5  7 kb
 
Кто знает модератора этой ветки?
 

Как открыть демо-счет МТ4 на MetaQuotes Demo? Раньше работало без проблем, сейчас на последней странице диалога пишет: Registration, Wait a little, please, и в таком состоянии бездействует бесконечно, поля с логином и паролем остаются пустыми. Никаких сообщений в логе. Пробовал и "демо", и "реал", и разные типы счетов.

UPD. Попробовал демо одного брокера - та же фигня.

 
Artyom Trishkin:

Программа с приходом события "новый тик" запускается в обработчике OnTick(), выполняется до конца и останавливается. С приходом нового тика всё повторяется сначала. Если за время выполнения программы пришёл следующий тик, а программа ещё не завершила обработку прошлого тика (всё ещё работает), то этот тик пропускается.

Программы на MQL не зацикленные. Имеют три точки входа - OnInit(), OnDeinit() и OnTick()

При запуске выполняется OnInit(), затем при поступлении тика - OnTick(), при завершении работы - OnDeinit().

Есть ещё другие обработчики. Но вам лучше просто открыть справку, чем просить её сюда кого-нибудь продублировать.

Спасибо. Да я это понимаю, просто функция написана в теле программы. Может я гдето не заметил ее вызов.
 
Ivan_Invanov:
Спасибо. Да я это понимаю, просто функция написана в теле программы. Может я гдето не заметил ее вызов.

Мы как можем увидеть то, о чём вы говорите? Приведите пример.

 
Artyom Trishkin:

Мы как можем увидеть то, о чём вы говорите? Приведите пример.

Спасибо еще раз, да, я не заметил вызов, я сейчас просмотрел , и ее вызывала функция, которая открывает сделки.
 
Ivan_Invanov:
Спасибо. Да я это понимаю, просто функция написана в теле программы. Может я гдето не заметил ее вызов.

в mql4 функции пишутся в любом порядке, выше ниже по барабану, может показаться что она работает раньше или позже. В с++ такого нет там все функции могут сработать только в порядке очереди написания и если вы хотите её вызвать то она должна быть определена до место вызова иначе программа падает. Человек показывал как сделать так чтобы в разнобой функции писать но я уже не помню как это делать на с++, да и это мало важно.

 
Ivan_Invanov:

Приветствую. Помогите пожалуйста. У меня вот такой вопрос. Правильно ли я понимаю. Что программа выполняется с начала и до конца, но обрывается, если приходит событие, например тик, начинает выполняться функция ontick, потом она заканчивает выполнение, и опять выполняется программа сначала? Этот вопрос связан вот с чем, где мне писать например размер торгового лота? в теле программы или в функции ontick ?

Я смотрю на официального бота, который как пример в терминале , там обсчёт лота выполняется в теле программы, и я не понял почему так.

У меня лот высчитывается так

#property link      "http://www.mql5.com"
input double CheckLots = 0.01;
input int    Persent   = 5;
   double Lots=NormalizeDouble(AccountBalance()*CheckLots/1000-0.005,2);  

стоит в начале советника...и ставил в самый конец кода

Когда идет обращение в функции OnTick к переменной Lots, то советник находит и пересчитывает.

 

@Artyom Trishkin

Вы модератор в этой ветке?

Причина обращения: