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

 

Подскажите, кто знает, каким способом можно вычислить максимальный лот, которым можно встать в 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() если это не секрет?