Нужна функция расчёта 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); }
что значит "более расширенная"? мне такой ф-ции хватает:
Этот вариант подходит для онлайн торговли, цифры берутся из терминала.
Мне же нужно восстановить 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. Вся загвоздка в том, что хотелось бы иметь функцию для разных валют депозита.
Мне же нужно восстановить 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
ЗЫ: если не секрет, зачем анализировать маржу на истории?
ЗЫ: если не секрет, зачем анализировать маржу на истории?
Не секрет! Делаю скрипт анализа (2-ю версию вот этой штуки https://www.mql5.com/ru/articles/1383), добрался до графической части и хотелось бы отображать графически всю информацию. т.е. восстанавливать из истории сделок всё что пожелаешь.
В результате думаю получится очень интересная картина торговли, то что скрыто от трейдера за многочисленными цифрами и длинными портянками закрытых позиций в истории. Да и граали могут стать не такими граалистыми когда видно больше чем даёт нам стандартный отчёт.
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);
Решение нашлось.
//+------------------------------------------------------------------+ //| Очень простая функция расчета маржи для форексных символов. | //| Расчет автоматически идет в базовой валюте счета и не работает | //| для сложных видов курсов, которые не имеют прямого пересчета | //| в базовую валюту торгового счета. | //+------------------------------------------------------------------+ 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/
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Нужна функция расчёта Margin, более расширенная нежели опубликованная тут https://www.mql5.com/ru/code/9537