Библиотеки: MT4Orders - страница 59

 
Andrey Khatimlianskii:

Что произойдет по истечении этой секунды? Продолжится работа в условиях отсутствия синхронизации?

Да, продолжит, выдав Алерт. Но я с трудом представляю, чтобы секунды не хватило. Рассинхрон длится миллисекунды.

Если такое произойдет, желательно здесь отписаться.

Это нужно прописывать в боевых роботах?

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

 
Andrey Khatimlianskii:

Или достаточно проверять MT4ORDERS::ByPass.Is() перед торговыми операциями (чтобы убедиться в отсутствии рассинхрона)?

Каждый раз при вызове OrdersTotal, OrdersHistoryTotal и OrderSelect идет ожидание ByPass.Is()==true. Поэтому результат этих функций актуален СРАЗУ после их вызова. По прошествии времени они могут измениться, поэтому правильно их вызывать снова, если была какая-либо пауза. В этом и состоит ответ на заданный выше вопрос. Это правильно делать не только в MT5, но и в MT4.


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

 
// Список изменений:
// 13.05.2021
//   Fix: Исправлена ошибка в OrderOpenReason().
 

fxsaber:

Да, продолжит, выдав Алерт. Но я с трудом представляю, чтобы секунды не хватило. Рассинхрон длится миллисекунды.
Если такое произойдет, желательно здесь отписаться.

Если все-таки не полагаться на то, что за секунду окружение синхронизировалось, как правильно прервать работу советника (запретить новые ордера) при отсутствии синхронизации?

if ( MT4ORDERS::ByPass.Is() == false ) // окружение не синхронизировано, не торгуем
        return;

OrderSend(...);

?

 
Andrey Khatimlianskii:

Если все-таки не полагаться на то, что за секунду окружение синхронизировалось, как правильно прервать работу советника (запретить новые ордера) при отсутствии синхронизации?

Здесь уже на свое усмотрение. Можете, как написали. Или сделать очередной Waiting. Или паузу увеличить. Я бы попытался дождаться хоть одного такого длительного рассинхрона.

 
fxsaber:

Здесь уже на свое усмотрение. Можете, как написали. Или сделать очередной Waiting. Или паузу увеличить. Я бы попытался дождаться хоть одного такого длительного рассинхрона.

Спасибо!

Попробую подождать алерта или задвоения, другие проверки уберу.

 
// Список изменений:
// 14.05.2021
//   Fix: BYPASS-механизм больше не влияет на OrderSelect(INT_MAX, SELECT_BY_POS) и OrderSelect(INT_MIN, SELECT_BY_POS).

Важно для тех, кто использует снепшоты и другие очень специфические техники торговли.

 

Утомили сюрпризы с маржой. Рекомендую запускать подобные проверочные скрипты перед тем, как использовать боевые советники.

// Проверка корректности расчета маржи в MT5.

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

bool EqualDouble( const double Value1, const double Value2, const double Epsilon = 0.01 )
{
  return(Value1 && Value2 && (MathMax(Value1, Value2) / MathMin(Value1, Value2) < 1 + Epsilon));
}

#define TOSTRING(A) #A + " = " + (string)(A) + " "

bool CheckMargin( const string Symb )
{
  const double RealMargin = AccountInfoDouble(ACCOUNT_MARGIN);
//  const double CalcMargin = GetMarginRequired(Symb); // https://www.mql5.com/ru/forum/170952/page9#comment_4134898
  
  double CalcMargin = 0;
  OrderCalcMargin(ORDER_TYPE_BUY, Symb, 1, SymbolInfoDouble(Symb, SYMBOL_ASK), CalcMargin);
  
  const bool Res = EqualDouble(RealMargin, CalcMargin);
  
  const string Str = TOSTRING(Symb) + TOSTRING(RealMargin) + TOSTRING(CalcMargin) + "- " + (string)Res;
  
  if (Res)
    Print(Str);
  else
    Alert(Str);
      
  return(Res);
}

bool CheckCalcMargin( const string Symb )
{
  bool Res = !OrdersTotal();
  
  if (Res)
  {
    const TICKET_TYPE Ticket = OrderSend(Symb, OP_BUY, 1, SymbolInfoDouble(Symb, SYMBOL_ASK), 0, 0, 0);
    
    if (Res = (Ticket != -1))
    {
      Res = CheckMargin(Symb);
      
      if (OrderSelect(Ticket, SELECT_BY_TICKET))
        OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 0);
    }
  }
  else
  {
    Alert("ERROR: OrdersTotal() != 0");
    
    ExpertRemove();
  }
  
  return(Res);
}

void OnStart()
{
  if (AccountInfoInteger(ACCOUNT_TRADE_MODE) != ACCOUNT_TRADE_MODE_DEMO)
    Alert("Demo account is required!");
  else  
    for (int i = SymbolsTotal(true) - 1; !IsStopped() && (i >= 0); i--)
    {
      const string Symb = SymbolName(i, true);
      
      if (!SymbolInfoInteger(Symb, SYMBOL_CUSTOM))
        CheckCalcMargin(Symb);
    }
}

Видим полное несоответствие расчетных показателей маржи MT5 и реальных. При таких раскладах, наверное, пока единственный способ - обходить соответствующие символы стороной.


ЗЫ А еще утомляет, что берешься за элементарные вещи, сразу находишь там баги, а на форуме об этом ни слова!

 
fxsaber:
Уважение единственному человеку на форуме, не устающему сообщать о багах. Большинство бросает после нескольких проигнорированных сообщений.
А символами этими вряд ли кто здесь пользуется, вот и не замечали.
 
На самом деле это не ошибка, это ошибочный дизайн. Проблема в том, что маржа рассчитывается на уровне свойств аккаунта, тогда как она должна быть на уровне свойств символа.
Причина обращения: