Скачать MetaTrader 5
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Интересуют возможности MQL5? Загляни в документацию!
Nefedov Kirill
2889
Nefedov Kirill 2011.05.29 18:13 

Нужна функция расчёта Margin, более расширенная нежели опубликованная тут https://www.mql5.com/ru/code/9537

IgorM М
4801
IgorM М 2011.05.29 18:27  
HIDDEN:

Нужна функция расчёта Margin, более расширенная нежели опубликованная тут https://www.mql5.com/ru/code/9537

что значит "более расширенная"? мне такой ф-ции хватает:

double calcmargin(double lot,int cmd){
   double margin = AccountMargin();
   double tmp=NormalizeDouble(AccountFreeMargin()-AccountFreeMarginCheck(Symbol(),cmd,lot),2);
   if(AccountBalance()-tmp>0) margin+=tmp; else margin =-1;
return(margin);
}
Nefedov Kirill
2889
Nefedov Kirill 2011.05.29 18:37  
IgorM:

что значит "более расширенная"? мне такой ф-ции хватает:


Этот вариант подходит для онлайн торговли, цифры берутся из терминала.

Мне же нужно восстановить Margin из истории сделок. т.е. где-то в истории есть закрытый ордер, хотелось бы узнать какова была маржа в тот момент при закрытии ордера из истории.

double MarginCalculate(string symbol, double volume, int bar = 0)
  {
   string first    = StringSubstr(symbol,0,3); // первый символ,   например EUR
   string second   = StringSubstr(symbol,3,3); // второй символ,   например USD
   string currency = AccountCurrency();        // валюта депозита, например USD
   double leverage = AccountLeverage();        // кредитное плечо, например 100
// размер контракта, например 100000
   double contract = MarketInfo(symbol, MODE_LOTSIZE);
   double bid      = MarketInfo(symbol, MODE_BID);      // цена бид
//---- допускаем только стандартные форексные символы XXXYYY
   if(StringLen(symbol) != 6)
     {
      Print("MarginCalculate: '",symbol,"' must be standard forex symbol XXXYYY");
      return(0.0);
     }
//---- проверка наличия данных
   if(bid <= 0 || contract <= 0) 
     {
      Print("MarginCalculate: no market information for '",symbol,"'");
      return(0.0);
     }
//---- проверяем самые простые варианты - без кроссов
   if(first == currency)   
       return(contract*volume / leverage);           // USDxxx
   if(second == currency)  
       return(contract*bid*volume / leverage);       // xxxUSD
//---- проверяем обычные кроссы, ищем прямое преобразование через валюту депозита
   string base = currency + first;                   // USDxxx
   if(iClose(base, PERIOD_M1,bar) > 0) 
       return(contract / iClose(base, PERIOD_M1,bar) * volume / leverage);
//---- попробуем наоборот
   base = first + currency;                          // xxxUSD
   if(iClose(base, PERIOD_M1,bar) > 0) 
       return(contract * iClose(base, PERIOD_M1,bar) * volume / leverage);
//---- нет возможности прямого перерасчета
   Print("MarginCalculate: can not convert '",symbol,"'");
   return(0.0);
  }

Понятно что грубоватый расчёт идёт, но в моем случае точность сильная не нужна (хотя желательно, но не возможно). Данный пример не способен рассчитать маржу скажем для AUDUSD, возможно кто-то довел данную функцию до более сложного вида расчётов. Если есть прошу поделитесь.

P.S. Вся загвоздка в том, что хотелось бы иметь функцию для разных валют депозита.

IgorM М
4801
IgorM М 2011.05.29 18:46  
HIDDEN:

Мне же нужно восстановить Margin из истории сделок. т.е. где-то в истории есть закрытый ордер, хотелось бы узнать какова была маржа в тот момент при закрытии ордера из истории.

в принципе несложная задачка, вот так рассчитывается маржа:

Финансовый инструмент: валютная пара EURUSD.
Объем позиции — 1 стандартный лот (на валютном рынке Форекс — это 100 000 единиц базовой валюты, в данном случае EUR), кредитное плечо 1:100, текущий курс EURUSD = 1.6000.
Маржа = 100000 / 100 = 1000 EUR, или 1000 × 1.6000 = 1600 USD

значит нужно брать стоимость мажоров входящих в кросс на момент закрытия ордера - наименьший ТФ это М1, из OHLC думаю целесообразно использовать Close, думаю приведенный Вами код правильно будет работать, достаточно заменить Bid на Close

для кроссов http://www.mrcmarkets.ru/information/deposit/msize.php

ЗЫ: если не секрет, зачем анализировать маржу на истории?

Nefedov Kirill
2889
Nefedov Kirill 2011.05.29 18:53  
IgorM:

ЗЫ: если не секрет, зачем анализировать маржу на истории?


Не секрет! Делаю скрипт анализа (2-ю версию вот этой штуки https://www.mql5.com/ru/articles/1383), добрался до графической части и хотелось бы отображать графически всю информацию. т.е. восстанавливать из истории сделок всё что пожелаешь.

В результате думаю получится очень интересная картина торговли, то что скрыто от трейдера за многочисленными цифрами и длинными портянками закрытых позиций в истории. Да и граали могут стать не такими граалистыми когда видно больше чем даёт нам стандартный отчёт.

IgorM М
4801
IgorM М 2011.05.29 19:30  

https://www.mql5.com/ru/forum/113937

для кроссов формула:http://www.nwbroker.ru/analytics/formul/ margin = 100000$*C*B*n, где C - текущая котировка по паре XXX/USD, B - размер кредитного плеча, n -количестово лотов

основная проблема правильно определить название мажоров, а сам расчет маржи на истории я думаю так будет выглядеть:

.....
margin = -1;
if (sym_major!=""){
         B = AccountLeverage();
         C = iClose(sym,PERIOD_M1,iBarShift(sym,PERIOD_M1,_time));
         margin = 100000*C*B*lot;
      }
return(margin);
Nefedov Kirill
2889
Nefedov Kirill 2011.05.29 19:34  

Решение нашлось.

//+------------------------------------------------------------------+
//| Очень простая функция расчета маржи для форексных символов.      |
//| Расчет автоматически идет в базовой валюте счета и не работает   |
//| для сложных видов курсов, которые не имеют прямого пересчета     |
//| в базовую валюту торгового счета.                                |
//+------------------------------------------------------------------+
double MarginCalculate(string symbol, double volume, int bar = 0){
   double Margin   = 0;
   string first    = StringSubstr(symbol,0,3); // первый символ,   например EUR
   string second   = StringSubstr(symbol,3,3); // второй символ,   например USD
   string currency = "USD";        // валюта депозита, например USD
   double leverage = AccountLeverage();        // кредитное плечо, например 100
// размер контракта, например 100000
   double contract = MarketInfo(symbol, MODE_LOTSIZE);
   double bid      = MarketInfo(symbol, MODE_BID);      // цена бид
//---- допускаем только стандартные форексные символы XXXYYY
   if(StringLen(symbol) != 6){
      Print("MarginCalculate: '",symbol,"' must be standard forex symbol XXXYYY");
      return(0.0);
     }
//---- проверка наличия данных
   if(bid <= 0 || contract <= 0){
      Print("MarginCalculate: no market information for '",symbol,"'");
      return(0.0);
     }
//---- проверяем самые простые варианты - без кроссов
   if(first == currency){
      if (AccountCurrency() == "RUR"){
         Margin = (contract * volume / leverage) * iClose("USDRUR", PERIOD_M1,bar);
      } else {
         Margin = (contract * volume / leverage);
      }
      return(NormalizeDouble(Margin,2));           // USDxxx
   }
   if(second == currency){
      if (AccountCurrency() == "RUR"){
         Margin = (contract * bid * volume / leverage) * iClose("USDRUR", PERIOD_M1,bar);
      } else {
         Margin = (contract * bid * volume / leverage);
      }
      return(NormalizeDouble(Margin,2));     // xxxUSD
   }
//---- проверяем обычные кроссы, ищем прямое преобразование через валюту депозита
   string base = currency + first;                   // USDxxx
   if(iClose(base, PERIOD_M1,bar) > 0){
      if (AccountCurrency() == "RUR"){
         Margin = (contract / iClose(base, PERIOD_M1,bar) * volume / leverage) * iClose("USDRUR", PERIOD_M1,bar);
      } else {
         Margin = (contract / iClose(base, PERIOD_M1,bar) * volume / leverage);
      }
      return(NormalizeDouble(Margin,2));
   }
//---- попробуем наоборот
   base = first + currency;                          // xxxUSD
   if(iClose(base, PERIOD_M1,bar) > 0){
      if (AccountCurrency() == "RUR"){
         Margin = (contract * iClose(base, PERIOD_M1,bar) * volume / leverage) * iClose("USDRUR", PERIOD_M1,bar);
      } else {
         Margin = (contract * iClose(base, PERIOD_M1,bar) * volume / leverage);
      }
      return(NormalizeDouble(Margin,2));
   }
//---- нет возможности прямого перерасчета
   Print("MarginCalculate: can not convert '",symbol,"'");
   return(0.0);
  }
//+------------------------------------------------------------------+
//| script program start function                                    |
//+------------------------------------------------------------------+
int start(){
//----
   Print(MarginCalculate( "AUDUSD", 1, 0 ));
//----
   return(0);
  }
//+------------------------------------------------------------------+

Универсальность конечно же страдает, но расчёты вот с этим калькулятором совпадают. http://www.alpari.ru/ru/calculator/

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