Características del lenguaje mql5, sutilezas y técnicas - página 88

 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Bichos, errores, preguntas

fxsaber, 2016.07.19 12:41

¿Qué sentido tiene tenerENUM_DEAL_PROPERTY_INTEGER::DEAL_TICKET si el único lugar donde se aplica es HistoryDealGetInteger(TicketDeal, DEAL_TICKET)?

Con el ejemplo de ORDER_TICKET la idea debería estar clara.

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

OrderCloseTime () en MQL5?

fxsaber, 2018.07.18 03:51

datetime OrderCloseTime( const ulong Ticket )
{
  return((HistoryOrderGetInteger(Ticket, ORDER_TICKET) == Ticket) || HistoryOrderSelect(Ticket) ? (datetime)HistoryOrderGetInteger(Ticket, ORDER_TIME_DONE) : 0);
}

Así podemos comprobar si la tabla de historial actual, generada previamente mediante las funciones HistorySelect, contiene el registro que necesitamos. Lo mismo ocurre con DEAL_TICKET.

 

Foro sobre trading, sistemas de trading automatizados y pruebas de estrategias de trading

Guardar el nivel de precios de la posición mediante la compensación (¿es posible?)

fxsaber, 2018.07.17 20:45

// Возвращает цену открытия выбранной позиции без учета клиринга
double GetSummaryPositionPrice()
{
  double TotalVolume = 0;
  double TotalDealPrice = 0;
  
  if (HistorySelectByPosition(PositionGetInteger(POSITION_IDENTIFIER)))
  {
    const int DealsTotal = HistoryDealsTotal();
    
    for (int i = 0; i < DealsTotal; i++)
    {
      const ulong DealTicket = HistoryDealGetTicket(i);
      
      if (HistoryDealGetInteger(DealTicket, DEAL_ORDER))
      {
        const double DealVolume = (HistoryDealGetInteger(DealTicket, DEAL_TYPE) ? -1 : 1) * HistoryDealGetDouble(DealTicket, DEAL_VOLUME);
        const double DealPrice = HistoryDealGetDouble(DealTicket, DEAL_PRICE);
  
        if (TotalVolume * DealVolume >= 0)
          TotalDealPrice = (TotalDealPrice * TotalVolume + DealPrice * DealVolume) / (TotalVolume + DealVolume);
        else if (MathAbs(DealVolume) - MathAbs(TotalVolume) > 0.005)
          TotalDealPrice = DealPrice;
          
        TotalVolume += DealVolume;
      }      
    }
  }
  
  return(TotalDealPrice);
}
 

Es posible que no se sepa que la función GetMicrosecondCount, a diferencia de GetTickCount, está vinculada a la hora local del ordenador. Esto significa que si esta hora cambia (por ejemplo, debido a la sincronización con la hora de Internet), los valores de GetMicrosecondCount también cambiarán en un valor correspondiente.Esto debe tenerse en cuenta si esta función se utiliza para medir intervalos de tiempo; de hecho, no debería utilizarse para este propósito. GetTickCount, por otro lado, no tiene estos problemas.

Como demostración, puede ejecutar este código y cambiar la hora del ordenador mientras se está ejecutando.

  datetime time= TimeLocal();
  ulong    microsec= GetMicrosecondCount();
  uint     ticks= GetTickCount();
  
  while(!IsStopped())
  {
    Comment(int(TimeLocal()-time),"   ",(GetMicrosecondCount()-microsec)/1000000,"   ",(GetTickCount()-ticks)/1000);
    Sleep(10);
  }
 
Alexey Navoykov:

Quizás no todo el mundo sepa que la función GetMicrosecondCount, a diferencia de GetTickCount, está ligada a la hora local del ordenador.

No lo sabía, ¡gracias!

 

Una variante de la función GetTickCount que evita los desbordamientos (siempre que el intervalo entre llamadas a la función no supere los 50 días)

ulong GetTickCountLong()
{
  static ulong sum=0;
  static uint  lasttickcount=0;
  uint tickcount= GetTickCount();
  if (tickcount<lasttickcount) sum+=0x100000000;
  lasttickcount= tickcount;
  return sum + tickcount;
}
 
Alexey Navoykov:

Es posible que no se sepa que la función GetMicrosecondCount, a diferencia de GetTickCount, está vinculada a la hora local del ordenador. Esto significa que si esta hora cambia (por ejemplo, debido a la sincronización con la hora de Internet), los valores de GetMicrosecondCount también cambiarán en un valor correspondiente.Esto debe tenerse en cuenta si esta función se utiliza para medir intervalos de tiempo; de hecho, no debería utilizarse para este propósito. GetTickCount, por otro lado, no tiene estos problemas.

Para demostrarlo, puede ejecutar este código y cambiar la hora del ordenador durante la ejecución del código.

Se trata de un error que los desarrolladores deberían solucionar. La función entonces no se ajusta a la descripción:

Функция GetMicrosecondCount() возвращает количество микросекунд, прошедших с момента начала работы MQL5-программы.
El valor de esta función en comparación con GetTickCount es de microsegundos, no de milisegundos (una precisión 1000 veces mayor). Además, no es hinchable.
Por eso no es del todo correcto hablar de su sustituibilidad.
 
Alexey Navoykov:

No todo el mundo sabe que la función GetMicrosecondCount, a diferencia de GetTickCount, está vinculada a la hora local del ordenador. Esto significa que si esta hora cambia (por ejemplo, debido a la sincronización con la hora de Internet), los valores de GetMicrosecondCount también cambiarán en un valor correspondiente.Esto debe tenerse en cuenta si esta función se utiliza para medir intervalos de tiempo; de hecho, no debería utilizarse para este propósito. GetTickCount, por otro lado, no tiene estos problemas.

Para demostrarlo, puedes ejecutar este código y cambiar la hora del ordenador mientras se está ejecutando.

Una observación más importante: de ella se deduce que es absolutamente inapropiado utilizar la función GetTickCount en lugar de GetMicrosecondCount.
Creo que será una sorpresa para mucha gente.

Examinando el funcionamiento de un simple script:

void OnStart()
  {
   uint i=GetTickCount();
   uint i0=GetTickCount();
   while(i==i0) i0=GetTickCount(); 
   
   int N1=1;
   ulong t1=GetMicrosecondCount();
   uint i1=GetTickCount();
   uint i2=GetTickCount();
   while(i1==i2) { i2=GetTickCount(); N1++;}
   t1=GetMicrosecondCount()-t1;
   
   ulong t=GetMicrosecondCount();
   ulong t0=GetMicrosecondCount();
   while(t==t0) t0=GetMicrosecondCount(); 
   int N2=1;
   ulong t2=GetMicrosecondCount();
   ulong t3=GetMicrosecondCount();
   while(t2==t3) { t3=GetMicrosecondCount(); N2++;}
   ulong t4=t3-t2;

   Print("1 значение в милисекундах:  " +(string)i1+", следующее значение   "+ (string)i2 + ", разница - " +(string)t1 + 
   " микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = " +DoubleToString((double)t1*1000.0/N1,3)+ " наносекунды");
   
   Print("1 значение в микросекундах: " +(string)t2+", следующее значение   "+ (string)t3 + ", разница - " +(string)t4 + 
   " микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = " +DoubleToString((double)t4*1000.0/N2,3)+ " наносекунды");
  }

El resultado del trabajo:

2018.07.27 00:23:02.261 TestTimeCount   1 значение в милисекундах:  25225093, следующее значение   25225109, разница - 15663 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.323 наносекунды
2018.07.27 00:23:02.261 TestTimeCount   1 значение в микросекундах: 20247, следующее значение   20248, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 33.333 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в милисекундах:  25226421, следующее значение   25226437, разница - 15586 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.324 наносекунды
2018.07.27 00:23:03.590 TestTimeCount   1 значение в микросекундах: 22835, следующее значение   22836, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 30.303 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в милисекундах:  25227750, следующее значение   25227765, разница - 15657 микросекунд, время выполнения функции GetTickCount (одного прохода цикла) = 2.309 наносекунды
2018.07.27 00:23:04.920 TestTimeCount   1 значение в микросекундах: 23701, следующее значение   23702, разница - 1 микросекунд, время выполнения функции GetMicrosecondCount (одного прохода цикла) = 27.027 наносекунды

podemos sacar las siguientes conclusiones:

  • El valor de la función GetTickCount () no cambia cada milisegundo sino cada 15,625milisegundos(1/64 de segundo, 64=2^6), mientras que el valor de la función GetMicrosecondCount() cambia cada micro segundo. Significa que la función GetMicrosecondCount es 15625 veces más precisa que GetTickCount, no 1000.
  • pero la función GetTickCount() es aproximadamente 12-15 veces más rápida que GetMicrosecondCount().
 
Nikolai Semko:

Pues bien, se trata de un error que los desarrolladores harían bien en solucionar. Porque entonces la función no se corresponde con la descripción:

El valor de esta función en comparación con GetTickCount es de microsegundos, no de milisegundos (1000 veces más preciso). Además, no es hinchable.
Por eso no es del todo correcto hablar de su sustituibilidad.

Si se mide el tiempo de ejecución de algunas secciones del programa, las fluctuaciones del rendimiento del sistema anulan toda esta precisión y se produce un error en milisegundos o incluso en decenas de milisegundos. Si se miden segmentos muy pequeños con una duración inferior a 1 milisegundo, entonces no tiene sentido. La proporción de error de medición será muy alta.

 
Alexey Navoykov:

Todavía no he visto ningún uso práctico de los microsegundos. Si se mide el tiempo de ejecución de algunas secciones del programa, las fluctuaciones del rendimiento del sistema anularán toda esta precisión, y el error será de milisegundos, o incluso de decenas de milisegundos. Si se miden segmentos muy pequeños con una duración inferior a 1 milisegundo, el error de medición será muy elevado.

  1. ver mi post anterior
  2. Tengo muchos ejemplos con el uso práctico de los microsegundos.

 
Nikolai Semko:

Otra observación importante sugiere que es absolutamente inapropiado utilizar la función GetTickCount en lugar de GetMicrosecondCount.
Creo que será una sorpresa para muchos programadores.

Examinando el funcionamiento de un simple script:

se pueden extraer las siguientes conclusiones:

  • El valor de la función GetTickCount ( ) cambia cada 15,6 milisegundos en lugar de cada milisegundo, mientras que el valor de la función GetMicrosecondCount() cambia cada micro segundo. Significa que GetMicrosecondCount es 15600 veces más preciso que GetTickCount, no 1000.
  • pero GetTickCount() es aproximadamente 12-15 veces más rápido que GetMicrosecondCount().

El argumento significativo

Razón de la queja: