English Русский 中文 Deutsch 日本語 Português
preview
Implementación del algoritmo criptográfico SHA-256 desde cero en MQL5

Implementación del algoritmo criptográfico SHA-256 desde cero en MQL5

MetaTrader 5Ejemplos |
252 6
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir

Los avances en MQL5 permiten una implementación eficiente de algoritmos criptográficos sin soluciones de terceros, lo que mejora la seguridad, la optimización y la estabilidad. Las ventajas de la implementación personalizada incluyen ajustes específicos para cada tarea, eliminación de vulnerabilidades y rendimiento uniforme en todos los entornos. La criptografía es ahora una parte integral de las API, la verificación de transacciones y la integridad de los datos, lo que exige a los desarrolladores un profundo conocimiento de estos algoritmos. La convergencia de la criptografía y los sistemas de negociación se ha convertido en un aspecto obligatorio del desarrollo de plataformas modernas.


Desafíos de compatibilidad de firmas API

El principal motivo para la implementación personalizada de SHA-256 radica en la incompatibilidad fundamental entre las funciones hash nativas de MQL5 y los requisitos de intercambio de criptomonedas. Esta incompatibilidad se manifiesta de varias formas críticas que afectan directamente a las operaciones comerciales.

Cuando las plataformas de negociación realizan llamadas API a exchanges de criptomonedas como Binance o Bybit, deben generar firmas criptográficas que coincidan perfectamente con las expectativas del exchange. Estas firmas sirven como prueba de autenticidad para cada solicitud, garantizando que los pedidos y otras operaciones confidenciales provienen de fuentes autorizadas. Sin embargo, las funciones criptográficas integradas en MQL5 suelen generar firmas que difieren de las producidas por las implementaciones estándar en otros lenguajes de programación.

Esta discrepancia en las firmas se produce porque las plataformas de intercambio de criptomonedas suelen esperar firmas generadas según estándares específicos, a menudo basados en implementaciones en lenguajes como Python o JavaScript. Las funciones nativas de MQL5, aunque son funcionales para fines generales, pueden manejar ciertos aspectos del proceso de hash de manera diferente, tales como:

  1. Ordenación de bytes en el procesamiento de entrada.
  2. Implementaciones de relleno.
  3. Gestión de la codificación de caracteres.
  4. Representación en memoria de valores intermedios.
  5. Manejo de caracteres especiales en la cadena de entrada.

Estas diferencias provocan varios problemas operativos graves en los entornos de producción:

En primer lugar, las solicitudes API son rechazadas por las bolsas porque las firmas no coinciden con los valores esperados. Este rechazo se produce en la capa de autenticación, antes incluso de que comience a ejecutarse la lógica comercial propiamente dicha. Consideremos un escenario en el que un algoritmo de negociación identifica una oportunidad rentable e intenta realizar una orden. Si la firma no es válida, la bolsa rechaza inmediatamente la solicitud, lo que hace que el sistema pierda por completo la oportunidad de negociación.

En segundo lugar, los fallos de autenticación se producen de forma sistemática en diferentes tipos de llamadas a la API. Incluso operaciones sencillas como consultar el saldo de una cuenta o comprobar el estado de un pedido se vuelven imposibles porque la plataforma no puede verificar la autenticidad de la solicitud. Esto crea un problema sistémico que afecta a todos los aspectos del funcionamiento del sistema de negociación.

En tercer lugar, la realización de pedidos se vuelve especialmente problemática. Al intentar realizar órdenes, las firmas no válidas impiden la ejecución de las operaciones, lo que puede dar lugar a:

  • Puntos de entrada perdidos para operaciones planificadas.
  • Incapacidad para salir de las posiciones cuando es necesario.
  • Operaciones fallidas de gestión de riesgos.
  • Ejecución incompleta de estrategias comerciales.

En cuarto lugar, la verificación de mensajes deja de ser fiable. Muchas plataformas de intercambio utilizan la verificación basada en hash para diversos tipos de mensajes y notificaciones. Las salidas hash inconsistentes significan que el sistema de intercambio no puede verificar estos mensajes de forma fiable, lo que puede provocar que se pierdan actualizaciones importantes o que se actúe basándose en información no verificada.

El impacto de estos problemas de compatibilidad va más allá de los problemas técnicos inmediatos. Afectan a toda la operación comercial de manera sutil pero significativa:

  • Las estrategias de negociación no pueden ejecutarse de forma fiable.
  • Los sistemas de gestión de riesgos pueden no funcionar según lo previsto.
  • La monitorización y el registro del sistema se vuelven menos fiables.
  • La integración con las API de intercambio requiere soluciones alternativas constantes.

Por ejemplo, consideremos una llamada API típica a un intercambio de criptomonedas. Los mismos datos de entrada podrían producir firmas completamente diferentes:

Usando la función incorporada de MQL5:

void OnStart()
{
   // The text to hash
   string text = "Hello";
   string key_text = "key";   
   
   // Method 1: Using HashCalculate() - Returns uchar array
   uchar data[];
   uchar key[];
   uchar result[];
   StringToCharArray(text, data);
   StringToCharArray(key_text, key);
  
  int res =  CryptEncode(CRYPT_HASH_SHA256, data, key, result);
  
  Print(ArrayToHex(result));
}

/*Result
 D9D3734CD05564A131946ECF9E240E0319CA2F5BA321BD9F87D634A24A29EF4D
*/

Usando la implementación estándar:


import hashlib
import hmac

text = "Hello" #message
key = "key"  #password

hash_object = hmac.new(bytes(key, 'utf-8'), text.encode('utf-8'), hashlib.sha256)
hex_dig = hash_object.hexdigest()

hex_dig

##output >>> "c70b9f4d665bd62974afc83582de810e72a41a58db82c538a9d734c9266d321e"

Las discrepancias en la generación de firmas pueden provocar que señales y estrategias comerciales válidas fallen. Las diferentes bolsas pueden tener requisitos de firma únicos, lo que requiere una implementación flexible y personalizable.

Las implementaciones personalizadas de SHA-256 proporcionan a los desarrolladores control para:

Cumplir con los requisitos específicos del intercambio.
Adaptarse a los estándares en constante evolución.
Depurar problemas relacionados con las firmas.
Garantizar la coherencia en todo el sistema de negociación.

Este control es crucial para el trading de alta frecuencia y las estrategias complejas, donde la fiabilidad y la velocidad son fundamentales. Aunque suponen un reto, las implementaciones personalizadas mejoran la fiabilidad y la integración en los sistemas de negociación de producción.

Diferencia en la implementación de HMAC y SHA-256

  • Python utiliza la biblioteca hmac, que realiza HMAC (Hash-based Message Authentication Code). No se trata solo de hacer un hash del texto con la clave, sino de un proceso combinado:
    1. La llave se complementa (o se corta) al tamaño requerido.
    2. Se realizan dos pasos de hashing: primero con la clave y el mensaje, luego con la clave y el resultado intermedio.
  • MQL5 en este código solo realiza el cálculo SHA-256 a través de CryptEncode() sin implementación completa de HMAC. Este es un hash de texto normal con una clave, no HMAC.

Conclusión : Python utiliza HMAC, mientras que MQL5 solo utiliza SHA-256, lo que ya garantiza resultados diferentes.


Optimización del rendimiento: un análisis en profundidad

Al implementar SHA-256 en un entorno comercial, la optimización del rendimiento se vuelve crucial, ya que cada milisegundo puede afectar los resultados comerciales. Una implementación personalizada ofrece varias vías de optimización que no serían posibles con las funciones integradas.

Los sistemas de comercio a menudo exhiben patrones específicos en sus operaciones criptográficas.m Por ejemplo, las firmas de pedidos suelen contener componentes similares, como marcas de tiempo, símbolos y cantidades. Al comprender estos patrones, podemos optimizar nuestra implementación de SHA-256 específicamente para estructuras de datos relacionadas con el comercio.

Considere cómo funciona la colocación de órdenes en un escenario comercial típico. Cada orden requiere varios datos: el par comercial, el tipo de orden, la cantidad, el precio y la marca de tiempo. En implementaciones estándar, estos datos se procesarían como una entrada completamente nueva cada vez. Sin embargo, podemos optimizar este proceso reconociendo que muchos componentes permanecen constantes o siguen patrones predecibles.

Examinemos cómo funciona esta optimización en la práctica. Al generar firmas para pedidos, gran parte de la estructura de datos permanece consistente:

baseEndpoint/symbol=BTCUSDT&side=BUY&type=LIMIT&quantity=0.1&price=50000&timestamp=1234567890

En esta cadena, normalmente solo cambian unos pocos elementos entre pedidos: la cantidad, el precio y la marca de tiempo. Al estructurar nuestra implementación para manejar eficientemente estos cambios parciales, podemos mejorar significativamente el rendimiento. Esto podría implicar:

  • Creación de funciones de preprocesamiento especializadas que manejan eficientemente estructuras de datos comerciales comunes.
  • Implementación de una gestión de buffer inteligente para componentes de uso frecuente.
  • Desarrollo de rutinas de análisis optimizadas para valores numéricos que aparecen comúnmente en operaciones comerciales.

La gestión de la memoria se vuelve especialmente importante en el entorno MQL5, que tiene sus propias restricciones y características específicas. La plataforma MetaTrader opera con recursos limitados y el uso ineficiente de la memoria puede afectar el rendimiento de todo el sistema comercial. Una implementación personalizada nos permite ajustar la asignación y desasignación de memoria en función de las necesidades exactas de nuestras operaciones comerciales.

Podemos implementar estrategias de almacenamiento en caché sofisticadas que reconozcan la localidad temporal de las operaciones comerciales. Por ejemplo, durante las sesiones de trading de alta frecuencia, ciertos pares de trading o tipos de órdenes podrían usarse repetidamente. Al almacenar en caché los estados hash intermedios para estos patrones comunes, podemos reducir la sobrecarga computacional para operaciones posteriores.


Preparación para el futuro: garantizar la viabilidad a largo plazo

El panorama de las criptomonedas es notablemente dinámico y los intercambios actualizan frecuentemente sus requisitos y protocolos de seguridad. Una implementación SHA-256 personalizada proporciona la flexibilidad necesaria para adaptarse a estos cambios manteniendo la confiabilidad del sistema.

Considere cómo los exchanges podrían modificar sus requisitos de firma a lo largo del tiempo. Podrían:

  • Cambiar el orden de los parámetros en la cadena de firma.
  • Añadir nuevos campos obligatorios a la firma.
  • Modificar cómo se manejan ciertos caracteres o casos especiales.
  • Implementar nuevas medidas de seguridad que afecten la forma en que se generan las firmas.

Con una implementación personalizada, adaptarse a estos cambios se vuelve sencillo. Mantenemos un control total sobre cada aspecto del proceso de hash, desde el preprocesamiento inicial de datos hasta el formateo de la salida final. Este control nos permite responder rápidamente a nuevos requisitos sin esperar actualizaciones de las funciones integradas de MQL5.

Por ejemplo, si un exchange decide modificar la forma en que maneja los caracteres Unicode en las firmas, podemos actualizar inmediatamente nuestra implementación para que coincida con los nuevos requisitos. Este nivel de adaptabilidad se vuelve crucial cuando se trata de múltiples intercambios, cada uno de los cuales potencialmente tiene requisitos diferentes.

La independencia de las funciones integradas de MQL5 proporciona otra ventaja significativa. A medida que MetaTrader evoluciona y actualiza su plataforma, las funciones integradas pueden cambiar de manera sutil que podría afectar la generación de firmas. Una implementación personalizada permanece estable en diferentes versiones de MetaTrader, lo que garantiza un comportamiento consistente independientemente de las actualizaciones de la plataforma.

El aspecto de preparación para el futuro se extiende más allá de los requisitos de firma. Los intercambios de criptomonedas podrían introducir nuevas características de seguridad o métodos de autenticación basados en SHA-256. Tener una implementación personalizada nos permite:

  • Ampliar la funcionalidad básica SHA-256 para admitir nuevas funciones de seguridad.
  • Modificar la implementación para que funcione con nuevos esquemas de autenticación.
  • Integre operaciones criptográficas adicionales sin problemas.
  • Mantener la compatibilidad con versiones anteriores mientras se agregan nuevas capacidades.

Además, una implementación personalizada proporciona una base para implementar otras funciones criptográficas que podrían resultar necesarias en el futuro. La estructura del código y las técnicas de optimización desarrolladas para SHA-256 pueden servir como plantilla para implementar otras funciones hash u operaciones criptográficas.

Consideremos un escenario en el que un exchange introduce un nuevo requisito de doble hash o combina SHA-256 con otro algoritmo. Con una implementación personalizada, agregar estas características se convierte en una cuestión de extender el código existente en lugar de intentar solucionar las limitaciones de las funciones integradas.

Esta extensibilidad es particularmente valiosa en el panorama del comercio de criptomonedas en rápida evolución. Pueden surgir rápidamente nuevos patrones comerciales, requisitos de seguridad y avances tecnológicos, y tener una implementación flexible y personalizable permite que los sistemas comerciales se adapten y evolucionen junto con el mercado.

La combinación de optimización del rendimiento y capacidades de preparación para el futuro hace que una implementación SHA-256 personalizada sea invaluable para operaciones serias de comercio de criptomonedas. Proporciona el control, la flexibilidad y la eficiencia necesarios para mantener una ventaja competitiva en un mercado en rápido movimiento y, al mismo tiempo, garantizar la viabilidad a largo plazo a medida que evolucionan los requisitos.


Comprensión del algoritmo SHA-256

SHA-256 significa Algoritmo Hash Seguro de 256 bits, una función hash criptográfica que toma una entrada arbitraria y la asigna a una salida de tamaño fijo de 256 bits (32 bytes). Pertenece a la familia de algoritmos SHA-2 y sigue un conjunto de pasos muy sistemáticos y bien definidos, una característica que equilibra la seguridad y el determinismo.

Implementación en MQL5

Examinemos cada componente en detalle. La implementación completa está disponible en la sección final como referencia. En esta implementación, tendremos dos clases, similares a la implementación de Python, donde se utilizan las clases HMAC y SHA256:

Aquí está la estructura de la clase SHA256 y HMAC.

class CSha256Class
  {
private:

   uint              total_message[];
   uint              paddedMessage[64];
   void              Initialize_H();//This function initializes the values of h0-h7
   uint              RawMessage[];//Keeps track of the raw message sent in
public:
   //hash values from h0 - h7
   uint              h0;
   uint              h1;
   uint              h2;
   uint              h3;
   uint              h4;
   uint              h5;
   uint              h6;
   uint              h7;

   uint              K[64];
   uint              W[64];

                     CSha256Class(void);
                    ~CSha256Class() {};

   void              PreProcessMessage(uint &message[], int messageLength);
   void              CreateMessageSchedule();
   void              Compression();
   void              UpdateHash(uint &message[], int message_len);
   void              GetDigest(uint &digest[]);
   string            GetHex();
  };
class HMacSha256
  {
private:

public:
   uint              k_ipad[64];
   uint              k_opad[64];
   uint              K[];
   string            hexval;
                     HMacSha256(string key, string message);
                    ~HMacSha256() {};
   CSha256Class      myshaclass;
   void              ProcessKey(string key);
  };



Guía paso a paso para implementar estas clases

Este módulo implementa el algoritmo HMAC tal y como se describe en RFC 2104.

Paso 1:
Creación de una función para procesar la clave. 

void HMacSha256::ProcessKey(string key)
  {
   int keyLength = StringLen(key);//stores the length of the key

   if(keyLength>64)
     {
      uchar keyCharacters[];

      StringToCharArray(key, keyCharacters);
      uint KeyCharuint[];
      ArrayResize(KeyCharuint, keyLength);

      //Converts the keys to their characters
      for(int i=0;i<keyLength;i++)
         KeyCharuint[i] = (uint)keyCharacters[i];

      //Time to hash the 
      CSha256Class keyhasher;
      keyhasher.UpdateHash(KeyCharuint, keyLength);

      uint digestValue[];
      keyhasher.GetDigest(digestValue);
      ArrayResize(K, 64);

      for(int i=0;i<ArraySize(digestValue);i++)
         K[i] = digestValue[i];

      for(int i=ArraySize(digestValue);i<64;i++)
         K[i] = 0x00;

     }
   else
     {
      uchar keyCharacters[];

      StringToCharArray(key, keyCharacters);
      ArrayResize(K, 64);

      for(int i=0;i<keyLength;i++)
         K[i] = (uint)keyCharacters[i];

      for(int i=keyLength;i<64;i++)
         K[i] = 0x00;
     }
  }

Esta implementación tiene en cuenta la longitud de la clave: si es superior a 64, primero se somete a un proceso de hash utilizando nuestra clase CSha256Class.

Paso 2:
Implementación completa de HMAC.

HMacSha256::HMacSha256(string key,string message)
  {
//process key and add zeros to complete n bytes of 64
   ProcessKey(key);

   for(int i=0;i<64;i++)
     {
      uint keyval = K[i];
      k_ipad[i] = 0x36 ^ keyval;
      k_opad[i] = 0x5c ^ keyval;
     }

//text chars
   uchar messageCharacters[];
   StringToCharArray(message, messageCharacters);
   int innerPaddingLength = 64+StringLen(message);

   uint innerPadding[];
   ArrayResize(innerPadding, innerPaddingLength);
        
   for(int i=0;i<64;i++)
      innerPadding[i] = k_ipad[i];

   int msg_counts = 0;
   for(int i=64;i<innerPaddingLength;i++)
     {
      innerPadding[i] = (uint)messageCharacters[msg_counts];
      msg_counts +=1;
     }

//send inner padding for hashing
   CSha256Class innerpaddHasher;
   innerpaddHasher.UpdateHash(innerPadding, ArraySize(innerPadding));


   uint ipad_digest_result[];
   innerpaddHasher.GetDigest(ipad_digest_result);

//   merge digest with outer padding
   uint outerpadding[];
   int outerpaddSize = 64 + ArraySize(ipad_digest_result);

   ArrayResize(outerpadding, outerpaddSize);
   for(int i=0;i<64;i++)
      outerpadding[i] = k_opad[i];

   int inner_counts = 0;
   for(int i=64;i<outerpaddSize;i++)
     {
      outerpadding[i] = ipad_digest_result[inner_counts];
      inner_counts+=1;
     }

   CSha256Class outerpaddHash;
   outerpaddHash.UpdateHash(outerpadding, ArraySize(outerpadding));
   hexval = outerpaddHash.GetHex();
  }

Hay otras funciones disponibles en el código completo adjunto.

El componente clave de esta implementación es la función Hash, que es gestionada por CSHa256Class.

La función hash implica varios pasos de operación sobre el texto.

Paso 1: Preprocesamiento de valores.

Debemos asegurarnos de que todos los datos sean múltiplos de 512 bits, por lo que aplicamos algunas operaciones de relleno.

  1. Convierta el mensaje a su formato binario.
  2. Añadir 1 al final.
  3. Añade ceros como relleno hasta que la longitud de los datos alcance los 448 bits (que es 512 - 64 bits). Esto garantiza que nos queden exactamente 64 bits en el bloque de 512 bits. En otras palabras, rellenamos el mensaje para que sea congruente con 448 módulo 512.
  4. Añade 64 bits al final, donde los 64 bits son un entero big-endian que representa la longitud de la entrada original en binario.

Paso 2: Inicialización de los valores hash.

Paso 3: Inicialización de las constantes de redondeo.

Paso 4: Divida los bits totales del mensaje en bloques de 512 bits y realice la siguiente operación en cada bloque de forma iterativa.

   int chunks_count = (int)MathFloor(ArraySize(total_message)/64.0);
   int copied = 0;

   for(int i=0; i<chunks_count; i++)
     {
      uint newChunk[];
      ArrayResize(newChunk, 64);
      ArrayInitialize(newChunk, 0);  // Initialize chunk array

      for(int j=0; j<64; j++)
        {
         newChunk[j] = total_message[copied];
         copied += 1;
        }

      PreProcessMessage(newChunk, ArraySize(newChunk));
      CreateMessageSchedule();
      Compression();
     }

Paso 5: Preprocesar el mensaje copiando la matriz de fragmentos en una nueva matriz en la que cada entrada sea una palabra de 32 bits.

void CSha256Class::PreProcessMessage(uint &message[],int messageLength)
  {
   ArrayInitialize(paddedMessage, 0);
   for(int i=0; i < messageLength; i++)
      paddedMessage[i] = message[i];
  }
Paso 6: Crea el calendario de mensajes para este fragmento.
void CSha256Class::CreateMessageSchedule()
  {
   ArrayInitialize(W, 0);

   int counts = 0;
   for(int i=0; i<ArraySize(paddedMessage); i+=4)
     {
      //32 bits is equivalent to 4 bytes from message
      uint byte1 = paddedMessage[i];
      uint byte2 = paddedMessage[i+1];
      uint byte3 = paddedMessage[i+2];
      uint byte4 = paddedMessage[i+3];

      uint combined = ((byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4);
      W[counts] = combined & 0xFFFFFFFF;

      counts += 1;
     }
   for(int i=counts; i<64; i++)
      W[i] = 0x00000000;
//preserve previous counts

   int prev_counts = counts;
   int left_count = 64-counts;
   for(int i=counts; i<64; i++)
     {
      uint s0 = (RightRotate(W[i-15], 7)) ^ (RightRotate(W[i-15],18)) ^ (W[i-15] >> 3);
      uint s1 = (RightRotate(W[i-2], 17)) ^ (RightRotate(W[i-2],19)) ^ (W[i-2] >> 10);

      W[i] = (W[i-16] + s0 + W[i-7] + s1) & 0xFFFFFFFF;
     }
  }

Paso 7: Aplique el bucle de compresión.

void CSha256Class::Compression(void)
  {
   uint a = h0;
   uint b = h1;
   uint c = h2;
   uint d = h3;
   uint e = h4;
   uint f = h5;
   uint g = h6;
   uint h = h7;

   for(int i=0; i<64; i++)
     {
      uint S1 = (RightRotate(e, 6) ^ RightRotate(e,11) ^ RightRotate(e,25)) & 0xFFFFFFFF;
      uint ch = ((e & f) ^ ((~e) & g))& 0xFFFFFFFF;
      uint temp1 = (h + S1 + ch + K[i] + W[i]) & 0xFFFFFFFF;
      uint S0 = (RightRotate(a, 2) ^ RightRotate(a, 13) ^ RightRotate(a, 22)) & 0xFFFFFFFF;
      uint maj = ((a & b) ^ (a & c) ^ (b & c)) & 0xFFFFFFFF;
      uint temp2 = (S0 + maj) & 0xFFFFFFFF;
      h = g & 0xFFFFFFFF;
      g = f & 0xFFFFFFFF;
      f = e & 0xFFFFFFFF;
      e = (d + temp1) & 0xFFFFFFFF;
      d = c & 0xFFFFFFFF;
      c = b & 0xFFFFFFFF;
      b = a & 0xFFFFFFFF;
      a = (temp1 + temp2)&0xFFFFFFFF;
     }

   h0 = h0 + a;
   h1 = h1 + b;
   h2 = h2 + c;
   h3 = h3 + d;
   h4 = h4 + e;
   h5 = h5 + f;
   h6 = h6 + g;
   h7 = h7 + h;

  }

Después de completar el bucle de compresión, actualizamos los valores hash finales añadiendo las variables de trabajo modificadas a los valores hash originales.
Esta operación de suma se realiza después de procesar cada fragmento de 512 bits del mensaje, y los valores hash actualizados se convierten en el punto de partida para procesar el siguiente fragmento. Este mecanismo de encadenamiento garantiza que el hash de cada bloque dependa de todos los bloques anteriores, lo que hace que el valor hash final dependa de todo el mensaje.


Cómo utilizar esta clase

Para generar firmas API para Binance o Bybit, cree una instancia HMAC (código de autenticación de mensajes basado en hash), similar a la implementación de Python.

void OnStart()
{
   // The text to hash
   string text = "Hello";
   string key_text = "key";   
     
  HMacSha256 sha256(key_text, text);
  Print(sha256.hexval);
}

>>> C70B9F4D665BD62974AFC83582DE810E72A41A58DB82C538A9D734C9266D321E

Al comparar las firmas generadas por ambas implementaciones, verás que producen resultados idénticos.


Conclusión

Los operadores que trabajan con criptomonedas suelen enfrentarse a problemas de compatibilidad de firmas API, optimización del rendimiento y preparación para el futuro cuando utilizan funciones criptográficas integradas en sistemas de negociación como MetaTrader 5. Este artículo guía a los operadores sobre cómo implementar SHA-256 desde cero en MQL5 para superar estos problemas.

En conclusión, crear una implementación personalizada de SHA-256 ofrece a los operadores compatibilidad con las plataformas de intercambio, un rendimiento mejorado y flexibilidad para adaptarse a cambios futuros, lo que la convierte en una estrategia esencial para operaciones seguras y eficientes con criptomonedas.

Recuerde comprobar periódicamente la implementación con vectores de prueba estándar y validar las firmas con sus intercambios de destino antes de implementarla en producción. A medida que las plataformas de intercambio de criptomonedas evolucionan sus requisitos de seguridad, contar con esta implementación flexible y personalizada resultará invaluable para una rápida adaptación y mantenimiento.

Traducción del inglés realizada por MetaQuotes Ltd.
Artículo original: https://www.mql5.com/en/articles/16357

Archivos adjuntos |
Sha256Algorithm.mqh (18.56 KB)
Sha256TestFile.mq5 (0.89 KB)
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 27 feb 2025 en 14:08
Sergey Zhilinskiy #:

Si key_text tiene más de 64 caracteres, entonces HMacSha256 calcula incorrectamente. ¿Qué hay que corregir para esto?

Mi implementación actual se adapta a claves con más de 64 caracteres de longitud. ¿Tiene algún par clave-mensaje específico para el que no funcione?

Sergey Zhilinskiy
Sergey Zhilinskiy | 27 feb 2025 en 15:32
Abdulkudus Okatengwu Kadir #:

Mi implementación actual se adapta a claves con más de 64 caracteres de longitud. Tiene algún par clave-mensaje específico para el que no funcione?

string texto = "Hola";

string clave_texto = "1234567890123456789012345678901234567890123456789012345678901234";

https://www.devglan.com/online-tools/hmac-sha256-online -> 7558a77ff19ed6cb4777355e4bbc4772759a8130e1bb0913ba62b88411fdbaf8

Script de prueba -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

if cadena texto_clave = "123456789012345678901234567890123456789012345678901234567890123" - OK
Abdulkudus Okatengwu Kadir
Abdulkudus Okatengwu Kadir | 28 feb 2025 en 11:39
Sergey Zhilinskiy #:

cadena texto = "Hola";

cadena clave_texto = "1234567890123456789012345678901234567890123456789012345678901234";

https://www.devglan.com/online-tools/hmac-sha256-online -> 7558a77ff19ed6cb4777355e4bbc4772759a8130e1bb0913ba62b88411fdbaf8

Script de prueba -> 2025.02.27 22:28:43.792 Sha256TestFile (EURUSD,M5) 6d8ee9dc1d16261fd986fafb97d919584aa206ca76706fb3deccc63ab2b7f6b

if cadena texto_clave = "123456789012345678901234567890123456789012345678901234567890123" - OK

Acabo de probarlo en mi terminal y me da lo mismo que la herramienta de hash online:

2025.02.28 12:37:16.468 hashin_example_code (EURUSD,M5) 7558A77FF19ED6CB4777355E4BBC4772759A8130E1BB0913BA62B88411FDBAF8

utilizando el código siguiente:
void Hash()
{
   // El texto a hash
   string text = "Hello";
   string key_text = "1234567890123456789012345678901234567890123456789012345678901234";
   HMacSha256 myhash(key_text, text);
   Print(myhash.hexval);
}
Si lo desea, puede compartir su código.

Sergey Zhilinskiy
Sergey Zhilinskiy | 1 mar 2025 en 02:50

Sí, funciona correctamente con el Sha256Algorithm.mqh original. Hice algunos cambios, ¿quizás por eso no funcionaba?

 string CSha256Class::GetHex( void )
  {
   string result  = "" ;
 /*
 resultado += UintToHex(h0);
 resultado += UintToHex(h1);
 resultado += UintToHex(h2);
 resultado += UintToHex(h3);
 resultado += UintToHex(h4);
 resultado += UintToHex(h5);
 resultado += UintToHex(h6);
 resultado += UintToHex(h7);
*/ 
   result += StringFormat ( "%.2x" ,h0);
   result += StringFormat ( "%.2x" ,h1);
   result += StringFormat ( "%.2x" ,h2);
   result += StringFormat ( "%.2x" ,h3);
   result += StringFormat ( "%.2x" ,h4);
   result += StringFormat ( "%.2x" ,h5);
   result += StringFormat ( "%.2x" ,h6);
   result += StringFormat ( "%.2x" ,h7);

   return (result);
  }

¡Perdón por la molestia!

Stanislav Korotky
Stanislav Korotky | 2 jul 2025 en 11:29
Hay una implementación de SHA256, SHA384, SHA512 en kodobase, funciona en MQL5 también.
Desarrollo de un asesor experto para el análisis de eventos de noticias basados en el calendario en MQL5 Desarrollo de un asesor experto para el análisis de eventos de noticias basados en el calendario en MQL5
La volatilidad tiende a alcanzar su punto máximo alrededor de eventos noticiosos de alto impacto, lo que crea oportunidades de ruptura significativas. En este artículo, describiremos el proceso de implementación de una estrategia de ruptura basada en el calendario. Cubriremos todo, desde la creación de una clase para interpretar y almacenar datos del calendario, el desarrollo de backtests realistas utilizando estos datos y, finalmente, la implementación del código de ejecución para operaciones en vivo.
Redes neuronales en el trading: Aprendizaje multitarea basado en el modelo ResNeXt Redes neuronales en el trading: Aprendizaje multitarea basado en el modelo ResNeXt
El marco de aprendizaje multitarea basado en ResNeXt optimiza el análisis de datos financieros considerando su alta dimensionalidad, la no linealidad y las dependencias temporales. El uso de la convolución grupal y cabezas especializadas permite al modelo extraer eficazmente características clave de los datos de origen.
Redes neuronales en el trading: Aprendizaje multitarea basado en el modelo ResNeXt (Final) Redes neuronales en el trading: Aprendizaje multitarea basado en el modelo ResNeXt (Final)
Continuamos nuestra exploración del framework de aprendizaje multitarea basado en ResNeXt, que destaca por su modularidad, su alta eficiencia desde el punto de vista computacional y su capacidad de identificar patrones consistentes en los datos. El uso de un único codificador y de "cabezas" especializadas reduce el riesgo de sobreentrenamiento del modelo y mejora la calidad de las predicciones.
Sistemas neurosimbólicos en trading algorítmico: Combinación de reglas simbólicas y redes neuronales Sistemas neurosimbólicos en trading algorítmico: Combinación de reglas simbólicas y redes neuronales
El artículo relata la experiencia del desarrollo de un sistema comercial híbrido que combine el análisis técnico clásico con las redes neuronales. El autor describe detalladamente la arquitectura del sistema, desde el análisis básico de patrones y la estructura de la red neuronal hasta los mecanismos de toma de decisiones comerciales, compartiendo código real y observaciones de carácter práctico.