Generador de Magic Numbers

 

Hola a todos.

Hace dos días que intento compartir un generador de Magic Numbers con el foro y el sistema no me deja. Primero porque el post tenia el enlace al Market donde tengo publicada la version completa y despues porque comparti el indicador compilado, listo para que lo descarguen. El mensaje de la segunda opertunidad fue que no se permite codigo compilado y que comparta el *.ex5 (justamente lo que habia hecho) 

Realmente creo que les seria muy util esta herramienta y es mi manera de agradecer por todas las buenas ideasque saque de aqui.

Si alguien me puede ayudar, le voy a estar muy agradecido.


Saludos.-

 
Augusto Osvaldo Toso:

Hola Augusto,

El motivo por el que tus mensajes fueron eliminados es doble:

  • No está permitido publicar enlaces ni ningún tipo de referencia a productos del Market, aunque sean gratuitos, ya que se considera contenido promocional.
  • Tampoco se permite compartir archivos compilados ( .ex5 ). El foro está orientado a compartir código fuente ( .mq5 ), para que otros usuarios puedan revisarlo, aprender o aportar mejoras.

En tu caso además hubo una confusión en un mensaje anterior donde se mencionó .ex5 como válido, cuando en realidad debe ser .mq5 .

Si quieres compartir tu generador, puedes hacerlo sin problema siguiendo estas pautas:

  • Publica el código fuente (.mq5) o pega el código utilizando el botón "Código" (Alt+S).
  • Evita cualquier referencia al Market

Seguro que así tu aporte será bien recibido.

 
Miguel Angel Vico Alba #:

Hola Augusto,

El motivo por el que tus mensajes fueron eliminados es doble:

  • No está permitido publicar enlaces ni ningún tipo de referencia a productos del Market, aunque sean gratuitos, ya que se considera contenido promocional.
  • Tampoco se permite compartir archivos compilados ( .ex5 ). El foro está orientado a compartir código fuente ( .mq5 ), para que otros usuarios puedan revisarlo, aprender o aportar mejoras.

En tu caso además hubo una confusión en un mensaje anterior donde se mencionó .ex5 como válido, cuando en realidad debe ser .mq5 .

Si quieres compartir tu generador, puedes hacerlo sin problema siguiendo estas pautas:

  • Publica el código fuente (.mq5) o pega el código utilizando el botón "Código" (Alt+S).
  • Evita cualquier referencia al Market

Seguro que así tu aporte será bien recibido.

Hola Miguel, gracias por tu respuesta. Este es el codigo:
//+------------------------------------------------------------------+
//|                         MagicDisplay.mq5                         |
//|               Copyright 2026, Augusto Toso & Kin                 |
//|                       https://www.mql5.com                       |
//+------------------------------------------------------------------+
#property copyright "Augusto Toso (Tato1211) & Kin"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property description "Magic Number Generator — Display on Chart"
#property description "Shows the unique Magic Number for current Symbol, Timeframe and EA ID"
#property script_show_inputs

//--- Recursos embebidos (con los nombres correctos de tus archivos)
#resource "\\Resources\\Generador_Magic.html" as string HtmlResource
#resource "\\Resources\\MagicGen.mqh" as string MqhResource

//--- Input parameters
input string InpEA_ID = "A";  // EA Identifier (max 2 characters)

//--- Panel constants
#define PANEL_PREFIX   "MAGIC_"
#define PANEL_X        20
#define PANEL_Y        40
#define PANEL_FONTSIZE 11
#define PANEL_PADDING  10

//--- Colors
#define COLOR_BG       0x000000  // Negro puro
#define COLOR_BORDER   clrLime
#define COLOR_TEXT     clrWhite
#define COLOR_HIGHLIGHT clrLime

//--- Global variables
string g_symbol;
string g_tf;
string g_magicStr;
int    g_magicInt;

//+------------------------------------------------------------------+
//| Alphabet with Ñ (Spanish)                                       |
//+------------------------------------------------------------------+
#define ALPHABET "ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"

//+------------------------------------------------------------------+
//| Convert string to number representation                         |
//+------------------------------------------------------------------+
string ConvertToNumber(string str)
  {
   string result = "";
   StringToUpper(str);
   for(int i = 0; i < StringLen(str); i++)
     {
      int c = StringGetCharacter(str, i);
      if(c >= '0' && c <= '9')
         result += StringFormat("%c", c);
      else
        {
         int pos = GetLetterPosition(c);
         if(pos > 0)
            result += IntegerToString(pos);
         else
            result += "0";
        }
     }
   return result;
  }

//+------------------------------------------------------------------+
//| Get letter position in alphabet                                 |
//+------------------------------------------------------------------+
int GetLetterPosition(int character)
  {
   for(int i = 0; i < StringLen(ALPHABET); i++)
      if(StringGetCharacter(ALPHABET, i) == character)
         return i + 1;
   return 0;
  }

//+------------------------------------------------------------------+
//| Decode a string (for display)                                   |
//+------------------------------------------------------------------+
string DecodePart(string str)
  {
   string result = "";
   StringToUpper(str);
   for(int i = 0; i < StringLen(str); i++)
     {
      int c = StringGetCharacter(str, i);
      if(c >= '0' && c <= '9')
         result += StringFormat("%c", c);
      else
        {
         int pos = GetLetterPosition(c);
         if(pos > 0)
            result += StringFormat("%c=%d", c, pos);
        }
      if(i < StringLen(str) - 1)
         result += " ";
     }
   return result;
  }

//+------------------------------------------------------------------+
//| Get timeframe in minutes                                        |
//+------------------------------------------------------------------+
string GetTimeframeString()
  {
   ENUM_TIMEFRAMES tf = Period();
   int seconds = PeriodSeconds(tf);
   int minutes = seconds / 60;
   return IntegerToString(minutes);
  }

//+------------------------------------------------------------------+
//| Generate Magic Number                                            |
//+------------------------------------------------------------------+
void GenerateMagic()
  {
   g_symbol = Symbol();
   g_tf = GetTimeframeString();

   string p1 = ConvertToNumber(g_symbol);
   string p2 = ConvertToNumber(g_tf);
   string p3 = ConvertToNumber(InpEA_ID);

   g_magicStr = p1 + p2 + p3;

   // For MT4 compatibility, limit to 9 digits if needed
   if(StringLen(g_magicStr) > 9)
      g_magicInt = (int)StringToInteger(StringSubstr(g_magicStr, 0, 9));
   else
      g_magicInt = (int)StringToInteger(g_magicStr);
  }

//+------------------------------------------------------------------+
//| Extrae un recurso a la carpeta Files                            |
//+------------------------------------------------------------------+
bool ExtractResource(string resData, string fileName)
  {
   int handle = FileOpen(fileName, FILE_WRITE | FILE_BIN);
   if(handle == INVALID_HANDLE)
     {
      Print("Error creando archivo: ", fileName);
      return false;
     }
   FileWriteString(handle, resData);
   FileClose(handle);
   return true;
  }

//+------------------------------------------------------------------+
//| Draw panel background (NEGRO OPACO FORZADO)                     |
//+------------------------------------------------------------------+
void PanelBG(int x, int y, int w, int h)
  {
   string full = PANEL_PREFIX + "BG";
   if(ObjectFind(0, full) < 0)
     {
      ObjectCreate(0, full, OBJ_RECTANGLE_LABEL, 0, 0, 0);
     }

   // Posición y tamaño
   ObjectSetInteger(0, full, OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, full, OBJPROP_YDISTANCE, y);
   ObjectSetInteger(0, full, OBJPROP_XSIZE,     w);
   ObjectSetInteger(0, full, OBJPROP_YSIZE,     h);

   // Color de fondo: NEGRO ABSOLUTO (0x000000)
   ObjectSetInteger(0, full, OBJPROP_BGCOLOR,   0x000000);

   // Color del borde: VERDE
   ObjectSetInteger(0, full, OBJPROP_COLOR,     clrLime);
   ObjectSetInteger(0, full, OBJPROP_WIDTH,     1);
   ObjectSetInteger(0, full, OBJPROP_BORDER_TYPE, BORDER_FLAT);

   // Propiedades críticas
   ObjectSetInteger(0, full, OBJPROP_BACK,        false);   // No es fondo de verdad, es objeto normal
   ObjectSetInteger(0, full, OBJPROP_FILL,        true);    // Forzar relleno
   ObjectSetInteger(0, full, OBJPROP_SELECTABLE,  false);
   ObjectSetInteger(0, full, OBJPROP_HIDDEN,      true);
   ObjectSetInteger(0, full, OBJPROP_ZORDER,      0);
   ObjectSetInteger(0, full, OBJPROP_CORNER,      CORNER_LEFT_UPPER);
  }
  
//+------------------------------------------------------------------+
//| Draw a text line in the panel                                   |
//+------------------------------------------------------------------+
void PanelText(string id, string text, int x, int y, color clr)
  {
   string full = PANEL_PREFIX + id;
   if(ObjectFind(0, full) < 0)
     {
      ObjectCreate(0, full, OBJ_LABEL, 0, 0, 0);
      ObjectSetInteger(0, full, OBJPROP_CORNER,     CORNER_LEFT_UPPER);
      ObjectSetInteger(0, full, OBJPROP_SELECTABLE, false);
      ObjectSetInteger(0, full, OBJPROP_HIDDEN,     true);
      ObjectSetInteger(0, full, OBJPROP_BACK,       false);  // ← el texto va adelante
      ObjectSetInteger(0, full, OBJPROP_ZORDER,     2);
     }
   ObjectSetInteger(0, full, OBJPROP_XDISTANCE, x);
   ObjectSetInteger(0, full, OBJPROP_YDISTANCE, y);
   ObjectSetString(0, full, OBJPROP_TEXT,       text);
   ObjectSetString(0, full, OBJPROP_FONT,       "Consolas");
   ObjectSetInteger(0, full, OBJPROP_FONTSIZE,  PANEL_FONTSIZE);
   ObjectSetInteger(0, full, OBJPROP_COLOR,     clr);
  }

//+------------------------------------------------------------------+
//| Create complete panel                                           |
//+------------------------------------------------------------------+
void CreatePanel()
  {
   string lines[20];
   int lineCount = 0;
   int maxLen = 0;

   // Build all text lines
   lines[lineCount] = "⚡ MAGIC NUMBER GENERATOR"; lineCount++;
   lines[lineCount] = "────────────────────────"; lineCount++;
   lines[lineCount] = "Symbol:   " + g_symbol; lineCount++;
   lines[lineCount] = "TF:       " + g_tf + " min"; lineCount++;
   lines[lineCount] = "EA ID:    " + InpEA_ID; lineCount++;
   lines[lineCount] = "────────────────────────"; lineCount++;
   lines[lineCount] = "MAGIC:    " + g_magicStr; lineCount++;
   lines[lineCount] = "Int:      " + IntegerToString(g_magicInt) + " (MT4)"; lineCount++;
   lines[lineCount] = "────────────────────────"; lineCount++;

   string d1 = DecodePart(g_symbol);
   string d2 = DecodePart(g_tf);
   string d3 = DecodePart(InpEA_ID);

   lines[lineCount] = "Decode 1: " + d1; lineCount++;
   lines[lineCount] = "Decode 2: " + d2; lineCount++;
   lines[lineCount] = "Decode 3: " + d3; lineCount++;
   lines[lineCount] = "────────────────────────"; lineCount++;

   string digits = "Digits:   " + IntegerToString(StringLen(g_magicStr)) + " / 19";
   lines[lineCount] = digits; lineCount++;

   if(StringLen(g_magicStr) > 19)
        lines[lineCount] = "⚠️ EXCEEDS 19 DIGITS!";
   else lines[lineCount] = "✅ Safe for MT5";
   lineCount++;

   // Find longest line
   for(int i = 0; i < lineCount; i++)
     {
      int len = StringLen(lines[i]);
      if(len > maxLen) maxLen = len;
     }

   int charWidth = (int)MathCeil(PANEL_FONTSIZE * 0.7);
   int panelWidth = maxLen * charWidth + PANEL_PADDING * 2;
   int panelHeight = lineCount * (PANEL_FONTSIZE + 4) + PANEL_PADDING * 2;

   // Delete old objects
   for(int i = 0; i < 50; i++)
     {
      string name = PANEL_PREFIX + IntegerToString(i);
      ObjectDelete(0, name);
     }

   // Draw background
   PanelBG(PANEL_X, PANEL_Y, panelWidth, panelHeight);

   // Draw all text lines
   for(int i = 0; i < lineCount; i++)
     {
      int yPos = PANEL_Y + PANEL_PADDING + i * (PANEL_FONTSIZE + 4);
      color clr = (i == 0 || i == 6 || i == lineCount-1 || i == lineCount-2) ? COLOR_HIGHLIGHT : COLOR_TEXT;
      PanelText("TXT" + IntegerToString(i), lines[i], PANEL_X + PANEL_PADDING, yPos, clr);
     }

   ChartRedraw(0);
  }

//+------------------------------------------------------------------+
//| Script program start function                                   |
//+------------------------------------------------------------------+
void OnStart()
  {
   // Extraer los archivos embebidos
   Print("Extrayendo archivos...");
   if(ExtractResource(HtmlResource, "Generador_Magic.html"))
      Print("✓ HTML extraído: MQL5/Files/Generador_Magic.html");
   else
      Print("✗ Error extrayendo HTML");

   if(ExtractResource(MqhResource, "MagicGen.mqh"))
      Print("✓ Include extraído: MQL5/Files/MagicGen.mqh");
   else
      Print("✗ Error extrayendo include");

   // Generar Magic Number
   GenerateMagic();

   // Mostrar panel en el gráfico
   CreatePanel();

   // Mostrar en el diario
   Print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
   Print("MAGIC NUMBER GENERATOR");
   Print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
   Print("Symbol:      ", g_symbol);
   Print("Timeframe:   ", g_tf, " min");
   Print("EA ID:       ", InpEA_ID);
   Print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
   Print("MAGIC NUMBER: ", g_magicStr);
   Print("As Integer:   ", g_magicInt, " (for MT4)");
   Print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
   Print("Digits: ", StringLen(g_magicStr), " / 19 max");
   if(StringLen(g_magicStr) > 19)
      Print("⚠️ WARNING: Exceeds 19 digits!");
   else
      Print("✅ Safe for MT5");
   Print("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
   Print("Archivos extraídos a la carpeta MQL5/Files/");
  }
//+------------------------------------------------------------------+
Extremadamente sencillo pero a mi me resulto super util. Se aceptan sugerencias y criticas constructivas.

Saludos.-
 
Augusto Osvaldo Toso #:
Hola Miguel, gracias por tu respuesta. Este es el codigo:
Extremadamente sencillo pero a mi me resulto super util. Se aceptan sugerencias y criticas constructivas.

Saludos.-
Hola, he visto un punto importante que podría causar problemas.

Limitar el Magic Number a 9 dígitos no garantiza que el valor final quepa dentro de un int de 32 bits, porque algunos valores de 9 dígitos siguen pudiendo exceder el rango permitido.

Muchos valores de 9 dígitos caben sin problema en int, como 123456789 o 999999999. Pero no todos. En cuanto superas 2147483647, ya te sales del rango válido de int. Por eso, usar 9 dígitos como criterio de seguridad no garantiza nada por sí solo.

Quizá podrías plantearte validar el rango del valor antes de convertirlo a int, en lugar de basarte solo en la longitud.