РЕШЕНО: Маркет invalid lots amount for FreeMarginCheck function

 
test on EURUSD,H1
2016.04.01 00:00  EURUSD,H1: invalid lots amount for FreeMarginCheck function
2016.04.01 00:00  EURUSD,H1: invalid lots amount for FreeMarginCheck function
strategy tester report 2 total trades

Интересная особенность автовалидации.

Сделал код, чтобы если не хватает денег - советник деинициализироваля. чтоб быстрее проходил тесты

постоянно получаю такую ошибку.

 

код проверки лота:

double GetLot(double LOTS)
{  
double Lot2,MinLots,MaxLots;
   long lotdig;

   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.000001)lotdig=6;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.00001)lotdig=5;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.0001)lotdig=4;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.001)lotdig=3;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.01)lotdig=2;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.1)lotdig=1;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==1)lotdig=0;
   MinLots=MarketInfo(Symbol(),MODE_MINLOT);
   MaxLots=MarketInfo(Symbol(),MODE_MAXLOT);

   Lot2=LOTS;
   if(Lot2>MaxLots) Lot2=MaxLots;
   if(Lot2<MinLots) Lot2=MinLots;
   return(NormalizeDouble(Lot2,lotdig));
}


 

и проверка на свободную маржу

      double marginbuy=EMPTY_VALUE;
      double marginsell=EMPTY_VALUE;
      marginbuy=AccountFreeMarginCheck(Symbol(),OP_BUY,GetLot(Lots));
      marginsell=AccountFreeMarginCheck(Symbol(),OP_SELL,GetLot(Lots));


если не хватает денег выходим

         if(((marginbuy<0 && marginsell<0) || (marginbuy==1 && marginsell==1)) && IsTestingUNI())
           {
            STOPTRADING=true;
            GlobalVariableSet(EAPadPROName+"STOPTRADING"+Symbol(),STOPTRADING);
            ExpertRemove();
            OnDeinit(0);
           }



в тестере на домашнем компьютере все ок. 

на автовалидации выбивает по ошибке:


 test on EURUSD,H1

2016.04.01 00:00  EURUSD,H1: invalid lots amount for FreeMarginCheck function
2016.04.01 00:00  EURUSD,H1: invalid lots amount for FreeMarginCheck function
strategy tester report 2 total trades

 

Кто сталкивался?  

 

Ihor Herasko:

MathMin
(MathMax(MathRound(volume / volumeStep) * volumeStep, volumeMin), volumeMax);

 

спасибо Ваш код решил ситуацию.   

 

Подставьте в приведенный код значение LotStep = 0.25 и, надеюсь, поймете, в чем дело.

Именно поэтому такая вот проверка:

if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.000001)lotdig=6;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.00001)lotdig=5;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.0001)lotdig=4;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.001)lotdig=3;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.01)lotdig=2;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.1)lotdig=1;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==1)lotdig=0;

 является очень плохим решением. Используйте универсальный прием для приведения значения объема к ближайшему корректному:

MathMin(MathMax(MathRound(volume / volumeStep) * volumeStep, volumeMin), volumeMax);
 

дело в том, что все советники имеют одинаковый код у меня. 

и все проходят проверку (вычисление свободной маржи перед открытием сделки)

но если я хочу удалить эксперт при нехватке средств - автовалидация не проходит.

попробую Ваш код  

 
Ihor Herasko:

MathMin
(MathMax(MathRound(volume / volumeStep) * volumeStep, volumeMin), volumeMax);

 

спасибо Ваш код решил ситуацию.  

 
Vladislav Andruschenko:

 

спасибо Ваш код решил ситуацию.  


спасибо, друзья, если бы не вы, долго пришлось бы трах...ся

с этой хре..ю..

 
Ihor Herasko:

Подставьте в приведенный код значение LotStep = 0.25 и, надеюсь, поймете, в чем дело.

Именно поэтому такая вот проверка:

if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.000001)lotdig=6;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.00001)lotdig=5;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.0001)lotdig=4;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.001)lotdig=3;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.01)lotdig=2;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==0.1)lotdig=1;
   if(MarketInfo(Symbol(),MODE_LOTSTEP)==1)lotdig=0;

 является очень плохим решением. Используйте универсальный прием для приведения значения объема к ближайшему корректному:

MathMin(MathMax(MathRound(volume / volumeStep) * volumeStep, volumeMin), volumeMax);

а если так - 

   l_minlot   = SymbolInfoDouble (sym,SYMBOL_VOLUME_MIN);
   if (l_minlot >= 1                        ) LotDigits = 0; 
   if (l_minlot >= 0.1   && l_minlot < 1    ) LotDigits = 1;
   if (l_minlot >= 0.01  && l_minlot < 0.1  ) LotDigits = 2; 
   if (l_minlot >= 0.001 && l_minlot < 0.01 ) LotDigits = 3;

здесь значение 0,25 вполне прокатывает ...  даже 0,99 прокатит ... 

я не спорю с выше приведённым кодом, я просто спрашиваю ... 

 
elmucon:

а если так - 

здесь значение 0,25 вполне прокатывает ...  даже 0,99 прокатит ... 

я не спорю с выше приведённым кодом, я просто спрашиваю ... 


Если здесь имелся в виду Lot Step, а не Lot Min, то все равно неправильно. Ведь при значении Lot Step = 0.25 получим LotDigits = 1. В итоге значение будет приведено к 0.2 или 0.3 в зависимости от используемого способа округления.

Если же здесь речь именно о том, что написано (Lot Min), то способ ошибочный в корне, т. к. база выбрана неверно.
 
Ihor Herasko:

Если здесь имелся в виду Lot Step, а не Lot Min, то все равно неправильно. Ведь при значении Lot Step = 0.25 получим LotDigits = 1. В итоге значение будет приведено к 0.2 или 0.3 в зависимости от используемого способа округления.

Если же здесь речь именно о том, что написано (Lot Min), то способ ошибочный в корне, т. к. база выбрана неверно.

0.01 > 0.25 < 0.1

0.25 больше 0,01 и меньше 0,1 и поэтому LotDigits будет 2

так что ИЧСЁ разок посчитайте ... 
 
elmucon:

так что ИЧСЁ разок посчитайте ... 

Вы ошибаетесь

0.1 < 0.25 < 1

0.25 больше 0,1 и меньше 1,0 и поэтому LotDigits будет 1

Причина обращения: