ПОМОГИТЕ переделать функцию проверки средств в советнике.

 

Господа, есть советник, которого пытаюсь тестировать на сервере с демо-счётом, но он работает не совсем корректно. Суть его работы основана на мартингейле, когда он доходит до лота, который больше максимального, он не берёт максимально возможный (как это прописано в коде), а пытается отправить торговый запрос брокеру, и получает ошибку "broker comment: no money".

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

Или кто-то опытный может прописать этот код, по сути не займёт времени больше 5 минут, и если советник вас заинтересует - оставите себе исправленную версию.

 
mason_one:

Господа, есть советник, которого пытаюсь тестировать на сервере с демо-счётом, но он работает не совсем корректно. Суть его работы основана на мартингейле, когда он доходит до лота, который больше максимального, он не берёт максимально возможный (как это прописано в коде), а пытается отправить торговый запрос брокеру, и получает ошибку "broker comment: no money".

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

Или кто-то опытный может прописать этот код, по сути не займёт времени больше 5 минут, и если советник вас заинтересует - оставите себе исправленную версию.

Читайте статью "Какие проверки должен пройти советник перед публикацией в маркете".

Какие проверки должен пройти торговый робот перед публикацией в Маркете
Какие проверки должен пройти торговый робот перед публикацией в Маркете
  • www.mql5.com
Все продукты Маркета перед публикацией проходят обязательную предварительную проверку, так как небольшая ошибка в логике советника или индикатора может привести к убыткам на торговом счете. Именно поэтому нами разработана серия базовых проверок, призванных обеспечить необходимый уровень качества продуктов Маркета. Если в процессе проверки...
 

НУ так выкладывай сюда код. Помогут. Иначе за деньги. 

Игры с Мартином - не перспективны. Впрочем как и локи, сетки и пр. Поэтому твой грааль никого не заинтересует. 

 
//+------------------------------------------------------------------+
//| Refreshes the symbol quotes data                                 |
//+------------------------------------------------------------------+
bool RefreshRates()
  {
//--- refresh rates
   if(!m_symbol.RefreshRates())
     {
      Print("RefreshRates error");
      return(false);
     }
//--- protection against the return value of "zero"
   if(m_symbol.Ask()==0 || m_symbol.Bid()==0)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+
//| Check the correctness of the order volume                        |
//+------------------------------------------------------------------+
bool CheckVolumeValue(double volume,string &error_description)
  {
//--- minimal allowed volume for trade operations
   double min_volume=m_symbol.LotsMin();
   if(volume<min_volume)
     {
      error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);
      return(false);
     }
//--- maximal allowed volume of trade operations
   double max_volume=m_symbol.LotsMax();
   if(volume>max_volume)
     {
      error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);
      return(true);
     }
//--- get minimal step of volume changing
   double volume_step=m_symbol.LotsStep();

   int ratio=(int)MathRound(volume/volume_step);
   if(MathAbs(ratio*volume_step-volume)>0.0000001)
     {
      error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",
                                     volume_step,ratio*volume_step);
      return(false);
     }
   error_description="Correct volume value";
   return(true);
  }
//+------------------------------------------------------------------+ 
//| Checks if the specified filling mode is allowed                  | 
//+------------------------------------------------------------------+ 
bool IsFillingTypeAllowed(int fill_type)
  {
//--- Obtain the value of the property that describes allowed filling modes 
   int filling=m_symbol.TradeFillFlags();
//--- Return true, if mode fill_type is allowed 
   return((filling & fill_type)==fill_type);
  }
//+------------------------------------------------------------------+
//| Lot Check                                                        |
//+------------------------------------------------------------------+
double LotCheck(double lots)
  {
//--- calculate maximum volume
   double volume=NormalizeDouble(lots,2);
   double stepvol=m_symbol.LotsStep();
   if(stepvol>0.0)
      volume=stepvol*MathFloor(volume/stepvol);
//---
   double minvol=m_symbol.LotsMin();
   if(volume<minvol)
      volume=0.0;
//---
   double maxvol=m_symbol.LotsMax();
   if(volume>maxvol)
      volume=maxvol;
   return(volume);
  }
 
выложил код проверки объёма
 
mason_one:
выложил код проверки объёма

Только последняя функция считает проверяет объем. 

в этой функции вы сразу нормализуете объем. Потом его пересчитываете и сравниваете с мин и макс. объемом. Надо наоборот. Сначала производим действие, потом нормализуем. 

 bool CheckVolumeValue(double volume,string &error_description) 


В этой функции если объем меньше мин объема - то функция возвращает false. Это правильно. 
А вот если объем больше допустимого то функция вернет true. Если в дальнейшем будете пересчет то правильно. Если это конечная проверка - то ошибка. 


 
Dmitiry Ananiev:

Только последняя функция считает проверяет объем. 

в этой функции вы сразу нормализуете объем. Потом его пересчитываете и сравниваете с мин и макс. объемом. Надо наоборот. Сначала производим действие, потом нормализуем. 


В этой функции если объем меньше мин объема - то функция возвращает false. Это правильно. 
А вот если объем больше допустимого то функция вернет true. Если в дальнейшем будете пересчет то правильно. Если это конечная проверка - то ошибка. 


Спасибо за наводящие мысли, общую идею я понял, но пока не сообразил, как реализовывается сразу пересчитать, и потом нормализовать.

 
mason_one:

Спасибо за наводящие мысли, общую идею я понял, но пока не сообразил, как реализовывается сразу пересчитать, и потом нормализовать.

double volume=NormalizeDouble(lots,2);

вот эту строчку убираем в начале и ставим перед return.

НУ естественно объявляем в начале volume и в конце получится 

volume=NormalizeDouble(lots,2);
return volume;
 
Dmitiry Ananiev:

вот эту строчку убираем в начале и ставим перед return.

НУ естественно объявляем в начале volume и в конце получится 

Спасибо большое, буду пробовать тестировать.

 
Dmitiry Ananiev:

вот эту строчку убираем в начале и ставим перед return.

НУ естественно объявляем в начале volume и в конце получится 

Всё равно он доходит до лота больше возможного, но не обновляет цикл, а выдаёт ошибку "not enought money", как я понимаю, это прописано у него прямо в коде? прикрепляю ниже

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)
   double check_volume_lot=m_trade.CheckVolume(m_symbol.Name(),ExtLot,m_symbol.Ask(),ORDER_TYPE_BUY);

   if(check_volume_lot!=0.0)
      if(check_volume_lot>=ExtLot)
        {
         if(m_trade.Buy(ExtLot,m_symbol.Name(),m_symbol.Ask(),sl,tp))
           {
            if(m_trade.ResultDeal()==0)
              {
               Print("#1 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
                     ", description of result: ",m_trade.ResultRetcodeDescription());
               PrintResult(m_trade,m_symbol);
              }
            else
              {
               Print("#2 Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),
                     ", description of result: ",m_trade.ResultRetcodeDescription());
               PrintResult(m_trade,m_symbol);
              }
           }
         else
           {
            Print("#3 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),
                  ", description of result: ",m_trade.ResultRetcodeDescription());
            PrintResult(m_trade,m_symbol);
           }
         return;
        }
   ExtLot=InpLots;
//---

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

 
Роботу не хватило денег.