Расчет свободных средств перед открытием позиции

 

Помогите разобраться!!!

Мне перед открытием позиции необходимо узнать сколько для этого понадобится свободных средств.

Взял пример из: Функции для управления капиталом в экспертах и получаю непонятные значения.

Например:

свободная маржа=8 586,69

лот беру: 0,1

вызываю функцию:

d_NeedMargin = GetMarginForOpening(lot, ex_Symbol, POSITION_TYPE_BUY);

d_NeedMargin == 10 654,8

Получается, что средств не хватает.

Но тут же можно открыть позицию с лотом в два раза большим 0,2 получается что средств хватает.


Не подскажите как правильно рассчитать сколько необходимо свободных средств для открытия позиции?

И желательно без параметра POSITION_TYPE_BUY так как заранее неизвестно покупка будет или продажа.

 

Предлагаю для расчета применить стандартную функцию OrderCalcMargin

 
avoitenko:

Предлагаю для расчета применить стандартную функцию OrderCalcMargin

Спасибо!

Все вроде заработало!!!!!!


P.S. Если полученное значение * 1.5 то значение то, что надо.

А то при открытии допустим 5 позиций последняя сделка может не открыться ввиду нехватки средств.

 

Прежде с функцией OrderCalcMargin() не работал. Почему вот этот скрипт возвращает нулевые значения?

double m;
void OnStart()
  {
    OrderCalcMargin(
                   ORDER_TYPE_BUY_STOP,// тип ордера
                   _Symbol,// имя символа
                   1.0,// объем
                   SymbolInfoDouble(_Symbol,SYMBOL_ASK),// цена открытия
                   m           // переменная для получения значения маржи
                   );
   Print("ORDER_TYPE_BUY_STOP, OrderCalcMargin(1.0)=",m);   
   
   OrderCalcMargin(
                   ORDER_TYPE_SELL_STOP,// тип ордера
                   _Symbol,// имя символа
                   1.0,// объем
                   SymbolInfoDouble(_Symbol,SYMBOL_BID),// цена открытия
                   m           // переменная для получения значения маржи
                   );
   Print("ORDER_TYPE_SELL_STOP, OrderCalcMargin(1.0)=",m);   
   
  }
 
Yedelkin:

Прежде с функцией OrderCalcMargin() не работал. Почему вот этот скрипт возвращает нулевые значения?

 

Может потому что ордера стоповые? Да и неплохо бы было проверять возвращаемое функцией значение, и если false, то выводить код ошибки.
Документация по MQL5: Стандартные константы, перечисления и структуры / Коды ошибок и предупреждений
Документация по MQL5: Стандартные константы, перечисления и структуры / Коды ошибок и предупреждений
  • www.mql5.com
Стандартные константы, перечисления и структуры / Коды ошибок и предупреждений - Документация по MQL5
 
marketeer:
Может потому что ордера стоповые? Да и неплохо бы было проверять возвращаемое функцией значение, и если false, то выводить код ошибки.

1. Из справки следует, что функция OrderCalcMargin() должна работать со всеми типами ордеров без исключения.

2. Функция возвращала значение true, поэтому сократил код в целях публикации на форуме. У Вас этот скрипт разве не ноль выдаёт? 

 
Yedelkin:

1. Из справки следует, что функция OrderCalcMargin() должна работать со всеми типами ордеров без исключения.

2. Функция возвращала значение true, поэтому сократил код в целях публикации на форуме. У Вас этот скрипт разве не ноль выдаёт? 

Я скрипт не проверял. Только хотел обратить внимание, что значение 0 еще не значит, что функция не работает. Стоповый ордер требует маржи?
 
marketeer:
Я скрипт не проверял. Только хотел обратить внимание, что значение 0 еще не значит, что функция не работает.

Понятно.

marketeer:
 Стоповый ордер требует маржи?

Расчёт маржи для открытия Stop-ордеров требуется для моей, как нынче модно говорить, "системы управления капиталом". 

...Кажется, понял, в чём дело. На форексных инструментах для отложенных ордеров маржа не взимается (то, о чём Вы говорите). Соответственно,  функция, рассчитывающая маржу под конкретный тип ордера,  возвращает ноль. Мне же требовалось рассчитать не маржу для выставления stop-ордеров, а маржу, которая потребуется при их срабатывании. Спасибо за подсказку!

 

Если валюта депозита и валюта маржи окажутся разными, то придётся переводить из одних единиц в другие. Я это делаю следующим образом:

double GetMarginEvgeTrofi(string fSymbol, int fType=0, string USD="USD"){
   double res;
   int i;
   string name;
   
   if(fType==0){
      res = SymbolInfoDouble(fSymbol, SYMBOL_MARGIN_LONG);
   }else{
      res = SymbolInfoDouble(fSymbol, SYMBOL_MARGIN_SHORT);
   }
   res = res * SymbolInfoDouble(fSymbol,SYMBOL_TRADE_CONTRACT_SIZE)/AccountInfoInteger(ACCOUNT_LEVERAGE);
//--- получим валюту счета
   string account_currency=AccountInfoString(ACCOUNT_CURRENCY);

//--- валюта, в которой берутся залоговые средства   
   string margin_currency=SymbolInfoString(fSymbol, SYMBOL_CURRENCY_MARGIN);
   
//--- если базовая валюта символа и  валюта депозита одинаковы
   if(margin_currency==account_currency) {
      //--- просто вернем значение контракта
      return(res);
   }
   //Print(DoubleToString(res,2)+" "+margin_currency);
   if(margin_currency!=USD){
      //Если валюта маржи не доллары, то переводим её в доллары
      for(i=0; i<SymbolsTotal(true); i++){
         name = SymbolName(i,true);
         if(SymbolInfoString(name, SYMBOL_CURRENCY_PROFIT) == margin_currency &&
            SymbolInfoString(name, SYMBOL_CURRENCY_BASE) == USD){
            res = res / PrCur(name, fType);
            margin_currency = USD;
            break;
         }else if(SymbolInfoString(name, SYMBOL_CURRENCY_PROFIT) == USD &&
                  SymbolInfoString(name, SYMBOL_CURRENCY_BASE) == margin_currency){
            res = res * PrCur(name, fType);
            margin_currency = USD;
            break;
         }
      }//Next i
   }
   
   if(margin_currency!=USD){
      Print(__FUNCTION__,"  Не удалось подобрать валюту расчета для комбинации символа "+fSymbol);
      Print("В списке 'Обзор рынка' необходимо, чтобы была отображена пара, в которой учавствуют "+ margin_currency+ " и USD.");
      return(NULL);
   }
   
   //Теперь, когда маржа вычисленна в долларах, её можно перевести в любую валюту депозита!
   
   if(margin_currency==account_currency) return(res);
   //Print(DoubleToString(res,2)+" "+margin_currency);
   for(i=0; i<SymbolsTotal(true); i++){
      name = SymbolName(i,true);
      if(SymbolInfoString(name, SYMBOL_CURRENCY_PROFIT) == margin_currency &&
         SymbolInfoString(name, SYMBOL_CURRENCY_BASE) == account_currency){
         res = res / PrCur(name, fType);
         margin_currency = account_currency;
         break;
      }else if(SymbolInfoString(name, SYMBOL_CURRENCY_PROFIT) == account_currency &&
               SymbolInfoString(name, SYMBOL_CURRENCY_BASE) == margin_currency){
         res = res * PrCur(name, fType);
         margin_currency = account_currency;
         break;
      }
   }//Next i
   
   if(margin_currency==account_currency) return(res);

   Print(__FUNCTION__,"  Не удалось конвертировать валюту "+margin_currency+" в "+account_currency+"! Требуется включить необходимую валютную пару в списке 'Обзор рынка'");
   return(NULL);

}//GetMarginEvgeTrofi()
//+------------------------------------------------------------------+
double PrCur(string fSymbol, int fType){
   //Возвращает цену символа (Ask - для покупки, Bid - для продажи)
   MqlTick tick;
   SymbolInfoTick(fSymbol, tick);
   if(fType == 0){
      return(tick.ask);
   }else{
      return(tick.bid);
   }
}//PrCur()

 Если где ошибся - подскажите плиз!

 
EvgeTrofi:

Если валюта депозита и валюта маржи окажутся разными, то придётся переводить из одних единиц в другие. Я это делаю следующим образом:

 Если где ошибся - подскажите плиз!


OrderCalcMargin

Вычисляет размер маржи, необходимой для указанного типа ордера на текущем счете и при текущем рыночном окружении без учета текущих отложенных ордеров и открытых позиций. Позволяет оценить размер маржи для планируемой торговой операции. Значение возвращается в валюте счета.

Разве этого не достаточно ?

 
Valmars:

OrderCalcMargin

Вычисляет размер маржи, необходимой для указанного типа ордера на текущем счете и при текущем рыночном окружении без учета текущих отложенных ордеров и открытых позиций. Позволяет оценить размер маржи для планируемой торговой операции. Значение возвращается в валюте счета.

Разве этого не достаточно ?

Функция OrderCalcMargin не работает в пользовательских индикаторах. Возвращает false. и ошибку:

ERR_FUNCTION_NOT_ALLOWED

4014

Системная функция не разрешена для вызова

 

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