Ордера исполняются, несмотря на ошибку (4/190 2006_02_06) - страница 3

 
Плиз, конкретно, табличку:
код ошибки - что делать
 
Плиз, конкретно, табличку:
код ошибки - что делать

Поддерживаю. Разве обязательно наступать на все грабли, если кто-то знает, как их обойти. А ещё лучше- завести ветку для разработки типовой функции торговой операции. Я так понимаю, что если разработчики выложат пример, то на них будет висеть ответственность за правильное исполнение, поэтому не выкладывают. Так давайте вместе, во главе с Метаквотес, разработаем максимально работоспособную функцию, потестируем её у разных брокеров и будем пользоваться. Я для этой цели советничка написал, который тупо каждые 5 минут открывает-закрывает позиции, и на разных счетах использует разные библиотеки торговых функций. Слежу- пытаюсь выяснить, какой вариантр меньше сбоев даёт.И ещё- один знакомый писал, что у него проблемы с двой ным открытием у одного брокера, а у другого нет. Так что это ещё и от брокера зависит.
 
Поддерживаю.
Я уже несколько раз об этом говорил.
Требуется рекомендуемый разработчиками набор типовых торговых решений.
+ посвящённая этому статья.
 

Плиз, конкретно, табличку:
код ошибки - что делать


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

Все типы ошибок есть в документации. Реагировать с повтором сделки надо только на самые простые типа неправильных цен.

Приведу упрощенные рекомендации по основным ошибкам в трейдинге:

ERR_TRADE_TIMEOUT - дилер/сервер не ответили, можно попытаться повторить сделку через некоторое время (например, минуту, а не через 5 сек)

ERR_TOO_FREQUENT_REQUESTS или ERR_TOO_MANY_REQUESTS - излишне частые запросы на сделки, надо уменьшить частоту запросов, это четко указывает на ошибки в логике эксперта/экспертов

ERR_INVALID_PRICE - неправильные цены bid/ask, зачастую из-за того, что трейдер забывает об обновлении рыночной информации через RefreshRates после задержек. однозначно указывает на серьезнейшие ошибки в эксперте. после таких ошибок практически надо останавливать трейдинг и разбираться в коде.

ERR_INVALID_STOPS - слишком близкие стопы или откровенно неправильные цены в стопах (take profit, stop loss или open price в отложенных ордерах), практически нельзя повторять торговую команду, если только нет 100% гарантии, что это произошло из-за устаревания цены.

ERR_INVALID_TRADE_VOLUME - ошибка в грануляции объемов, ни в коем случае нельзя повторять сделку

ERR_MARKET_CLOSED - рынок закрыт, можно попробовать сделку, но только через достаточно большой срок (несколько минут)

ERR_TRADE_DISABLED - торговля по инструменту полностью запрещена, повторять сделку нельзя ни в коем случае.

ERR_NOT_ENOUGH_MONEY - денег не хватает, повторять сделку с теми же параметрами категорически нельзя. можно повторить, уменьшив объем, но надо быть уверенным в достаточности средств и правильной грануляции объема.

ERR_PRICE_CHANGED или ERR_REQUOTE - реквот - цена обновилась, имеет смысл обновить рыночное окружение и попробовать заново, можно даже без задержек.

ERR_OFF_QUOTES или ERR_BROKER_BUSY - дилер по какой-то причине (например, в начале сессии цен нет, не подтвержденные цены, fast market) не дал цен или отказал. имеет смысл повторить сделку через небольшой период времени (от 5 сек) на обновленном рыночном окружении

ERR_ORDER_LOCKED - ордер заблокирован и уже обрабатывается, похоже на явную ошибку в логике эксперта или в самом терминале MT4, лучше ничего не повторять, а выйти

ERR_LONG_POSITIONS_ONLY_ALLOWED - разрешена только покупка, повторять sell ни в коем случае нельзя

ERR_TRADE_MODIFY_DENIED - модификация запрещена, так как ордер слишком близок к рынку и исполнению, можно попробовать через некоторый промежуток времени (секунд через 10-15, но ни в коем случае не сразу)

ERR_TRADE_CONTEXT_BUSY - торговый поток занят, необходимо использовать IsTradeAllowed(), явно требуется переписать эксперт с учетом занятости потока

ERR_TRADE_EXPIRATION_DENIED - запрещено использовать поле expiration в отложенных ордерах, потоврить операцию можно только если убрать expiration.

Эти рекомендации достаточно упрощенные, если нужны уточнения - спрашивайте, пожалуйста.
 
Огромное спасибо за рекомендации!!! Скопировал, оформляю в рамочку. Наверное, повешу на стену над рабочим столом.
 
а ВОТ ТАК ПОЙДЁТ? иЛИ ЕЩЁ ЧТО-НИБУДЬ ДОБАВИТЬ-ИЗМЕНИТЬ НАДО? Я понимаю, что разработчики не возьмут на себя ответственность за 100% исполнение ордера брокером, просто прошу рекомендаций в первую очередь разработчиков и реально торгующих советниками специалистов. Ищу наиболее защищённый от ошибок вариант кода
//+------------------------------------------------------------------+


int ticket;
double BuyPrice[10];
double SellPrice[10];
int SellTime[10];
int BuyTime[10];
int SellClosePrice[10]; 
int BuyClosePrice[10];
int SellCloseTime[10]; 
int BuyCloseTime[10];

double ISK=1.5;
double InsuranceStop;
int MaxTriesNumber=5;
int Slippage=3;
int err;
bool close;

//+------------------------------------------------------------------+

int Buy(double Lots,int Loss,int MagicNumber)
{

if (Loss==0 || Lots<0.1 || Lots>=10000 || MagicNumber<0) 
   {
   Print("invalid parameters");return(0);
   }
InsuranceStop=Loss*ISK;
for (int try=1;try<=MaxTriesNumber;try++)
   {
   while (!IsTradeAllowed()) Sleep(60);
   RefreshRates();
   ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,NormalizeDouble(Ask-InsuranceStop*Point,4),1000,"",MagicNumber,Blue);
   Sleep(60);
   if (ticket>0) 
      {
      BuyPrice[MagicNumber]=Ask;
      BuyTime[MagicNumber]=CurTime();
      SendMail("Buying succesful   ",ticket+"   "+BuyPrice[ticket]+"   "+TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS));
      break;
      }  
   else
      {
      err=GetLastError();
      Print("Buying failed with error #",err," : ",ErrorDescription(err));
      switch(err)
         {
         case 128/*"ERR_TRADE_TIMEOUT"*/: Sleep(30);
         case 8/*ERR_TOO_FREQUENT_REQUESTS*/: Print("Check Your Code!"); break; 
         case 141/*ERR_TOO_MANY_REQUESTS*/: Print("Check Your Code!"); break; 
         case 129/*ERR_INVALID_PRICE*/: Print("Check Your Code, Use RefreshRates!"); break;
         case 130/*ERR_INVALID_STOPS*/: Print("Check Your Code, Change Stops!"); break;
         case 131/*ERR_INVALID_TRADE_VOLUME*/: Print("Lots can not be",Lots); break;
         case 132/*ERR_MARKET_CLOSED*/: Sleep(300);
         case 133/*ERR_TRADE_DISABLED*/: Print("???"); break;
         case 134/*ERR_NOT_ENOUGH_MONEY*/: Print("Check Your Free Margin!"); break;
         case 135/*("ERR_PRICE_CHANGED*/: Sleep(5);
         case 138/**"ERR_REQUOTE*/: Sleep(5);
         case 136/*"ERR_OFF_QUOTES*/: Sleep(10);
         case 137/*"ERR_BROKER_BUSY*/: Sleep(10);
         case 139/*"ERR_ORDER_LOCKED*/: Print("Check Your Code or Terminal!"); break;
         case 146/*"ERR_TRADE_CONTEXT_BUSY*/: Print("Check Your Code, Use IsTradeAllowed!"); break;
         case 4/*ERR_SERVER_BUSY*/: Sleep(30);
         case 6/*ERR_NO_CONNECTION*/: Sleep(60);
         default: Print("Check Your Code or try manually!"); break;
         }
         if (try==MaxTriesNumber) 
            {
            Print("Warning!!!Last try failed!");
            SendMail("Warning!!!Last try failed!Try Manually.","");
            break;
            }
         }
      }
return(ticket);
}
//+------------------------------------------------------------------+
int Sell(double Lots,int Loss,int MagicNumber)
{

if (Loss==0 || Lots<0.1 || Lots>=10000 || MagicNumber<0) 
   {
   Print("invalid parameters");return(0);
   }
InsuranceStop=Loss*ISK;
for (int try=1;try<=MaxTriesNumber;try++)
   {
   while (!IsTradeAllowed()) Sleep(60);
   RefreshRates();
   ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,NormalizeDouble(Bid+InsuranceStop*Point,4),1000,"",MagicNumber,Yellow);
   Sleep(60);
   if (ticket>0) 
      {
      SellPrice[MagicNumber]=Bid;
      SellTime[MagicNumber]=CurTime();
      SendMail("Selling succesful   ",ticket+"   "+SellPrice[ticket]+"   "+TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS));
      break;
      }  
   else
      {
      err=GetLastError();
      Print("Selling failed with error #",err," : ",ErrorDescription(err));
      switch(err)
         {
         case 128/*"ERR_TRADE_TIMEOUT"*/: Sleep(30);
         case 8/*ERR_TOO_FREQUENT_REQUESTS*/: Print("Check Your Code!"); break; 
         case 141/*ERR_TOO_MANY_REQUESTS*/: Print("Check Your Code!"); break; 
         case 129/*ERR_INVALID_PRICE*/: Print("Check Your Code, Use RefreshRates!"); break;
         case 130/*ERR_INVALID_STOPS*/: Print("Check Your Code, Change Stops!"); break;
         case 131/*ERR_INVALID_TRADE_VOLUME*/: Print("Lots can not be",Lots); break;
         case 132/*ERR_MARKET_CLOSED*/: Sleep(300);
         case 133/*ERR_TRADE_DISABLED*/: Print("???"); break;
         case 134/*ERR_NOT_ENOUGH_MONEY*/: Print("Check Your Free Margin!"); break;
         case 135/*("ERR_PRICE_CHANGED*/: Sleep(5);
         case 138/**"ERR_REQUOTE*/: Sleep(5);
         case 136/*"ERR_OFF_QUOTES*/: Sleep(10);
         case 137/*"ERR_BROKER_BUSY*/: Sleep(10);
         case 139/*"ERR_ORDER_LOCKED*/: Print("Check Your Code or Terminal!"); break;
         case 146/*"ERR_TRADE_CONTEXT_BUSY*/: Print("Check Your Code, Use IsTradeAllowed!"); break;
         case 4/*ERR_SERVER_BUSY*/: Sleep(30);
         case 6/*ERR_NO_CONNECTION*/: Sleep(60);
         default: Print("Check Your Code or try manually!"); break;
         }
         if (try==MaxTriesNumber) 
            {
            Print("Warning!!!Last try failed!");
            SendMail("Warning!!!Last try failed!Try Manually.","");
            break;
            }
         }
      }
return(ticket);
}
//+------------------------------------------------------------------+
int CloseBuy(int MagicNumber)
{
for(int i=OrdersTotal();i>=0;i--)
   {
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)  break;
   if(OrderMagicNumber()!=MagicNumber || OrderSymbol()!=Symbol() ) continue;
   if (OrderType()==OP_BUY)
      {
      for (int try=1;try<=MaxTriesNumber;try++)
         {
         while (!IsTradeAllowed()) Sleep(60);
         close=false;
         RefreshRates();
         close=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Orange);         
         Sleep(60);
         if (close) 
            {
            ticket=OrderTicket();
            BuyClosePrice[MagicNumber]=OrderClosePrice();
            BuyCloseTime[MagicNumber]=CurTime();
            SendMail("Closing succesful   ",ticket+"   "+BuyClosePrice[MagicNumber]+"   "+TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS));
            break;
            }  
         else
            {
            err=GetLastError();
            Print("Closing failed with error #",err," : ",ErrorDescription(err));
            switch(err)
               {
               case 128/*"ERR_TRADE_TIMEOUT"*/: Sleep(30);
               case 8/*ERR_TOO_FREQUENT_REQUESTS*/: Print("Check Your Code!"); break; 
               case 141/*ERR_TOO_MANY_REQUESTS*/: Print("Check Your Code!"); break; 
               case 129/*ERR_INVALID_PRICE*/: Print("Check Your Code, Use RefreshRates!"); break;
               case 130/*ERR_INVALID_STOPS*/: Print("Check Your Code, Change Stops!"); break;
               case 131/*ERR_INVALID_TRADE_VOLUME*/: Print("Lots can not be",Lots); break;
               case 132/*ERR_MARKET_CLOSED*/: Sleep(300);
               case 133/*ERR_TRADE_DISABLED*/: Print("???"); break;
               case 134/*ERR_NOT_ENOUGH_MONEY*/: Print("Check Your Free Margin!"); break;
               case 135/*("ERR_PRICE_CHANGED*/: Sleep(5);
               case 138/**"ERR_REQUOTE*/: Sleep(5);
               case 136/*"ERR_OFF_QUOTES*/: Sleep(10);
               case 137/*"ERR_BROKER_BUSY*/: Sleep(10);
               case 139/*"ERR_ORDER_LOCKED*/: Print("Check Your Code or Terminal!"); break;
               case 146/*"ERR_TRADE_CONTEXT_BUSY*/: Print("Check Your Code, Use IsTradeAllowed!"); break;
               case 4/*ERR_SERVER_BUSY*/: Sleep(30);
               case 6/*ERR_NO_CONNECTION*/: Sleep(60);
               default: Print("Check Your Code or try manually!"); break;
               }
               if (try==MaxTriesNumber) 
                  {
                  Print("Warning!!!Last try failed!");
                  SendMail("Warning!!!Last try failed!Try Manually.","");
                  break;
                  }
            }
         }
      }
   }
return(ticket);
}
//+------------------------------------------------------------------+
int CloseSell(int MagicNumber)
{
for(int i=OrdersTotal();i>=0;i--)
   {
   if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)==false)  break;
   if(OrderMagicNumber()!=MagicNumber || OrderSymbol()!=Symbol() ) continue;
   if (OrderType()==OP_SELL)
      {
      for (int try=1;try<=MaxTriesNumber;try++)
         {
         while (!IsTradeAllowed()) Sleep(60);
         close=false;
         RefreshRates();
         close=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),Slippage,Orange);         
         Sleep(60);
         if (close) 
            {
            ticket=OrderTicket();
            SellClosePrice[MagicNumber]=OrderClosePrice();
            SellCloseTime[MagicNumber]=CurTime();
            SendMail("Closing succesful   ",ticket+"   "+SellClosePrice[MagicNumber]+"   "+TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS));
            break;
            }  
         else
            {
            err=GetLastError();
            Print("Closing failed with error #",err," : ",ErrorDescription(err));
            switch(err)
               {
               case 128/*"ERR_TRADE_TIMEOUT"*/: Sleep(30);
               case 8/*ERR_TOO_FREQUENT_REQUESTS*/: Print("Check Your Code!"); break; 
               case 141/*ERR_TOO_MANY_REQUESTS*/: Print("Check Your Code!"); break; 
               case 129/*ERR_INVALID_PRICE*/: Print("Check Your Code, Use RefreshRates!"); break;
               case 130/*ERR_INVALID_STOPS*/: Print("Check Your Code, Change Stops!"); break;
               case 131/*ERR_INVALID_TRADE_VOLUME*/: Print("Lots can not be",Lots); break;
               case 132/*ERR_MARKET_CLOSED*/: Sleep(300);
               case 133/*ERR_TRADE_DISABLED*/: Print("???"); break;
               case 134/*ERR_NOT_ENOUGH_MONEY*/: Print("Check Your Free Margin!"); break;
               case 135/*("ERR_PRICE_CHANGED*/: Sleep(5);
               case 138/**"ERR_REQUOTE*/: Sleep(5);
               case 136/*"ERR_OFF_QUOTES*/: Sleep(10);
               case 137/*"ERR_BROKER_BUSY*/: Sleep(10);
               case 139/*"ERR_ORDER_LOCKED*/: Print("Check Your Code or Terminal!"); break;
               case 146/*"ERR_TRADE_CONTEXT_BUSY*/: Print("Check Your Code, Use IsTradeAllowed!"); break;
               case 4/*ERR_SERVER_BUSY*/: Sleep(30);
               case 6/*ERR_NO_CONNECTION*/: Sleep(60);
               default: Print("Check Your Code or try manually!"); break;
               }
               if (try==MaxTriesNumber) 
                  {
                  Print("Warning!!!Last try failed!");
                  SendMail("Warning!!!Last try failed!Try Manually.","");
                  break;
                  }
            }
         }
      }
   }
return(ticket);
}

//+------------------------------------------------------------------+
 
Никто не отвечает... А я уже ошибку нашёл- там где слип у меня все цифры в секундах- их надо на 1000 умножить.