И снова маржа...

 

Приветствую всех.

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

Только и нужно-то получить по каждому инструменту размер требуемой маржи для открытия ордера (1 лот).

Правила известны и давно обсуждались:

1. Если валюта для вычисления залога равна валюте депозита - размер контракта / плечо
2. Если валюты не равны, тогда ищем пару <валюта залога + валюта депозита>, если есть, тогда: ( ask + bid ) / 2.0 * размер контракта / плечо

3. Если валюты не равны и нет пары <валюта залога + валюта депозита>, тогда ищем пару <валюта депозита + валюта залога>, если есть тогда: 1 / (( ask + bid ) / 2.0) * размер контракта / плечо 

Это в теории... 

Да вот неувязочки выходят со стандартными функциями как ни крути.

Пример скрипта:

//+------------------------------------------------------------------+
//|                                                   MarginCalc.mq4 |
//|                                   Copyright 2014, Eugene Lugovoy |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2014, Eugene Lugovoy"
#property link      "http://www.mql5.com"
#property version   "1.00"
#property strict
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
 Print("Symbols activation...");
 ActivateAllSymbols();
 Print("Done.");

 Print("Begin of Margin list:");
 ShowMargin();
 Print("End of Margin list.");
 
 Print("Symbols de-activation...");
 DeactivateAllSymbols();
 Print("Done.");
 Print("Script Done!");
   
}

void ActivateAllSymbols()
{
 int i;
 for (i=0;i<SymbolsTotal(false);i++)
     {
      SymbolSelect(SymbolName(i,false),true);
     }
}

void DeactivateAllSymbols()
{
 int i;
 for (i=SymbolsTotal(false)-1;i>=0;i--)
     {
      SymbolSelect(SymbolName(i,false),false);
     }
}

void ShowMargin()
{
 int i;
 string symbol;
 double margin1, margin2, margin3;
 Print ("Leverage: ",AccountLeverage());
 for (i=0;i<SymbolsTotal(true);i++)
     {
      symbol = SymbolName(i,true);
      margin1 = GetMargin1(symbol);
      margin2 = GetMargin2(symbol);
      Print(symbol,": lot=",MarketInfo(symbol, MODE_LOTSIZE),"> ",margin1,", ",margin2);
     }
}

double GetMargin1(string p_symbol)
{
 double result;
 double m1,m2;
 
 m1 = MathAbs(AccountFreeMargin() - AccountFreeMarginCheck(p_symbol, OP_BUY, 1.0));
 m2 = MathAbs(AccountFreeMargin() - AccountFreeMarginCheck(p_symbol, OP_SELL, 1.0));
 if (m1>m2) { result = m1; } else {result = m2;}
 return (result);
}

double GetMargin2(string p_symbol)
{
 double result;
 result = MarketInfo(p_symbol, MODE_MARGINREQUIRED);
 return (result);
}

 

Валюта депозита USD, плечо 500 

По первому варианту (валюта для вычисления залога равна валюте депозита - размер контракта / плечо) пару результатов:

0    23:17:09.089    MarginCalc EURUSD,H1: USDPLN: lot=100000.0> 200.0, 200.0
0    23:17:09.089    MarginCalc EURUSD,H1: USDRON: lot=100000.0> 200.0, 200.0
0    23:17:09.089    MarginCalc EURUSD,H1: USDRUB: lot=100000.0> 8000.0, 8000.0
0    23:17:09.089    MarginCalc EURUSD,H1: USDSEK: lot=100000.0> 200.0, 200.0
Плечо 500, валюта USD, а для USDRUB залог 8000 вместо 200...

USDRUB хз как вычисляется, или плечо другое под нее...

Плюс получаю результаты типа:

0       23:17:09.042    MarginCalc EURUSD,H1: CADCHF: lot=100000.0> 1.#INF, -9.223372036854776e+016
0       23:17:09.042    MarginCalc EURUSD,H1: CADJPY: lot=100000.0> 1.#INF, -9.223372036854776e+016
0       23:17:09.042    MarginCalc EURUSD,H1: CAHIC: lot=500.0> 1.#QNAN, -9.223372036854776e+016

Или

0       23:17:09.042    MarginCalc EURUSD,H1: CALI: lot=150.0> 0.0, 0.0
0       23:17:09.042    MarginCalc EURUSD,H1: CAP: lot=500.0> 0.0, 0.0
0       23:17:09.042    MarginCalc EURUSD,H1: CARREF: lot=1000.0> 0.0, 0.0

Все символы в MarketWatch присутствуют на момент запуска.

По CFDs вообще хз как считать:

23:17:09.042    MarginCalc EURUSD,H1: AGSW: lot=500.0> 1.#INF, -9.223372036854776e+016 (при закрытом чарте)
23:11:13.496    MarginCalc EURUSD,H1: AGSW: lot=500.0> 13.47999063889438, 13.48 (при открытом чарте)

Bid = 8.62, Ask = 8.64

Размер контракта/плечо = 1, как 13.48 получить...?

если кто в теме - help! 

 

1. Нашел как избавиться от "1.#INF" и "1.#QNAN". Нужно отправить ордер брокеру перед запросом функций, можно отложенный, даже если не откроется, все равно данные будут уже более менее правильными.

2. Кстати, в расчетах упустил валюту для расчета маржи, она может быть установлена для каждого инструмента своя. Хотя...

0    11:00:23.453    MarginCalc EURUSD,H1: USDRON: lot=100000.0> 200.0, 200.0, MSYM: USD
0    11:00:23.453    MarginCalc EURUSD,H1: USDRUB: lot=100000.0> 8000.0, 8000.0, MSYM: USD
0    11:00:23.453    MarginCalc EURUSD,H1: USDSEK: lot=100000.0> 200.0, 200.0, MSYM: USD
0    11:00:23.453    MarginCalc EURUSD,H1: USDSGD: lot=100000.0> 200.0, 200.0, MSYM: USD
0    11:00:23.453    MarginCalc EURUSD,H1: USDTRY: lot=100000.0> 200.0, 200.0, MSYM: USD
0    11:00:23.453    MarginCalc EURUSD,H1: USDZAR: lot=100000.0> 200.0, 200.0, MSYM: USD

 

у всех валюта расчета залоговых средств USD,  а по USDRUB - результат 8000...

 

Эврика!

Оказывается на стороне сервера по каждому инструменту есть спец настроечка для маржи. и по факту формула:

lots * contract size / leverage * percentage / 100 

Как раз "percentage" установлен в 4000... поэтому по USDRUB размер маржи в 40 раз больше...

Тема закрыта. Но может кому понадобятся эти разборки... 

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