Как вычислить максимальный лот которым можно открыться?

 

Подскажите, кто знает, каким способом можно вычислить максимальный лот, которым можно встать в SELL по USDCHF в текущий момент с учетом уже открытых и хеджированных позиций?

Другими словами, нужно найти такой размер лота, при котором функция

AccountFreeMarginCheck("USDCHF", OP_SELL, <вычисленный лот>);
вернет ноль (или около нуля, с учетом мелких погрешностей)
 
Может у кого нибудь найдется кусочек кода для вычисления этого лота?
 
double СВОБОДНО=AccountFreeMargin();
double МАРЖА=MarketInfo(Symbol(),MODE_MARGINREQUIRED);
double ДОСТЛОТ=СВОБОДНО/МАРЖА;
 
kombat писал (а) >>

Данный способ к сожалению не учитывает уже открытые позиции, т. к. у меня может быть открыто к примеру 2.0 лота по EURUSD на покупку и если я захочу продать, к примеру 1 лот, то маржа будет совсем другая нежели та, которую вернет MODE_MARGINREQUIRED, потому что 1 лот на продажу при уже открытых 2 лотах на покупку будет считаться по хеджированному правилу...

Другими словами, если у меня в данный момент есть позиция SELL по USDCHF, то

double СВОБОДНО=AccountFreeMargin();
double МАРЖА=MarketInfo("USDCHF",MODE_MARGINREQUIRED);
double ДОСТЛОТ=СВОБОДНО/МАРЖА;
    
Comment(AccountFreeMarginCheck("USDCHF",  OP_BUY, ДОСТЛОТ));

вернет далеко не ноль

 
Michael писал (а) >>

Подскажите, кто знает, каким способом можно вычислить максимальный лот, которым можно встать в SELL по USDCHF в текущий момент с учетом уже открытых и хеджированных позиций?

Другими словами, нужно найти такой размер лота, при котором функция

вернет ноль (или около нуля, с учетом мелких погрешностей)

Скрипт Max Lot:

//+------------------------------------------------------------------+
//|                                                      Max Lot.mq4 |
//|                                                          Valmars |
//+------------------------------------------------------------------+
#property copyright "Valmars"
#property link      "*****"

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
//----
  double vol; 
  string symbol=Symbol();
  vol=LotsCalculate(symbol,OP_BUY);
  Print("MaxLot= ", vol);  
//----
   return(0);
  }
//+------------------------------------------------------------------+
double LotsCalculate(string symbol,int cmd)
   {
   double vol;
   vol=MarketInfo(symbol,MODE_MINLOT);
   while (AccountFreeMarginCheck(symbol,cmd,vol) > 0)
    {
     {vol=vol+MarketInfo(symbol,MODE_LOTSTEP);}
    }
   vol=vol-MarketInfo(symbol,MODE_LOTSTEP);
   if (AccountFreeMarginCheck(symbol,cmd,vol) > 0)
return(vol);
   else
return(0);   
   }
 
Valmars писал (а) >>

Скрипт Max Lot:

Большое спасибо, это то, что надо, но ... к сожалению цикл

while (AccountFreeMarginCheck(symbol,cmd,vol) > 0)

очень долго выполняется, если к примеру шаг лота 0.01, а на депо осталось еще лотов 100, то цикл выполнится 10 тысяч раз, при этом мне надо для каждой вылюты вычислять на каждом проходе. Может есть способ обойтись без этого цикла и вычислять по аналогии, как это делает AccountFreeMarginCheck()?

Было бы супер!

 
Michael писал (а) >>

Большое спасибо, это то, что надо, но ... к сожалению цикл

очень долго выполняется, если к примеру шаг лота 0.01, а на депо осталось еще лотов 100, то цикл выполнится 10 тысяч раз, при этом мне надо для каждой вылюты вычислять на каждом проходе. Может есть способ обойтись без этого цикла и вычислять по аналогии, как это делает AccountFreeMarginCheck()?

Было бы супер!

Вот так будет быстрее:

double LotsCalculate(string symbol,int cmd){
   double vol;
   vol=MarketInfo(symbol,MODE_MINLOT);
      while (AccountFreeMarginCheck(symbol,cmd,vol)>0){
         vol=vol+MarketInfo(symbol,MODE_LOTSTEP)*100;
      }
   vol=vol-MarketInfo(symbol,MODE_LOTSTEP)*100;
      while (AccountFreeMarginCheck(symbol,cmd,vol)>0){
         vol=vol+MarketInfo(symbol,MODE_LOTSTEP)*10;
      }
   vol=vol-MarketInfo(symbol,MODE_LOTSTEP)*10;      
      while (AccountFreeMarginCheck(symbol,cmd,vol)>0){
         vol=vol+MarketInfo(symbol,MODE_LOTSTEP);
      }
   vol=vol-MarketInfo(symbol,MODE_LOTSTEP);        
   if (AccountFreeMarginCheck(symbol,cmd,vol) > 0)
   return(vol);
   else
   return(0);   
}
 
Огромное спасибо!!!
 
Michael писал (а) >>

Большое спасибо, это то, что надо, но ... к сожалению цикл

очень долго выполняется, если к примеру шаг лота 0.01, а на депо осталось еще лотов 100, то цикл выполнится 10 тысяч раз, при этом мне надо для каждой вылюты вычислять на каждом проходе. Может есть способ обойтись без этого цикла и вычислять по аналогии, как это делает AccountFreeMarginCheck()?

Было бы супер!

Moжно ещё вот так:

//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start()
  {
   string symbol=Symbol();
   double vol=LotsCalculate(symbol,OP_BUY);
   Print("MaxLot= ", vol);  
   return(0);
  }
//+------------------------------------------------------------------+
double LotsCalculate(string symbol,int cmd)
  {
   double vol=10.0;
   for (int i=0;AccountFreeMarginCheck(symbol,cmd,vol)>0;i++){vol+=10.0;}
   vol=vol-10.0+1.0;
   for (i=0;AccountFreeMarginCheck(symbol,cmd,vol)>0;i++){vol+=1.0;}
   vol=vol-1.0+0.1;
   for (i=0;AccountFreeMarginCheck(symbol,cmd,vol)>0;i++){vol+=0.1;}
   vol=vol-0.1;
   if (0.01>=MarketInfo(symbol,MODE_MINLOT))
    {
     vol+=0.01;
     for (i=0;AccountFreeMarginCheck(symbol,cmd,vol)>0;i++)
      {vol-=0.01;}
    }   
   if (AccountFreeMarginCheck(symbol,cmd,vol) > 0)
    return(vol);
   return(0);   
  }
 

А есть ли способ обойтись без AccountFreeMarginCheck?

Проблема в том, что если вставить код в индикатор, то получаем ошибку "FreeMarginCheck function cannot be called from a custom indicator"

 

Я сделал так:

double maxLots(string symbol, int cmd) {
    double result = 0;
    double lotStep = MarketInfo(symbol, MODE_LOTSTEP);
    double v = MarketInfo(symbol, MODE_MINLOT);
    double mult = 100;
    
    while (true) {
        if (AccountFreeMarginCheck(symbol, cmd, v + lotStep * mult) > 0) {
            v = v + lotStep * mult;
        } else {
            mult = mult / 10;
            
            if (mult < 1) {
                if (AccountFreeMarginCheck(symbol, cmd, v) > 0) {
                    result = v;
                }
                break;
            }
        }
    }
    
    return(result);
}

10000 тысяч вызовов этой фичи выполняются за 800 - 900 мс, конечно, хотелось бы еще быстрее, для этого нужно вычислять по формуле, по которой работает AccountFreeMarginCheck(), не могли бы разработчики описать принцип работы функции AccountFreeMarginCheck() если это не секрет?

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