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

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
pusheax
698
pusheax  

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

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

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

Например:

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

лот беру: 0,1

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

d_NeedMargin = GetMarginForOpening(lot, ex_Symbol, POSITION_TYPE_BUY);

d_NeedMargin == 10 654,8

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

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


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

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

Andrey Voytenko
29403
Andrey Voytenko  

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

pusheax
698
pusheax  
avoitenko:

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

Спасибо!

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


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

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

Yedelkin
4193
Yedelkin  

Прежде с функцией 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);   
   
  }

 

Stanislav Korotky
22192
Stanislav Korotky  
Yedelkin:

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

 

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

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

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

Stanislav Korotky
22192
Stanislav Korotky  
Yedelkin:

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

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

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

Понятно.

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

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

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

Evgeniy Trofimov
2633
Evgeniy Trofimov  

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

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()

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

Валерий
1411
Валерий  
EvgeTrofi:

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

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


OrderCalcMargin

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

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

Evgeniy Trofimov
2633
Evgeniy Trofimov  
Valmars:

OrderCalcMargin

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

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

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

ERR_FUNCTION_NOT_ALLOWED

4014

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

 

12
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий