Bibliotecas: TypeToBytes

 

TypeToBytes:

Operación byte a byte con estructuras y tipos estándar de datos

Autor: fxsaber

 
Un breve ejemplo de cómo utilizar la biblioteca

Foro sobre negociación, sistemas automatizados de negociación y prueba de estrategias de negociación

Dos BookEvent vecinos pueden duplicar una pila

fxsaber, 2016.09.14 16:29

EA muestra cuando dos pilas vecinas son copias la una de la otra

#include <TypeToBytes.mqh> // https://www.mql5.com/es/code/16280

template <typename T>
bool ArrayEqual( const T &Array1[], const T &Array2[] )
{
  const int Amount = ArraySize(Array1);
  bool Res = (Amount == ArraySize(Array2));

  if (Res)
    for (int i = 0; i < Amount; i++)
      if (_R(Array1[i]) != Array2[i]) // https://www.mql5.com/es/code/16280
      {
        Res = false;

        break;
      }

  return(Res);
}

template <typename T>
bool ArrayClone( const T &Source[], T &Target[] )
{
  ArrayFree(Target);

  return(ArrayCopy(Target, Source) >= 0);
}

void OnInit( void )
{
  MarketBookAdd(_Symbol);
}

void OnDeinit( const int Reason )
{
  MarketBookRelease(_Symbol);
}

void OnBookEvent( const string &symbol )
{
  static MqlBookInfo PrevBook[];
  MqlBookInfo Book[];

  if ((symbol == _Symbol) && MarketBookGet(symbol, Book))
  {
    if (ArrayEqual(Book, PrevBook))
    {
      if (ArraySize(PrevBook) > 0)
        Alert("Book == PrevBook");
    }
    else
      ArrayClone(Book, PrevBook);
  }
}

Resultado

2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:30.896 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:29.406 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:23.151 Test2 (Si-9.16,M1)      Book == PrevBook
2016.09.14 17:24:23.151 Test2 (Si-9.16,M1)      Book == PrevBook
Puede haber muchos motivos para estas situaciones: desde que MT5 se salte algunas stakes, hasta que la propia bolsa genere stakes dobles.

 
Otro ejemplo

Foro sobre negociación, sistemas automatizados de negociación y prueba de estrategias de negociación

Probando 'CopyTicks'

fxsaber, 2016.09.15 10:07 AM

Cómo otros usan CopyTicks no lo entiendo. No hay confianza, por desgracia. Muy crudo.

Asesor

#include <TypeToBytes.mqh> // https://www.mql5.com/es/code/16280

void OnTick( void )
{
  static MqlTick PrevTick;  
  static int Amount = 0;
  
  MqlTick Ticks[];
  
  if (Amount > 0)
  {
    Amount = CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, PrevTick.time_msc);
    
    int i;
    
    for (i = 0; i < Amount; i++)
      if (_R(Ticks[i]) == PrevTick) // https://www.mql5.com/es/code/16280
        break;
        
    if (i == Amount)
      Print("En la historia (longitud = " + (string)Amount + ") no hay ninguna marca que estuviera en el Evento anterior".);
  }
  else
    Amount = CopyTicks(_Symbol, Ticks, COPY_TICKS_ALL, TimeCurrent() * 1000);
    
  if (Amount > 0)
    PrevTick = Ticks[Amount - 1];  
}

Resultado

2016.09.15 11:04:02.810 Test2 (RTS-9.16,M1)     В истории (length = 2) нет тика, что был на предыдущем Event.
2016.09.15 11:03:59.312 Test2 (RTS-9.16,M1)     В истории (length = 13) нет тика, что был на предыдущем Event.
2016.09.15 11:03:59.290 Test2 (RTS-9.16,M1)     В истории (length = 1) нет тика, что был на предыдущем Event.

¡Un Tick que estaba en la historia ya no está en la historia en el próximo evento Tick!

Queridos desarrolladores, hagan que CopyTicks funcione. Incluso las pruebas simples fallan.


 
He encontrado una laguna que me permite sustituir esas engorrosas entradas
_W(Tick, Offset, (double)1.23456);     // Escribe el valor (double)1.23456 en el offset encontrado
_W(CloneTick, 0, Tick);                // Escribe en CloneTick en el offset cero el valor del objeto estructural Tick
_W(Color, 2, (uchar)230);              // Escribe el valor (uchar)230 en el offset 2.
en lugar de tan voluminosos registros.
_W(Tick)[Offset] = 1.23456;             // Escribe el valor (double)1.23456 en el offset encontrado
_W(CloneTick)[0] = Tick;                // Escribe en CloneTick en el offset cero el valor del objeto estructural Tick
_W(Color)[2] = (uchar)230;              // Escribe el valor (uchar)230 en el offset 2.

Es decir, existe una posibilidad real de trabajar con tipos estándar y estructuras simples como con un array, no sólo en modo lectura, ¡sino también en modo escritura!
 
fxsaber:
He encontrado un resquicio legal que me permite sustituir esas engorrosas entradas
para hacer las habituales

Es decir, existe la posibilidad real de trabajar con tipos estándar y estructuras simples como con un array, no sólo en modo lectura, ¡sino también en modo escritura!

Publicado. Ahora para cualquier variable (estructura o tipo estándar) funciona no sólo la lectura, como con una matriz, sino también ESCRIBIR:

_W(AnyVariable)[Pos] = AnyValue; // Escribe el valor AnyValue en el byte Pos en la variable AnyVariable

No era fácil de adivinar antes de la implementación - Supongo que resultó ser una buena prueba para el dominio medio de la programación orientada a objetos: sólo conozco los clásicos para las clases.

Si alguien sabe algo similar, por favor, comparta un enlace para la educación.

 
Ejemplo de visualización del contenido en bytes de una variable
#include <TypeToBytes.mqh>

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

string BytesToString( const uchar &Bytes[] )
{  
  string Str = "";

  const int Amount = ArraySize(Bytes);
  
  for (int i = 0; i < Amount; i++)
    Str += TOSTRING(i) + "," + TOSTRING(Bytes[i]) + "\n";
    
  return(Str);
}

#define  VALUETOSTRING(A) typename(A) + TOSTRING(A) + ":\n" + BytesToString(_R(A).Bytes)

void OnStart()
{
  int Tmp = 1;  
  Print(VALUETOSTRING(Tmp));
  
  Tmp = -1;
  Print(VALUETOSTRING(Tmp));
}
Resultado
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 3, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 2, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 1, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 0, Bytes[i] = 255
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     int Tmp = -1:
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 3, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 2, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 1, Bytes[i] = 0
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)      i = 0, Bytes[i] = 1
2016.10.02 20:26:52.383 Test (RTS-12.16,M1)     int Tmp = 1:
 
Doble comparación concisa no numérica

Foro sobre negociación, sistemas automatizados de negociación y prueba de estrategias de negociación

¿Cómo comparar rápidamente el doble y el QNaN?

fxsaber, 2016.10.11.11:14 pm.

¡Que guay, no lo sabía! Pues entonces de esta manera
#include <TypeToBytes.mqh>

double Nan(long bit_value)
  {
   struct L { long   x; } l; l.x=bit_value;
   struct D { double x; } d=(D)l;
   return(d.x);
  }

double QNaN   =Nan(0x7FF7000000000000);  

void OnStart()
{
   if (_R(QNaN)==QNaN) {
      Alert("QNaN is QNaN");
   } else {
      Alert("Ooops");
   }   
}

 
Ejemplo de creación de un doble no numérico
#include <TypeToBytes.mqh>

void OnStart()
{
  double QNaN = 0;
  
  _W(QNaN) = 0x7FF7000000000000;
  
  Print(QNaN);
}

 
Ejemplo de una nueva característica no toca directamente la biblioteca, pero indirectamente - sobre el tema de las estructuras

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

MetaEditor construir 1463

fxsaber, 2016.11.10:42 AM

class PRINTCLASS
{
public:  
  template <typename T>
  static void MyPrint( const T &Value )
  {
    T Array[1];
    
    Array[0] = Value;
    
    ::ArrayPrint(Array);
  }
  
  template <typename T>
  static void MyPrint( const T Value )
  {
    ::Print(Value);
  }
};

#define Print(A) PRINTCLASS::MyPrint(A)

void OnStart()
{
  MqlTick Tick;
  
  SymbolInfoTick(_Symbol, Tick);

  Print(Tick);
  
  int i = 5;
  
  Print(i);
}
Imprimir ahora también puede imprimir estructuras simples.
 
fxsaber:
Ejemplo de creación de un doble no numérico
#include <TypeToBytes.mqh>

void OnStart()
{
  double QNaN = 0;
  
  _W(QNaN) = 0x7FF7000000000000;
  
  Print(QNaN);
}

Ahora podemos hacerlo de otra forma

#include <TypeToBytes.mqh>

void OnStart()
{
  double Number = (double)"01.23_example";
  double Nan = (double)"nan";
  
  Print(Number);
  Print(Nan);
  
  ArrayPrint(_R(Nan).Bytes); // Imprimir bytes
  
  ulong Num = 0;
  
  _W(Num) = Nan; // Copia byte a byte de Nan a Num
    
  PrintFormat("%I64X", Num);
}

resultado

1.23
nan
255 255 255 255 255 255 255 127
7 F FFFFFFFFFFFFFF
 
fxsaber:

Ahora podemos hacerlo de otra manera

#include <TypeToBytes.mqh>

void OnStart()
{
  double Number = (double)"01.23_example";
  double Nan = (double)"nan";
  
  Print(Number);
  Print(Nan);
  
  ArrayPrint(_R(Nan).Bytes); // Imprimir bytes
  
  ulong Num = 0;
  
  _W(Num) = Nan; // Copia byte a byte de Nan a Num
    
  PrintFormat("%I64X", Num);
}

Resultado

1.23
nan
255 255 255 255 255 255 255 127
7 F FFFFFFFFFFFFFF
¿Ha actualizado el código fuente en la publicación?