Даже если Вы создадите идеального «эксперта», ошибок не избежать, уж очень много факторов которых Вы не можете контролировать (связь, провайдер, ДЦ, терминал и тд.). Ошибки при выполнении торговых операций (открытие, удаление или модификация ордеров) можно разделить на две группы.
Первая – это когда «советник» не верно оформляет «заказ» на торговую операцию. Такой ордер терминал не исполняет а возвращает нам код ошибки. Код ошибки это число, например ошибка номер 130 – неправильно выставлены стопы.
Вторая – это когда с нашей стороны ордер оформлен верно и терминал послал его на исполнение, возвращается ошибка обрив связи, брокер занят и тд.
Итак научим наш «советник» распознавать эти ошибки и реагировать на них.
При установке ордеров мы используем торговую функцию OrderSend, при успешном исходе она возвращает номер открытого ордера, а при неудачи (ошибке) -1.
При удалении (OrderDelete), если ордер удален получим TRUE, если нет FALSE (ошибка).
Что бы узнать код ошибки вызывается функция GetLastError(), которая возвращает номер последней ошибки.
После каждой торговой операции (открытие, модификация и удаление), проверяем на наличие ошибок, в нашем «советнике» таких блоков где нужно вставить код четыре, каждый раз после функции OrderSend и OrderDelete.
Если ошибка есть – вызываем функцию GetLastError. Получим номер ошибки, но этот номер нам нужен как зайцу стопсигнал, все эти номера все одно не упомнишь. Вызываем функцию inf и передаем ей номер ошибки.
inf(15, GetLastError()); // если дошли сюда значит есть ошибка... узнаем какая именно
В этой функции есть блок который распознает ошибку и уже на «человеческом» языке сообщит нам в чем проблема.
case 15: switch(Number) // Переход на номер ошибки { case 2: Graf_Text = "Общая ошибка."; break; case 4: Graf_Text = "Торговый сервер занят."; break; case 129: Graf_Text = "Неправильная цена. "; break; case 135: Graf_Text = "Цена изменилась."; break; case 136: Graf_Text = "Нет цен. Ждём новый тик.."; break; case 137: Graf_Text = "Брокер занят."; break; case 146: Graf_Text = "Подсистема торговли занята."; break; case 5 : Graf_Text = "Старая версия терминала."; break; case 64: Graf_Text = "Счет заблокирован."; break; case 133: Graf_Text = "Торговля запрещена"; break; case 134: Alert("Недостаточно денег для совершения операции."); return(0); // Выход из функции default: Graf_Text = StringConcatenate("Возникла ошибка ",Number); } break;
Здесь нет ничего сложного и Вы сами можете сделать так, чтобы «советник» обрабатывал те ошибки, которые Вы посчитаете наиболее важными.
То что мы знаем об ошибке – хорошо, еще лучше чтобы «эксперт» сам реагировал на конкретную ситуацию. Например, если есть ошибка 137 (Брокер занят), а «советник» будет продолжать посылать по 100 запросов в секунду, счет могут заблокировать. В этом и подобных случаях чтобы наш «эксперт» не был назойливым при подобных ошибках будем делать паузу (пережидать несколько секунд).
if(IsTesting() == false) Sleep(5000); // если это не тестирование - "засыпаем" на 5 секунд.
Sleep() – функция останавливает «эксперта» на заданное время.
IsTesting() – функция возвращает TRUE в режиме тестирования, иначе возвращает FALSE.
Если это тестирование то паузы не нужны.
Вносим изменения в блок обработки ошибок.
case 15: switch(Number) // Переход на номер ошибки { case 2: Graf_Text = "Общая ошибка."; break; case 4: Graf_Text = "Торговый сервер занят."; if(IsTesting() == false) Sleep(5000); // если это не тестирование - "засыпаем" на 5 секунд. break; case 129: Graf_Text = "Неправильная цена."; break; case 130: Graf_Text = "Неправильная дистанция."; break; case 135: Graf_Text = "Цена изменилась."; break; case 136: Graf_Text = "Нет цен. Ждём новый тик.."; if(IsTesting() == false) Sleep(1); // если это не тестирование - "засыпаем" на 1 миллисекунду. break; case 137: Graf_Text = "Брокер занят."; if(IsTesting() == false)Sleep(5000); // если это не тестирование - "засыпаем" на 5 секунд. break; case 146: Graf_Text = "Подсистема торговли занята."; if(IsTesting() == false) Sleep(500); // если это не тестирование - "засыпаем" на пол секунды. break; case 5 : Graf_Text = "Старая версия терминала."; break; case 64: Graf_Text = "Счет заблокирован."; break; case 133: Graf_Text = "Торговля запрещена"; break; case 134: Alert("Недостаточно денег для совершения операции."); return(0); // Выход из функции default: Graf_Text = StringConcatenate("Возникла ошибка ",Number); } break;
Теперь «советник» будет не только сообщать об ошибках но и реагировать на них.
Исходник: TradeOnNews-0.3
Советник «Болтун» — https://forexlab.ru/mql-talk-advisor/