Bibliotecas: MT4Orders - página 61

 
Andrey Khatimlianskii:

¿O basta con comprobar MT4ORDERS::ByPass.Is() antes de las operaciones comerciales (para asegurarse de que no hay desincronización)?

Cada vez que se llama a OrdersTotal, OrdersHistoryTotal y OrderSelect, ByPass.Is()==true está pendiente. Por eso el resultado de estas funciones es relevante JUSTO después de ser llamadas. Pueden cambiar a medida que pasa el tiempo, por lo que es correcto llamarlas de nuevo si hubo alguna pausa. Esta es la respuesta a la pregunta anterior. Es correcto hacer esto no sólo en MT5, sino también en MT4.


Así que si usted acaba de leer el entorno de negociación, usted puede hacer una operación de comercio de inmediato, porque el entorno sigue siendo relevante. Es por eso que fue posible ocultar el mecanismo para el usuario medio de la biblioteca.

 
// Lista de cambios:
// 13.05.2021
// Corrección: Corregido un error en OrderOpenReason().
 
amrali:

Error encontrado:

La función OrderOpenReason() devuelve (ENUM_DEAL_REASON)DEAL_REASON_TP para órdenes cerradas en takeprofit.

Gracias. Corregido.

 

fxsaber:

Sí, lo hará, dando una Alerta. Pero me cuesta imaginar que un segundo no sea suficiente. La resincronización dura milisegundos.
Si eso ocurre, sería recomendable informar de ello aquí.

Si aún así no te fías de que el entorno se sincronice en un segundo, ¿cómo interrumpir correctamente el EA (deshabilitar nuevas órdenes) si no hay sincronización?

if ( MT4ORDERS::ByPass.Is() == false ) // el entorno no está sincronizado, no opere
        return;

OrderSend(...);

?

 
Andrey Khatimlianskii:

Si no nos fiamos de que el entorno se sincronice en un segundo, ¿cómo podemos interrumpir correctamente el EA (prohibir nuevas órdenes) si no hay sincronización?

Aquí es a su discreción. Usted puede hacer como usted ha escrito. O hacer otra Espera. O aumentar la pausa. Yo intentaría esperar al menos una desincronización tan larga.

 
fxsaber:

Depende de tu criterio. Puedes hacer lo que has escrito. O hacer otra Espera. O aumentar la pausa. Yo intentaría esperar al menos una desincronización tan larga.

Gracias.

Intentaré esperar una alerta o una desincronización, eliminaré las otras comprobaciones.

 
// Lista de cambios:
// 14.05.2021
// Corrección: El mecanismo BYPASS ya no afecta a OrderSelect(INT_MAX, SELECT_BY_POS) y OrderSelect(INT_MIN, SELECT_BY_POS).

Importante para quienes utilizan snapshots y otras técnicas de negociación muy específicas.

 

Cansado de sorpresas con los márgenes. Recomiendo ejecutar este tipo de scripts de prueba antes de utilizar Asesores Expertos de combate.

// Compruebe si el cálculo del margen en MT5 es correcto.

#include <MT4Orders.mqh> // https://www.mql5.com/es/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);
    }
}

Vemos una discrepancia total entre las cifras de margen calculadas de MT5 y las reales. En tales circunstancias, tal vez la única manera es evitar los símbolos correspondientes.


ZЫ Y también es fastidioso que retomes cosas elementales e inmediatamente encuentres bugs allí, ¡y no haya ni una palabra al respecto en el foro!

 
fxsaber:
Respeto a la única persona del foro que no se cansa de informar de fallos. La mayoría de la gente abandona después de unos cuantos posts ignorados.
Y aquí casi nadie usa estos símbolos, por eso no se dieron cuenta.
 
En realidad no es un error, es un fallo de diseño. El problema es que el margen se calcula a nivel de las propiedades de la cuenta, mientras que debería ser a nivel de las propiedades del símbolo.