Тестер удаляет ордера

 
Народ, у вас не случалось, что при тестировании, без видимой причины удаляются отложенные ордера ? Наваял я тут следующее чудо:
//+------------------------------------------------------------------+
//|                                                       tunnel.mq4 |
//|                                                       Черный Кот |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "Черный Кот"
#property link      ""
 
//---- input parameters
extern int  Level=20;
extern int  LotSize=1;
extern int  Slip=3;
extern int  StopLoss=300;
extern int  TakeProfit=50;
 
 
#define ST_INIT 0
#define ST_RUN  1
 
int State=ST_INIT;
int LastBuy, LastSell;
 
int init()
{
   
   LastBuy=-1; LastSell=-1;
   return(0);
}
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//----
   
//----
   return(0);
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int GetStateOfLast()
{
   int lb=0, ls=0;
   if((LastBuy==-1)&&(LastSell==-1)) return (9);
   
   if(OrderSelect(LastBuy, SELECT_BY_TICKET))
   {            
      if(OrderType()==OP_BUYSTOP) lb=0;
      else 
      {
         if(OrderType()==OP_BUY) 
         {
            lb=1;
            if(OrderCloseTime() != 0) 
            {
               Print("Buy closed");
               lb=2;
            }
         }
         else 
         {
            Print("Buy type illegal");
            lb=100;
         }
      }
   }    
   else 
   {
     Print("Cannot select Buy");
     lb=100;
   }
      
   if(OrderSelect(LastSell, SELECT_BY_TICKET))
   {            
      if(OrderType()==OP_SELLSTOP) ls=0;
      else 
      {
         if(OrderType()==OP_SELL) 
         {
            ls=1;
            if(OrderCloseTime() != 0) 
            {
               Print("Sell closed");
               ls=2;
            }
         }
         else 
         {
            Print("Sell type illegal");
            ls=100;
         }                
      }
   }    
   else
   {
     Print("Cannot select Sell");
     ls=100;
   }
 
 
                       
   int s=lb*3 + ls;
//   Print("State=", s);
   return (s);
}
 
 
bool BuySet, BuyMov, SellSet, SellMov;
bool BuySetEnb, BuyMovEnb, SellSetEnb, SellMovEnb;
int S;
 
void DecodeStateOfLast()
{
   int S=GetStateOfLast();
//   Print("s=",s);
   switch(S)
   {
      case 0 : //lb=0, ls=0 - оба не открыты
      // ждать
      BuySet=false; BuyMov=false; SellSet=false; SellMov=false;
      break;
      case 4 : //lb=1, ls=1 - оба открылись
      //ждать пока один или оба не закроются
      BuySet=false; BuyMov=false; SellSet=false; SellMov=false;
      break;      
//------------------------------------------------------------------------
      case 1 : //lb=0, ls=1 - открылся на продажу      
      //поставить еще один отложенный на продажу и передвинуть вниз на покупку
      BuySet=false; BuyMov=true; SellSet=true; SellMov=false;
      break;
      case 2 : //lb=0, ls=2 - на продажу успел закрыться
      //поставить еще один отложенный на продажу и передвинуть вниз на покупку      
      BuySet=false; BuyMov=true; SellSet=true; SellMov=false;
      break;
//------------------------------------------------------------------------      
      case 3 : //lb=1, ls=0 - открылся на покупку
      //поставить еще один отложенный на покупку и передвинуть вверх на продажу      
      BuySet=true; BuyMov=false; SellSet=false; SellMov=true;
      break;      
      case 6 : //lb=2, ls=0 - на покупку успел закрыться
      //поставить отложенный на покупку, и передвинуть вверх на продажу
      BuySet=true; BuyMov=false; SellSet=false; SellMov=true;
      break;
//------------------------------------------------------------------------      
      case 5 : //lb=1, ls=2 - открылся на покупку, а на продажу успел закрыться
      //поставить отложенные на продажу и на покупку
      BuySet=true; BuyMov=false; SellSet=true; SellMov=false;
      break;      
      case 7 : //lb=2, ls=1 - на продажу закрылся, на покупку открылся      
      //поставить отложенные на продажу и на покупку
      BuySet=true; BuyMov=false; SellSet=true; SellMov=false;
      break;
      case 8 : //lb=2, ls=2 - оба закрылись
      //поставить отложенные на продажу и на покупку
      BuySet=true; BuyMov=false; SellSet=true; SellMov=false;
      break;         
      case 9 : //начальное состояние
      //поставить отложенные на продажу и на покупку
//      Print("Empty state");
      BuySet=true; BuyMov=false; SellSet=true; SellMov=false;
      break;               
   }
   
}
 
double GetTP(int op)
{
   double tp;
   if(op==OP_BUY)
   {
      if(TakeProfit != 0) tp=Bid + TakeProfit*Point; else tp=0;      
   }
   else
   {
      if(TakeProfit != 0) tp=Ask - TakeProfit*Point; else tp=0;      
   }
   return (tp);
}
 
double GetSL(int op)
{
   double sl;
   if(op==OP_BUY)
   {
      if(StopLoss != 0)   sl=Bid - StopLoss*Point;   else sl=0;
   }
   else
   {
      if(StopLoss != 0)   sl=Ask + StopLoss*Point;   else sl=0;
   }
   return (sl);
}
 
void SetAndMov()
{
   double tp, sl;
   if(BuySet)
   {
//      Print("BuySet");
      if(BuySetEnb)      
      {
//         Print("BuySetEnb");
         tp=GetTP(OP_BUY); sl=GetSL(OP_BUY);
         Print("Buy:  Ask=",Ask,"  open=",Ask+Level*Point,"  sl=",sl,"  tp=",tp);
         LastBuy=OrderSend(Symbol(),OP_BUYSTOP, LotSize,Ask+Level*Point,Slip,sl,tp,NULL,0,0,Blue);         
         if(LastBuy==-1)
         {
            Print("BuySend error:", GetLastError());
         }
      }         
   }
   if(SellSet)
   {
//      Print("SellSet");
      if(SellSetEnb)
      {
//         Print("SellSetEnb");
         tp=GetTP(OP_SELL); sl=GetSL(OP_SELL);
         Print("Sell:  Bid=",Bid,"  open=",Bid-Level*Point,"  sl=",sl,"  tp=",tp);  
         LastSell = OrderSend(Symbol(),OP_SELLSTOP,LotSize,Bid-Level*Point,Slip,sl,tp,NULL,0,0,Red);         
         if(LastSell==-1)
         {
            Print("SellSend error:", GetLastError());
         }
         
      }
   }   
   if(BuyMov)
   {
      if(BuyMovEnb)
      {
         tp=GetTP(OP_BUY); sl=GetSL(OP_BUY);
         OrderModify(LastBuy,Ask+Level*Point,sl,tp,0, Blue);
      }
   }
   if(SellMov)
   {
      if(SellMovEnb)
      {
         tp=GetTP(OP_SELL); sl=GetSL(OP_SELL);
         OrderModify(LastSell,Bid-Level*Point,sl,tp,0, Red);
      }
   }
   
}
 
 
int start()
{
   double sl, tp;
   BuySetEnb=true; BuyMovEnb=true; SellSetEnb=true; SellMovEnb=true;
 
 
   if(!OrderSelect(LastBuy,SELECT_BY_TICKET))
   {
      Print("Buy select error");
   }
   double b=OrderOpenPrice();
   
   if(!OrderSelect(LastSell,SELECT_BY_TICKET))
   {
      Print("Sell select error");
   }   
   double s=OrderOpenPrice();
   //FileWrite(log, TimeToStr(MarketInfo(Symbol(),MODE_TIME)), "   delta=",(b-s)*Point, "   S=",S);
   Print("  b=",b,"  s=",s,"   delta=",(b-s)/Point, "   S=",S, "  Orders=", OrdersTotal());
   
   DecodeStateOfLast();
   SetAndMov();   
   return(0);
}
//+------------------------------------------------------------------+
Извините что чудо грязное, всё в следах отладки, суть не в этом. Тестировал билдом 198 от 19 октября, скачанным с alpari.org. На EURUSD, таймфрейм М5, режим "все тики". С 2006.03.15 13:25. Точнее хотел с 2004. 06.01, но тестер закачал лишь с 2006.03.15 05:00 а прогон начал с 2006. 03.15 13:25. Если кто подскажет, как закачать в тестер hst-минутку с диска, моя благодарность тоже не будет знать границ. У меня он упорно лезет на сервер, что только ни делал. Но суть опять же не в этом, простите за маленькое отступление. Суть в том, что 2006.03.20 08:15 был удален отложенный ордер. А вызова OrderDelete() в моем коде не проглядывается. И еще. В функции start() у меня вызывается отладочная печать, печатающая в том числе и количество ордеров. Так вот, 2006.03.20 08:15, число ордеров не изменилось !!! Тем не менее дальнейший анализ ситуации показал, что отложенный ордер был все-таки совершенно реально удален. Вот кусок таблицы результатов прогона:
682006.03.17 17:00buy stop211.001.22001.18771.2227
692006.03.17 17:00modify201.001.21571.24801.2130
702006.03.17 17:56buy211.001.22001.18771.2227
712006.03.17 17:56buy stop221.001.22201.18971.2247
722006.03.17 17:56modify201.001.21771.25001.2150
732006.03.17 18:05t/p141.001.22051.18551.2205261.7012862.10
742006.03.17 18:05t/p151.001.22051.18551.2205270.0013132.10
752006.03.20 00:00sell201.001.21771.25001.2150
762006.03.20 00:00sell stop231.001.21561.24791.2129
772006.03.20 00:00modify221.001.21991.18761.2226
782006.03.20 07:55sell231.001.21561.24791.2129
792006.03.20 07:55sell stop241.001.21361.24591.2109
802006.03.20 07:55modify221.001.21791.18561.2206
812006.03.20 08:15delete221.001.21791.18561.2206
822006.03.20 18:36t/p201.001.21501.25001.2150270.0013402.10
832006.03.21 01:27sell241.001.21361.24591.2109
842006.03.21 01:27sell stop251.001.21151.24381.2088
852006.03.21 04:01t/p91.001.21281.24781.2128280.0013682.10
862006.03.21 04:01t/p191.001.21301.24801.2130280.0013962.10
В конце этого куска видно, что ордер 22 был удален.

А вот кусок вывода на консоль, из которого видно, что в 2006.03.20 08:15, число видимых функцией OrdersTotal() ордеров не изменилось. Как было 5, так и осталось. Хотя повторяю, ордер был удален совершенно реально.

02:00:36 2006.03.20 08:12 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:12 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:12 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:13 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:13 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:14 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:15 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:15 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:16 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:17 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:17 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:17 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:18 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:18 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:19 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:19 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5
02:00:36 2006.03.20 08:20 tunnel EURUSD,M5: b=1.2198 s=1. 2155 delta=43 S=0 Orders=5

Вобщем не знаю что с этим делать, и уповаю на помощь Великих ! Помогите чайнику, и кто нибудь поможет вам :)
 
eugenk1 писал (а):
Народ, у вас не случалось, что при тестировании, без видимой причины удаляются отложенные ордера ?
Не-а, не случалось. Погонял Ваш код, поудивлялся. Действительно, фиг знает, что творится...
Предположительно, самопроизвольное удаление некоторых ордеров связано с нехваткой денег на счету. Увеличение баланса тестового счёта позволяет немного отодвинуть момент удаления. Например, если при 10 тыс. удаляется 19 ордер, то при 50 тыс. - 266-ой, а 19-ый не трогается. Во как!!!

eugenk1 писал (а):
Если кто подскажет, как закачать в тестер hst-минутку с диска, моя благодарность тоже не будет знать границ.

Подготовка котировок для тестов на истории
 
Отложенные ордеры (именно отложенные, как в этом случае) удаляются в момент их активации, если недостаточно маржи. Тестер сам об этом явно пишет "delete".
 
Ооо, спасибо, Ренат! Значит, я правильно предположил! :-) В деньгах дело было.
 
Ренат, спасибо огромное !!! Эквити этот код и правда очень прилично заваливает...Ренат, извини за назойливость, тогда ещё один вопрос. Почему удаление ордера никак не отразилось в тестовой распечатке на 2006.03.20 08:15 ? Ордер был удален. OrdersTotal() должна была это заметить... И уж совсем неудобно спрашивать, но спрошу еще. Тестировал я это же чудо на GPBJPY. Там самопроизвольно, без событий (т.е. срабатывания удаленных, закрытий и модификаций) менялись цены срабатывания отложенных ордеров. Именно потому я и печатаю у себя их цены открытия b и s и их разность delta. По замыслу алгоритма, delta меняться не должна. Тем не менее, она меняется, причем тогда, когда никаких событий нет. Просто иногда сами собой меняются b и s. Не можешь объяснить, где тут собака порылась ? Если надо, распечатку консоли выложу.

Игорь, спасибо что заинтересовался. И спасибо за инфу о закачке истории в тестер ! :) Код кстати с неплохой на мой взгляд идеей. Цена движется в туннеле из двух отложенных ордеров (почему и назвал его tunnel). Как только один открывается, тут же добавляется новый отложенный. Система опирается только на цену, не использует никаких индикаторов с их запаздыванием, и по определению является трендочуствительной (в самом деле, тренд это преимущественное число шагов цены в одном направлениии за единицу времени). Потому этот код дает огромный процент выигранных сделок. Губит его ничтожное число сделок неудачных. Их как раз хватает для того, чтобы нас посетил пьяница придурок и дебошир Коля Маржоффф, со своей опухшей рожей и грязными ногтями :)))))) Сейчас думаю как этот код усовершенствовать. Если хочешь - присоединяйся !
 
Если вопрос с удалением отложенных ордеров раскрыт, то с OrdersTotal() надо бы Вам самому разобраться. И в процессе получите опыт.

Мы не можем заниматься исследованиями чужих алгоритмов экспертов в "свободном полете", а реагируем исключительно на явные и обоснованные ошибки.
Причина обращения: