[РЕШЕНО]OrderCalcMargin и проблема с ним связанная. - страница 4

 

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Kirill Belousov, 2017.10.05 07:33

Вот тест:

#define TOSTRING(A) #A+" = "+(string)(A)
void OnStart()
  {
   double margin_1=999,price_1;

   Print(TOSTRING(price_1=SymbolInfoDouble(Symbol(),SYMBOL_ASK)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print(TOSTRING(price_1=SymbolInfoDouble(Symbol(),SYMBOL_BID)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print(TOSTRING(price_1=10.0));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print(TOSTRING(price_1=1.0));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
   Print("price_1= ",price_1," margin_1= ",NormalizeDouble(margin_1,8)," ",TOSTRING(MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1)));
//выведем признак выбранности мажоров
   Print(TOSTRING(SymbolInfoInteger("GBPUSD",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("USDJPY",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("USDCAD",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("AUDUSD",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("NZDUSD",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("USDCHF",SYMBOL_SELECT)));
   Print(TOSTRING(SymbolInfoInteger("EURUSD",SYMBOL_SELECT)));
   for(int i=SymbolsTotal(false);i>=0;i--)
     {
       //проверим для каждого символа брокера ситуацию, когда OrderCalcMargin()==true, а маржа=0
       if(OrderCalcMargin(ORDER_TYPE_BUY,SymbolName(i,false),0.1,SymbolInfoDouble(SymbolName(i,false),SYMBOL_ASK),margin_1)==true && margin_1==0)
        {
         Print(TOSTRING(SymbolName(i,false))," ",TOSTRING(margin_1)," ");
        }
     }
  }

// Альтернатива OrderCalcMargin
bool MyOrderCalcMargin(const ENUM_ORDER_TYPE action,const string symbol,const double volume,const double price,double &margin)
  {
   double MarginInit,MarginMain;

   const bool Res=SymbolInfoMarginRate(symbol,action,MarginInit,MarginMain);

   margin=Res ? MarginInit*price*volume*SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_VALUE)/
          (SymbolInfoDouble(symbol,SYMBOL_TRADE_TICK_SIZE)*AccountInfoInteger(ACCOUNT_LEVERAGE)) : 0;

   return(Res);
  }

1. Выберем в MarketWatch кроссы, а все с USD скроем

2.Добавим символ DSHBTC и откроем его график.

3. Закроем терминал

4. Откроем терминал

5. Запустим тест на DSHBTC

Вот ЛОГ:

JM      0       09:26:05.485    test (DSHBTC,H1)        price_1=SymbolInfoDouble(Symbol(),SYMBOL_ASK) = 0.07183
QK      0       09:26:05.487    test (DSHBTC,H1)        price_1= 0.07183 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
KO      0       09:26:05.487    test (DSHBTC,H1)        price_1= 0.07183 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
QN      0       09:26:05.487    test (DSHBTC,H1)        price_1=SymbolInfoDouble(Symbol(),SYMBOL_BID) = 0.07079000000000001
NJ      0       09:26:05.487    test (DSHBTC,H1)        price_1= 0.07079000000000001 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
HO      0       09:26:05.487    test (DSHBTC,H1)        price_1= 0.07079000000000001 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
LL      0       09:26:05.487    test (DSHBTC,H1)        price_1=10.0 = 10.0
EE      0       09:26:05.487    test (DSHBTC,H1)        price_1= 10.0 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
QF      0       09:26:05.487    test (DSHBTC,H1)        price_1= 10.0 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
HD      0       09:26:05.487    test (DSHBTC,H1)        price_1=1.0 = 1.0
EN      0       09:26:05.487    test (DSHBTC,H1)        price_1= 1.0 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
OM      0       09:26:05.487    test (DSHBTC,H1)        price_1= 1.0 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
EN      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(GBPUSD,SYMBOL_SELECT) = 0
GI      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(USDJPY,SYMBOL_SELECT) = 0
DS      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(USDCAD,SYMBOL_SELECT) = 0
JL      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(AUDUSD,SYMBOL_SELECT) = 0
JF      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(NZDUSD,SYMBOL_SELECT) = 0
MQ      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(USDCHF,SYMBOL_SELECT) = 0
HK      0       09:26:05.487    test (DSHBTC,H1)        SymbolInfoInteger(EURUSD,SYMBOL_SELECT) = 0
LH      0       09:26:05.488    test (DSHBTC,H1)        SymbolName(i,false) = DSHBTC margin_1 = 0.0 
RS      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = NZDJPY margin_1 = 0.0 
FE      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = NZDCHF margin_1 = 0.0 
QO      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = NZDCAD margin_1 = 0.0 
RP      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = GBPNZD margin_1 = 0.0 
JD      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = GBPCAD margin_1 = 0.0 
CN      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = GBPJPY margin_1 = 0.0 
KP      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = GBPCHF margin_1 = 0.0 
JK      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = GBPAUD margin_1 = 0.0 
QL      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURNZD margin_1 = 0.0 
RG      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURJPY margin_1 = 0.0 
RH      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURGBP margin_1 = 0.0 
HS      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURCHF margin_1 = 0.0 
CD      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURCAD margin_1 = 0.0 
GO      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = EURAUD margin_1 = 0.0 
QP      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = CHFJPY margin_1 = 0.0 
JJ      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = CADJPY margin_1 = 0.0 
JL      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = CADCHF margin_1 = 0.0 
QF      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = AUDNZD margin_1 = 0.0 
NI      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = AUDJPY margin_1 = 0.0 
JS      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = AUDCHF margin_1 = 0.0 
EF      0       09:26:05.489    test (DSHBTC,H1)        SymbolName(i,false) = AUDCAD margin_1 = 0.0 

По всем кроссам показывает маржу=0  и МАЖОРЫ ДЛЯ КРОССОВ НЕ ВЫБРАЛИСЬ.

Еще раз накинем скрипт на DSHBTC

ЛОГ

HF      0       09:29:07.268    test (DSHBTC,H1)        price_1=SymbolInfoDouble(Symbol(),SYMBOL_ASK) = 0.07185999999999999
IQ      0       09:29:07.268    test (DSHBTC,H1)        price_1= 0.07185999999999999 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
KP      0       09:29:07.268    test (DSHBTC,H1)        price_1= 0.07185999999999999 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
DE      0       09:29:07.269    test (DSHBTC,H1)        price_1=SymbolInfoDouble(Symbol(),SYMBOL_BID) = 0.07087
OQ      0       09:29:07.269    test (DSHBTC,H1)        price_1= 0.07087 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
MQ      0       09:29:07.269    test (DSHBTC,H1)        price_1= 0.07087 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
QP      0       09:29:07.269    test (DSHBTC,H1)        price_1=10.0 = 10.0
HI      0       09:29:07.269    test (DSHBTC,H1)        price_1= 10.0 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
LK      0       09:29:07.269    test (DSHBTC,H1)        price_1= 10.0 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
MH      0       09:29:07.269    test (DSHBTC,H1)        price_1=1.0 = 1.0
HR      0       09:29:07.269    test (DSHBTC,H1)        price_1= 1.0 margin_1= 0.0 OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
NP      0       09:29:07.269    test (DSHBTC,H1)        price_1= 1.0 margin_1= 0.0 MyOrderCalcMargin(ORDER_TYPE_BUY,_Symbol,0.1,price_1,margin_1) = true
GR      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(GBPUSD,SYMBOL_SELECT) = 1
FM      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(USDJPY,SYMBOL_SELECT) = 0
JG      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(USDCAD,SYMBOL_SELECT) = 1
DP      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(AUDUSD,SYMBOL_SELECT) = 1
DJ      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(NZDUSD,SYMBOL_SELECT) = 1
OE      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(USDCHF,SYMBOL_SELECT) = 1
FO      0       09:29:07.269    test (DSHBTC,H1)        SymbolInfoInteger(EURUSD,SYMBOL_SELECT) = 1
DD      0       09:29:07.269    test (DSHBTC,H1)        SymbolName(i,false) = DSHBTC margin_1 = 0.0 

Выбрались мажоры, но кроме USDJPY

Все тесты проводились на MetaQuotes



Этот скрипт запускался на одном символе, а считали по разным? Я правильно понял?

 
Alexey Viktorov:

Этот скрипт запускался на одном символе, а считали по разным? Я правильно понял?

Да. Искал по всем символам брокера, где функция OrderCalcMargin() подсчитывается, но маржа=0
 

Похоже что проблема выявлена. Для получения маржи кроссам должны быть в обзоре рынка символы с валютой депозита. То-есть для получения маржи по GBPJPY нужны символы GBPUSD и USDJPY

 
Alexey Viktorov:

Похоже что проблема выявлена. Для получения маржи кроссам должны быть в обзоре рынка символы с валютой депозита. То-есть для получения маржи по GBPJPY нужны символы GBPUSD и USDJPY

Пробовал, перед получением маржи, добавить эти символы в обзор рынка? Получилось?

 
Artyom Trishkin:

Пробовал, перед получением маржи, добавить эти символы в обзор рынка? Получилось?

Да.

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

Alexey Viktorov, 2017.10.05 09:46

Добавьте в начало скрипта такой цикл

   for(int i = 0; i < SymbolsTotal(true); i++)
     Print(SymbolName(i, true));

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

При первом запуске обращение к AUDJPY только добавляет в обзор рынка AUDUSD и USDJPY и только при втором обращении через эти пары получает свойство символа. Именно это и вызывает проблему с OrderCalcMargin в моём случае.

Осталось разобраться как пограмотней определить какую валюту добавлять.
 

Можно даже ничего не изобретать. Достаточно вставить в цикл небольшую задержку

   do
    {
     calcMargin = OrderCalcMargin(m_orderType, _Symbol, lots, price, margin);
     Sleep(50);
     k++;
    }
   while(margin <= 0);
     Print(_Symbol, " ", k, " error ", _LastError);
2017.10.05 11:17:21.559 TestCalcMargin (CADJPY,H1)      CADJPY 2 error 0

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

 
Alexey Viktorov:

Можно даже ничего не изобретать. Достаточно вставить в цикл небольшую задержку

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

Вы только о конкретном случае говорите или смотрели это для всех случаев - график при открытии терминала не открыт (символ выбран), график не открыт и символ не выбран, советник мультивалютный для обоих предыдущих случаев?
 
Kirill Belousov:
Вы только о конкретном случае говорите или смотрели это для всех случаев - график при открытии терминала не открыт (символ выбран), график не открыт и символ не выбран, советник мультивалютный для обоих предыдущих случаев?

Если инструмент пересчёта из валюты маржи в валюту депозита присутствует в обзоре рынка, то никаких проблем не возникает.

Если его нет, то при первом обращении происходит добавление этого инструмента, но без паузы вторая попытка получить размер маржи не даст положительного результата. Пауза обязательна. Длительность поставлена "от фонаря", 5 мало, поставил 50, хватило. На этом я и закончил.

Если советник мультивалютный, значит график инструмента по которому открывается ордер открыт, а с инструментом пересчёта маржи всё то-же самое как описано выше.

Началось отсюда

Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий

Ошибки, баги, вопросы

fxsaber, 2017.10.05 08:04

Воспроизведение бага

  1. Заходим на Metaquotes-Demo.
  2. В обзоре рынка оставляет только AUDJPY и открываем его чарт.
  3. Перезагружаем терминал и ждем полноценного подключения - котиры идут.
  4. Запускаем скрипт на чарте

void OnStart()
{  
  for (int i = 0; i < 5; i++)
    Print(SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE));
}


Результат такой

2017.10.05 09:02:27.460 Test6 (AUDJPY,M1)       0.0
2017.10.05 09:02:27.460 Test6 (AUDJPY,M1)       0.0
2017.10.05 09:02:27.460 Test6 (AUDJPY,M1)       0.0
2017.10.05 09:02:27.460 Test6 (AUDJPY,M1)       0.0
2017.10.05 09:02:27.460 Test6 (AUDJPY,M1)       0.0


Повторный запуск

2017.10.05 09:02:32.028 Test6 (AUDJPY,M1)       0.8868393047179851
2017.10.05 09:02:32.028 Test6 (AUDJPY,M1)       0.8868393047179851
2017.10.05 09:02:32.028 Test6 (AUDJPY,M1)       0.8868393047179851
2017.10.05 09:02:32.028 Test6 (AUDJPY,M1)       0.8868393047179851
2017.10.05 09:02:32.028 Test6 (AUDJPY,M1)       0.8868393047179851


Т.е. SYMBOL_TRADE_TICK_VALUE возвращает нули при первом запуске, если не делать Sleep();


ЗЫ На тему невидимого символа в Обзоре рынка. Если до шага запуска скрипта попытаться открыть чарт USDJPY (нажать Enter и ввести "USDJPY"), то ничего не получится. А если после запуска скрипта - получится. Хотя Обзор рынка не изменился.


 
Предложенный способ не всегда работает. Например, у одного брокера на долларовом демо-счете маржа для UKBrent (который по спецификации торгуется, как фьючерс, котируемый в том же долларе) всегда равна 0. Речь про OrderCalcMargin. OrderCheck маржу возвращает, но только если автоторговля разрешена, а если запрещена - получаем код ERR_TRADE_DISABLED вместо маржи. Очень неудобно, если MQL-программа используется для анализа маржи для ручной торговли.
Причина обращения: