Русский

Учебник по MQL4  Создание обычной программы  Функция обработки ошибок

Функция обработки ошибок


Ошибки, возникающие при исполнении торговых приказов можно разделить на две группы - преодолимые и критические. К преодолимым ошибкам относятся все ошибки, сопровождающие отказ сервера, после которых можно продолжать торговлю. Например, торговый приказ может быть отклонён брокером в случае, если на текущий момент в его распоряжении нет информации о текущих ценах. Такая ситуация может возникнуть в случае очень медленного рынка, т.е. в условиях, когда тики поступают редко. Или напротив, в условиях быстро меняющегося рынка, когда поступающих котировок слишком много, брокер не всегда может удовлетворить множество торговых заявок от трейдеров, и тогда возникает пауза перед исполнением приказа, а иногда - отказ. В подобных случаях эксперт, после исполнения некоторого кода, поставленного в соответствие коду ошибки, может продолжать работу, например, после некоторой паузы повторить торговый приказ.

К критическим относятся все ошибки, возникновение которых свидетельствует о каких-либо серьёзных нарушениях. Например, если счёт заблокирован, то отправлять торговые приказы на сервер нет никакого смысла. В этом случае эксперт должен вывести необходимое сообщение, и не выполнять повторение торгового приказа. В составе обычного эксперта функция обработки ошибок должна использоваться обязательно.


Пользовательская функция обработки ошибок Errors()

bool Errors( int Error )

Функция возвращает TRUE, если ошибка преодолимая и FALSE, если ошибка является критической или отсутствует.
Параметр Error может принимать любое значение и соответствовать коду ошибки, возникшей при попытке осуществить торговую операцию.

Пользовательская функция обработки ошибок Errors() оформлена в виде включаемого файла Errors.mqh:

//--------------------------------------------------------------------
// Errors.mqh
// Предназначен для использования в качестве примера в учебнике MQL4.
//--------------------------------------------------------------- 1 --
// Функция обработки ошибок.
// Возвращаемые значения:
// true - если ошибка преодолимая (т.е. можно продолжать работу)
// false - если ошибка критическая (т.е. торговать нельзя)
//--------------------------------------------------------------- 2 --
bool Errors(int Error) // Пользовательская функция
{
// Error // Номер ошибки
if(Error==0)
return(false); // Нет ошибки
Inform(15,Error); // Сообщение
//--------------------------------------------------------------- 3 --
switch(Error)
{ // Преодолимые ошибки:
case 129: // Неправильная цена
case 135: // Цена изменилась
RefreshRates(); // Обновим данные
return(true); // Ошибка преодолимая
case 136: // Нет цен. Ждём новый тик.
while(RefreshRates()==false) // До нового тика
Sleep(1); // Задержка в цикле
return(true); // Ошибка преодолимая
case 146: // Подсистема торговли занята
Sleep(500); // Простое решение
RefreshRates(); // Обновим данные
return(true); // Ошибка преодолимая
// Критические ошибки:
case 2 : // Общая ошибка
case 5 : // Старая версия клиентского терминала
case 64: // Счет заблокирован
case 133: // Торговля запрещена
default: // Другие варианты
return(false); // Критическая ошибка
}
//--------------------------------------------------------------- 4 --
}
//--------------------------------------------------------------------

Одним из вопросов, возникающих при составлении алгоритма функции обработки ошибок Errors(), является вопрос о том, что должна вернуть функция, если значение передаваемого параметра равно 0 (т.е. ошибки нет). В правильно написанном эксперте такая ситуация вообще не возникает. Однако при совершенствовании программы код может быть несколько изменён, при этом в каких-то случаях может передаваться и нулевое значение ошибки. Поэтому уже на этапе первоначальной разработки имеет смысл ввести в функцию несколько строк кода для случая, если значение Error равно 0 (блок 2-3).

Какой должна быть реакция функции Errors() на нулевое значение переменной Error, зависит от того, какой алгоритм используется для обработки значения, возвращаемого функцией. В рассматриваемом эксперте значение, возвращаемое функцией, принимается во внимание в исполнительных торговых функциях. Если функция Errors() возвращает значение true (ошибка преодолимая), то предпринимается повторная попытка осуществить торговую операцию. Если же возвращено значение false, то исполнение торговой функции прекращается и управление последовательно возвращается в вызывающую функцию, затем в функцию start() и клиентскому терминалу. Если выбирать между двумя этими вариантами, то случай, когда ошибки нет (Error = 0) соответствует второму варианту, а именно возвращаемому значению false. Этим гарантируется, что однажды исполненный приказ не будет повторён.

После вывода с помощью функции Inform() сообщения об ошибке управление передаётся в блок 3-4, оператору switch. Для каждого из рассматриваемых кодов ошибок в функции предусмотрен свой вариант case. Например, если возникла ошибка 136, то это значит, что на текущий момент у брокера нет цен, на основании которых он может принять правильное решение. Это значит также, что в период до ближайшего тика ситуация не изменится, т.е. нет необходимости многократно повторять один и тот же торговый приказ, он всё равно не будет исполнен. Правильным решением в этом случае является пауза - отсутствие какой-либо инициативы со стороны эксперта. Для этой цели используется простой способ определения нового тика - анализ значения, возвращаемого функцией RefreshRates(). Как только новый тик появляется, управление возвращается в вызвавшую функцию, в которой торговый приказ (при необходимости, после соответствующего анализа) повторяется.

При возникновении любой ошибки, которая, по мнению программиста, является критической, функция возвращает значение false. В этом случае в торговых функциях не будет осуществляться повтор торгового приказа, поэтому нет смысла и предпринимать какие-либо действия в функции Errors(). Все ошибки, рассмотрение которых не предусмотрено, также расцениваются как критические (вариант default). В общем случае список обрабатываемых кодов ошибок может быть расширен (см. Коды ошибок).