Функция обработки ошибок. Нужна помощь!

 

Всем форумчанам привет!

Пишу своего первого полноценного советника и возник такой вопрос. Как правильно использовать функцию обработки ошибок, чтобы при возникновении непреодолимой ошибки при отправки ордера, эксперт перестал делать запросы на отправку ордера. Не соображу как это сделать. Помогите!

Имеем допустим такую программу:

void OnTick()

   if (OpenOrder ()!=0)

   if (Error()==false         //Не знаю что тут писать и как организовать, чтобы при возникновения   Error()==false советник переставал выполнять торговую функцию OpenOrder ()

return;  

 int OpenOrder (int Error=0, double price=0, color clr=clrBlack)                                     // Вызов функции

{

  RefreshRates();                                                                           

  int Order=OrderSend(_Symbol,typeOrder,Lot,price,30,0,0,comment,Magic,0,clr);           // Отправляем ордер

  if (Order<0)                                                                                                             // Проверка наличия ошибок

  Error=GetLastError();                                                                                               // Получаем номер ошибки, если есть

return(Error);  

bool Error()

{

 switch(OpenOrder())

 {

 case допустим 'преодолимая ошибка':   Sleep(200); RefreshRates();return (true);

 case 'непреодолимая ошибка':   return (false); 

}

 

Может как то по-другому все это организовать? Я в этом деле непрофессионал, нужна помощь. Может у кого-то написан универсальный алгоритм, поделитесь опытом.

 Всем заранее спасибо!

 

Если Вам нужно совсем завершить работу советника при какой-то ошибке, то посмотрите в сторону ExpertRemove().

Если нужно только какую-то часть программы перестать выполнять, то можно создать static-переменную булевского типа, при ошибке задать ей true и затем если она истинна, то не выполнять заданный участок кода:

void OnTick()
{ 
   static bool isStopped = false;
   
   if(!isStopped)
   {
      if (OpenOrder ()!=0) // правда я не очень понял эту строку, но это Вам уже видней :)
   
      if (!Error())
      {
         isStopped = true;
      }
   }
   else
   {
      Comment("Произошла критическая ошибка #..., часть программы XX не выполняется");
   }
   
   return;  
} 

Можно то же самое сделать с глобальной переменной, но я бы рекомендовал без острой нужды к глобальным переменным не прибегать.

Примечание: static-переменные сохраняют свои значения при переинициализациях из-за переключений ТФ, инструментов и т.п. Т.е. чтобы сбросить ошибку при варианте выше будет нужно полностью удалить эксперта с графика и снова его запустить.

ExpertRemove - Документация на MQL4
  • docs.mql4.com
ExpertRemove - Документация на MQL4
 

Собсна, а нафига вообще эта функция обработки ошибок? Просто пишите нормальную универсальную функцию int OpenOrder(....) с разовым проходом, а не зацикленную, пока не откроется.

И что за непреодолимая ошибка такая? Пример можете привести? 

 
Sergey Odnoromanenko:

Собсна, а нафига вообще эта функция обработки ошибок? Просто пишите нормальную универсальную функцию int OpenOrder(....) с разовым проходом, а не зацикленную, пока не откроется.

И что за непреодолимая ошибка такая? Пример можете привести? 

Например не хватает средств на счете. Сов будет бесконечно слать ордер, но он не откроется.
 
Sergey Odnoromanenko:

Собсна, а нафига вообще эта функция обработки ошибок? Просто пишите нормальную универсальную функцию int OpenOrder(....) с разовым проходом, а не зацикленную, пока не откроется.

И что за непреодолимая ошибка такая? Пример можете привести? 

Или например просто

Общая ошибка

Неправильные параметры

Старая версия клиентского терминала

Недостаточно прав

Недопустимая операция, нарушающая функционирование сервера

Счет заблокирован

Неправильный номер счета

Неправильная цена

Неправильные стопы

Неправильный объем

Рынок закрыт

Торговля запрещена

 
Sergey Odnoromanenko:

Собсна, а нафига вообще эта функция обработки ошибок? Просто пишите нормальную универсальную функцию int OpenOrder(....) с разовым проходом, а не зацикленную, пока не откроется.

Напишите пример, как правильно!
 
Alexey Zykov:
Например не хватает средств на счете. Сов будет бесконечно слать ордер, но он не откроется.
Так ставьте нужные условия, и сов будет отправлять ордер только по этим условиям!
 
Boris:
Так ставьте нужные условия, и сов будет отправлять ордер только по этим условиям!
Другие ошибки перечислены выше! Возможны и другие варианты
 
Sergey Odnoromanenko:

Собсна, а нафига вообще эта функция обработки ошибок? Просто пишите нормальную универсальную функцию int OpenOrder(....) с разовым проходом, а не зацикленную, пока не откроется.

И что за непреодолимая ошибка такая? Пример можете привести? 

То есть как должно работать:

1-приходит новый тик---проверяются условия на открытия, если они выполняются то ---функция отправки ордера----если позицию открыть не удалось по причине неприодолимой ошибки, то предыдущие  две функции с приходом нового тика больше не выполнять

 
Alexey Zykov:

То есть как должно работать:

1-приходит новый тик---проверяются условия на открытия, если они выполняются то ---функция отправки ордера----если позицию открыть не удалось по причине неприодолимой ошибки, то предыдущие  две функции с приходом нового тика больше не выполнять

Примерная структура функции OpenOrder(тут передаваемые в функцию параметры)

int err=ERR_NO_ERROR, ticket=EMPTY;

Цикл по количеству попыток открытия ордера при неудачной попытке

Сбрасываем переменные --> ResetLastError(); err=GetLastError(); Отсылаем запрос --> ticket=OrderSend()

Если ticket больше ноля -->останавливаем цикл --> break; Иначе проверяем код ошибки в err

Если в err содержится непреодолимая ошибка --> return(EMPTY); Иначе обрабатываем ошибку

Обработка ошибки индивидуальная для каждого типа.

В конце функции за пределами тела цикла возвращаем значение переменной тикета --> return(ticket);


Вызываем функцию примерно так:

TicketOpenPos=OpenOrder(тут необходимые параметры);

if(TicketOpenPos<0)

   {
    // функция OpenOrder() нарвалась на непреодолимую ошибку или не смогла открыть позицию за заданное количество попыток
    // (можно дополнительно возвращать значение err из OpenOrder и здесь его проверить   и обработать)
   }

 
Artyom Trishkin:

Примерная структура функции OpenOrder(тут передаваемые в функцию параметры)

int err=ERR_NO_ERROR, ticket=EMPTY;

Цикл по количеству попыток открытия ордера при неудачной попытке

Сбрасываем переменные --> ResetLastError(); err=GetLastError(); Отсылаем запрос --> ticket=OrderSend()

Если ticket больше ноля -->останавливаем цикл --> break; Иначе проверяем код ошибки в err

Если в err содержится непреодолимая ошибка --> return(EMPTY); Иначе обрабатываем ошибку

Обработка ошибки индивидуальная для каждого типа.

В конце функции за пределами тела цикла возвращаем значение переменной тикета --> return(ticket);


Вызываем функцию примерно так:

TicketOpenPos=OpenOrder(тут необходимые параметры);

if(TicketOpenPos<0)

   {
    // функция OpenOrder() нарвалась на непреодолимую ошибку или не смогла открыть позицию за заданное количество попыток
    // (можно дополнительно возвращать значение err из OpenOrder и здесь его проверить   и обработать)
   }

Спасибо большое! Стало понятнее. Вот только зачем использовать ResetLastError(), ведь вызов GetLastError() обнуляет переменную _LastError.