Librerías: MT4Orders Informe rápido - página 5

 
Forester #:

Servidor: MetaQuotes-Demo Hedge
Trate el ticket 99 en la página dos.

Un poco localizado.

#include <MT4Orders.mqh>

void OnTick ()
{
  static int Count = 0;
  
  if (Count > 6)
    return;
  
  MqlTick Tick;
  SymbolInfoTick(_Symbol, Tick);
  
  const double Offset = 5 * _Point;
  bool Buy =  false;
  bool Sell =  false;

  for (uint i = OrdersTotal(); (bool)i--;)
    if (OrderSelect(i, SELECT_BY_POS))         
    {
      if(OrderMagicNumber())
        switch (OrderType())
        {
        case OP_BUY:
          OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.bid + Offset, 0);
          Buy = true;
         
         break;
        case OP_SELL:
          OrderModify(OrderTicket(), OrderOpenPrice(), 0, Tick.ask - Offset, 0);
          Sell = true;
         
         break;
        case OP_BUYLIMIT:
          OrderModify(OrderTicket(), Tick.ask - Offset, 0, 0, 0);
          Buy = true;
         
         break;
        case OP_SELLLIMIT:          
          OrderModify(OrderTicket(), Tick.bid + Offset, 0, 0, 0);
          Sell = true;
         
         break;
        }
      else
        OrderDelete(OrderTicket());
    }

  if (!Buy)
    OrderSend(_Symbol, OP_BUYLIMIT, 1, Tick.ask - Offset, 0, 0, 0, NULL, ++Count);

  if (!Sell)
    OrderSend(_Symbol, OP_SELLLIMIT, 1, Tick.bid + Offset, 0, 0, 0, NULL, ++Count);
  
  OrderSend(_Symbol, OP_BUYLIMIT, 1,  Tick.ask - Offset, 0, Tick.ask - Offset, Tick.ask - Offset);
  Count++;
}

string TimeToString( const long Time )
{
  return((string)(datetime)(Time / 1000) + "." + IntegerToString(Time % 1000, 3, '0'));
}

void OnDeinit( const int )
{
  if (HistorySelect(0, INT_MAX))
    for (uint i = HistoryOrdersTotal(); (bool)i--;)
    {
      const ulong Ticket = HistoryOrderGetTicket(i);
      
      Print((string)i + ": " + (string)Ticket + " " + TimeToString(HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE_MSC)));
    }
}


No importa lo que esté haciendo el EA. Lo principal es el código resaltado, que simplemente muestra las órdenes MT5 del historial de operaciones: el lugar de la orden, su ticket y la hora a la que entró en el historial.

11: 13 2023.05.29 23:54:39.425
10: 12 2023.05.29 00:04:25.870
 9: 11 2023.05.29 00:03:59.331
 8: 10 2023.05.29 00:03:59.430
 7: 9 2023.05.29 00:03:59.281
 6: 8 2023.05.29 00:03:59.281
 5: 7 2023.05.29 00:03:59.227
 4: 3 2023.05.29 00:03:59.331
 3: 6 2023.05.29 00:03:18.390
 2: 5 2023.05.29 00:03:18.390
 1: 4 2023.05.29 00:02:41.107
 0: 2 2023.05.29 00:02:41.107

En la tabla del histórico, las órdenes MT5 no están ordenadas por ticket ni por hora. No veo el sentido de reportar este comportamiento de MQ-Tester a los desarrolladores. Al fin y al cabo, "las tareas están de más".

Por lo tanto, yo no normalizaría MQ-Tester.

 
fxsaber #:

Un poco localizado.


No importa lo que haga el EA. Lo principal es un código dedicado que simplemente salidas MT5 órdenes del historial de operaciones: el lugar de la orden, su billete y el tiempo que se metió en la historia.

En la tabla del historial, las órdenes MT5 no están ordenadas por ticket ni por hora. No veo el sentido de reportar este comportamiento de MQ-Tester a los desarrolladores. Al fin y al cabo, "las tareas están de más".

Por lo tanto, yo no normalizaría MQ-Tester.

Creo que las órdenes limitadas tienen su propia cola de transferencia al historial cuando se cierran. No en cada tick.
Si no necesitan arreglar errores obvios con las primeras operaciones de prueba y swaps (que desconté hace un par de semanas), entonces es sólo una característica. Matriz de confusión es más importante....
 
A veces es bueno saberlo.
// Duración máxima de la reducción a partir de la hora fijada.
int MaxLengthDD( datetime &BeginDD, datetime &EndDD, const datetime From = 0 )
{
  const int Total = OrdersHistoryTotal();
  
  double Profit = 0;
  double MaxProfit = 0;
  datetime Begin = 0;
  
  BeginDD = 0;
  EndDD = 0;
  
  for (int i = 0; i < Total; i++)
    if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) && (OrderType() <= OP_SELL))
    {
      if (!Begin && (OrderOpenTime() > From))
        Begin = OrderOpenTime();
        
      Profit += OrderProfit() + OrderSwap() + OrderCommission();
      
      if ((Profit > MaxProfit) || (i == Total - 1))
      {
        MaxProfit = Profit;
        
        const datetime End = OrderCloseTime();        
        
        if (Begin && (End - Begin > EndDD - BeginDD))
        {
          BeginDD = Begin;
          EndDD = End;
        }
        
        if (Begin)
          Begin = End;
      }
    }
    
  return((int)(EndDD - BeginDD));
}

void PrintMaxLengthDD( const datetime &From[] )
{
  const int Size = ArraySize(From);
  
  datetime BeginDD, EndDD;
  
  for (int i = 0; i < Size; i++)
    Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);  
}
 

fxsaber #:
Иногда полезно знать.

Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);

Es mejor no escribir tan empaquetado y frívolo (no sólo aquí, sino también en otras fuentes). El orden de los cálculos de operandos con la misma prioridad no se establece rígidamente - el compilador puede optimizarlo basándose en sus propias consideraciones, entonces puedes obtener diferentes efectos secundarios. Si funciona ahora, no significa que no vaya a dejar de funcionar más adelante, porque la implementación interna del compilador cambia todo el tiempo.

 
Stanislav Korotky #:

Es mejor no escribir tan empaquetado y frívolo (no sólo aquí, sino también en otras fuentes). El orden de los cálculos de operandos con la misma prioridad no se establece rígidamente - el compilador puede optimizarlo basándose en sus propias consideraciones, entonces puedes obtener diferentes efectos secundarios. Si funciona ahora, no significa que no vaya a dejar de funcionar más adelante, porque la implementación interna del compilador cambia todo el tiempo.

Gracias por el buen consejo. Por desgracia, es difícil obligarme a abandonar el estilo "conciso" en favor del correcto. Hay mucho código "incorrecto" escrito y utilizado.

 
fxsaber #:
// Duración máxima de la detracción a partir de un momento dado.
¿Desde la fecha de inicio a plazo?
Stanislav Korotky #:

Es mejor no escribir de forma tan empaquetada y frívola (no sólo aquí, sino también en otras fuentes). El orden de los cálculos de los operandos con la misma prioridad no se establece rígidamente - el compilador puede optimizarlo basándose en sus propias consideraciones, entonces puedes obtener diferentes efectos secundarios. Si funciona ahora, no significa que no vaya a dejar de funcionar más adelante, porque la implementación interna del compilador cambia todo el tiempo.

¿Qué tiene de malo?

Yo solo

/ (25 * 3600)
no me gusta. Hay 24 horas en un día, no 25.
 

Forester #:
C даты начала форварда?

Cualquiera.

¿Qué es lo que falla?

No hay un orden unívoco en el que se formará la cadena para Imprimir. Si de derecha a izquierda, el resultado será diferente de la prevista.

    Print("From " + TimeToString(From[i], TIME_DATE) + " MaxLengthDD = " + (string)(MaxLengthDD(BeginDD, EndDD, From[i]) / (25 * 3600)) + " days: " +
          (string)BeginDD + " - " + (string)EndDD);  


Me gustaría que no hubiera ambigüedad en tal caso.

int MaxLengthDD( const datetime &BeginDD, const datetime &EndDD, const datetime From = 0 )
 
fxsaber #:

Gracias por los buenos consejos. Por desgracia, es difícil obligarme a abandonar el estilo "conciso" en favor del correcto. Hay mucho código "incorrecto" escrito y utilizado.

Casi siempre colapso las funciones y otro código en una sola línea si el código está trabajado/probado y no pienso volver a él. Sólo para ahorrar espacio.
Y es más conveniente leer el código sin desplazarse hacia atrás y adelante cuando se puede ver todo en una sola pantalla. Especialmente en editores que resaltan la palabra resaltada (desafortunadamente Metaeditor no es uno de ellos).
 
Forester #:
Yo casi siempre colapso funciones y otro código en una línea si el código está trabajado/probado y no planeo volver a él. Sólo para ahorrar espacio.
Y es más cómodo leer el código sin desplazarse hacia adelante y hacia atrás cuando se puede ver todo en una sola pantalla. Especialmente en editores que resaltan la palabra resaltada (desafortunadamente Metaeditor no es uno de ellos).

Desafortunadamente, esta práctica puede llevar a errores muy difíciles de ver cuando cambias de compilador.

Sin embargo, hay situaciones en las que sólo necesitas usar el orden establecido en el compilador. Y ahí no sé cómo evitarlo para que no haya UB.

 
fxsaber #:

De cualquiera.

La información sobre la reducción máxima de largo es interesante. Lo hice para todo el array de cadenas. Todavía no he actualizado el código en el sitio.
Pero no está muy claro para qué sirve la fecha. Si hacemos un punto de división en back / forward pruebas (como he sugerido), entonces tenemos que calcular las estadísticas sobre ellos por separado en 2 tablas (períodos max drawdown estará allí también).
Y sólo para una fecha es de alguna manera demasiado específica e incomprensible.