Ошибки, баги, вопросы - страница 3669

 
Yuriy Bykov #:
И не забыть домножить на величину одного пункта: Ask + 1000 * _Point и Ask - 1000 * _PointСпасиьбо

Спасибо всем, эта окончательная форма и подошла в конце.

 
Aleksei Skrypnev #:

Спасибо всем, эта окончательная форма и подошла в конце.

И даже нормализация не понадобилась?
;)
 
Sergey Gridnev #:
И даже нормализация не понадобилась?
;)
В моём случае не понадобилась. Хотя я про неё думал, до до неё не дошло.
 

Здравствуйте. 

CAccountInfo MaxLotCheck не возвращает правильное значение на некоторых символах, например GOLD и BITCOIN. Рисует 500, что является значением SYMBOL_VOLUME_MAX, то есть Максимальным объемом из Спецификации.

Прочитал мнение аксакалов форума о том, что многое зависит от конкретного брокера и конкретного инструмента. Если это так, то как вообще можно доверять какой-то информации, если её могут подменять как угодно или вовсе не возвращать. 

Если кто-то сталкивался с подобным, то с благодарностью приму совет как и мне решить эту проблему. Если остается только уповать на брокера, то хотелось бы получить подтверждения и этого. Спасибо.


Продолжаю расследование.

Смотрю в исходник CAccountInfo::MaxLotCheck.

Он опирается на функцию OrderCalcMargin:

double CAccountInfo::MaxLotCheck(const string symbol,const ENUM_ORDER_TYPE trade_operation,
                                 const double price,const double percent) const
  {
   double margin=0.0;
//--- проверки
   if(symbol=="" || price<=0.0 || percent<1 || percent>100)
     {
      Print("CAccountInfo::MaxLotCheck invalid parameters");
      return(0.0);
     }
//--- calculate margin requirements for 1 lot
   if(!OrderCalcMargin(trade_operation,symbol,1.0,price,margin) || margin<0.0)
     {
      Print("CAccountInfo::MaxLotCheck margin calculation failed");
      return(0.0);
     }
//--- 
   if(margin==0.0) // для отложенных ордеров
      return(SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX));
//--- вычисление максимального объема
   double volume=NormalizeDouble(FreeMargin()*percent/100.0/margin,2);
//--- нормализация и проверка лимитов
   double stepvol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_STEP);
   if(stepvol>0.0)
      volume=stepvol*MathFloor(volume/stepvol);
//--- 
   double minvol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);
   if(volume<minvol)
      volume=0.0;
//--- 
   double maxvol=SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX);
   if(volume>maxvol)
      volume=maxvol;
//--- возвращается объем 
   return(volume);
  }

Обращаю внимание на фрагмент кода:

//--- calculate margin requirements for 1 lot
   if(!OrderCalcMargin(trade_operation,symbol,1.0,price,margin) || margin<0.0)
     {
      Print("CAccountInfo::MaxLotCheck margin calculation failed");
      return(0.0);
     }
//--- 
   if(margin==0.0) // для отложенных ордеров
      return(SymbolInfoDouble(symbol,SYMBOL_VOLUME_MAX));

Вызываю отдельно OrderCalcMargin, возвращает значение выше нуля. Но при этом MaxLotCheck ведет себя так, как будто margin==0.0 и возвращает мне SYMBOL_VOLUME_MAX.

Документация по MQL5: Стандартная библиотека / Торговые классы / CAccountInfo
Документация по MQL5: Стандартная библиотека / Торговые классы / CAccountInfo
  • www.mql5.com
Класс CAccountInfo является классом для упрощенного доступа к свойствам текущего открытого торгового счета. Класс CAccountInfo обеспечивает доступ...
 
seldes #:

Здравствуйте. 

CAccountInfo MaxLotCheck не возвращает правильное значение на некоторых символах, например GOLD и BITCOIN. Рисует 500, что является значением SYMBOL_VOLUME_MAX, то есть Максимальным объемом из Спецификации.

Прочитал мнение аксакалов форума о том, что многое зависит от конкретного брокера и конкретного инструмента. Если это так, то как вообще можно доверять какой-то информации, если её могут подменять как угодно или вовсе не возвращать. 

Если кто-то сталкивался с подобным, то с благодарностью приму совет как и мне решить эту проблему. Если остается только уповать на брокера, то хотелось бы получить подтверждения и этого. Спасибо.

Думаю это проблема брокера, так как лимиты на торговые обьемы ставит именно брокер. Терминалу абсолютно все равно хоть лимит 10 хоть 100500. 
 
Vladimir Pastushak #:
Думаю это проблема брокера, так как лимиты на торговые обьемы ставит именно брокер. Терминалу абсолютно все равно хоть лимит 10 хоть 100500. 

Заметил интересное. 

OrderCalcMargin

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

возвращает мне 0.37  на GOLD, цена которому 3700. Купить 1 лот золота по 37 центов я никак не могу, хотя хотелось бы :)

Из-за этого в дальнейшем вычислении максимальный лот начинает сильно превышать SYMBOL_VOLUME_MAX, который мне функция и возвращает.

Складывается ощущение, что функция OrderCalcMargin ошибочно работает с ценами больше какой-то суммы. 

Например, 1 лот EURUSD можно купить за 2355, что верно.

Но купить 1 лот NVIDIA по 7 долларов при цене 175 за акцию, если верить тому же OrderCalcMargin, никак не получится.



Дополню. 

OrderCalcMargin рассчитывается по-разному в зависимости от способа вычисления. Думаю, ошибка (моя или не моя, пока не разобрался) в этом. 

 ENUM_SYMBOL_CALC_MODE
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
Documentation on MQL5: Constants, Enumerations and Structures / Environment State / Symbol Properties
  • www.mql5.com
To obtain the current market information there are several functions: SymbolInfoInteger() , SymbolInfoDouble() and SymbolInfoString() . The first...
 

Действительно, опираясь на SYMBOL_TRADE_CALC_MODE, стало понятно, что маржа за лот высчитывается по формуле Margin: Lots * InitialMargin * Margin_Rate

Библиотечная функция MaxLotCheck прекрасно работает, когда начальная маржа равна 1. 

А если взять, например, GOLD, то по спецификации начальная маржа там 0.000001 а лот 0.38. Простое перемножение дает 0,00000038.

Нужно умножать начальную маржу на размер контракта. В данном случае он 100. Сумма взята из спецификации символа.

И только после этого мы можем правильно запросить OrderCalcMargin, который честно вернет цену около 3700, которая является 1.0 лотом при покупке.

Препарировал MaxLotCheck, вывалив его в OnTick() и слегка доработав напильником под сложившуюся ситуацию.

   Print(SymbolInfoInteger(_Symbol,SYMBOL_TRADE_CALC_MODE)); // просто для наглядности получим енум чтобы понять по какой формуле идет расчет 

   double percent_temp=100;
   double margin_temp=0.0;

//--- объявим переменные, в которые будут записаны коэффициенты
   double initial_margin_rate = 0;     // коэффициент взимания начальной маржи
   double maintenance_margin_rate = 0; // коэффициент взимания поддерживающей маржи

   if(!SymbolInfoMarginRate(_Symbol, ORDER_TYPE_BUY, initial_margin_rate, maintenance_margin_rate)) {
      Print("SymbolInfoMarginRate() failed. Error ", GetLastError());
   }

   double m_rate = initial_margin_rate * SymbolInfoDouble(_Symbol,SYMBOL_TRADE_CONTRACT_SIZE);

//--- расчет маржи для 1 лота
   if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1/m_rate,m_bid,margin_temp) || margin_temp<0.0) {
      Print("CAccountInfo::MaxLotCheck margin calculation failed");
   }
//---
   if(margin_temp==0.0) // для отложенных ордеров
      Print("res ", SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX));
//--- вычисление максимального объема
   double volume=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*percent_temp/100.0/margin_temp,5);
//--- нормализация и проверка лимитов
   double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
   if(stepvol>0.0)
      volume=stepvol*MathFloor(volume/stepvol);
//---
   double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
   if(volume<minvol)
      volume=0.0;
//---
   double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
   if(volume>maxvol)
      volume=maxvol;

//вот вам и макслот
   Print("vol ", volume);


Возможно, я изобрел велосипед. Подскажите, пожалуйста, готовое решение, если оно есть.

 
Anton #:

Эти сообщения в логах терминала никакого отношения к остановке или запуску чего-либо не имеют, все это просто периодическое журналирование текущего состояния терминала. Т.е. никаких действий в этот момент терминалом не совершается, только вывод в лог информации.

Эксперты на чартах были, да. Вот тут видно: 

Почему они перестали что-то писать в свои логи - это сложно сказать.

Оооооочень долго общался с поддержкой Бинанса. Итог: мои IP не в бане, дело не в них. В сухом остатке сейчас получается, что, с одного и того же сервера:

-- команда curl https://fapi.binance.com/fapi/v1/ticker/bookTicker?symbol=ETHUSDT возвращает успех

-- WebRequest из MT5 https://fapi.binance.com/fapi/v1/ticker/bookTicker?symbol=ETHUSDT вот с таким кодом возвращает 503 Service Temporarily Unavailable (разумеется, все URL в белом списке терминала).

Получается, проблема либо в моем коде, либо в МТ5. Мой код дважды проверяли разные люди в саппорте, сказали все в порядке.

 
Kristian Kafarov #:

возвращает 503 Service Temporarily Unavailable (разумеется, все URL в белом списке терминала).


int OnInit()
  {
//---
   string cookie=NULL, /*headers,*/ resultstr, res_headers;  
   char   post[], result[], post0[];      
   string url="https://fapi.binance.com/fapi/v1/ticker/bookTicker?symbol=ETHUSDT";//+Symbol()
 
   ResetLastError(); 
   int code=WebRequest("GET", url, cookie, NULL, 500, post0, 0, result, res_headers);
        
   if(code==-1)Print("WebRequest error. Error code = "+(string)GetLastError()); 
                              else {
                                   resultstr=CharArrayToString(result);  
                                   Print(resultstr);            
                                   } 
//---
   return(INIT_SUCCEEDED);
  }

2025.09.23 18:33:04.968 test (USDCHF,M5) {"symbol":"ETHUSDT","bidPrice":"4184.71","bidQty":"180.815","askPrice":"4184.72","askQty":"62.373","time":1758641587412,"lastUpdateId":8665646461391}

(это MT5)

 
trader6_1 #:

2025.09.23 18:33:04.968 test (USDCHF,M5) {"symbol":"ETHUSDT","bidPrice":"4184.71","bidQty":"180.815","askPrice":"4184.72","askQty":"62.373","time":1758641587412,"lastUpdateId":8665646461391}

(это MT5)

Спасибо! А с какой машины запускали? У меня дома (Win 10) тоже работает. А сервер (Швейцария, Win Server 2012 R2) нет.