2026-07-31 13:06:41 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| Gen.mq5 |
|
| | | //| Copyright 2026, Niquel Mendoza |
|
| | | //| https://www.mql5.com |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2026, Niquel Mendoza"
|
| | | #property link "https://www.mql5.com"
|
| | | #property version "1.00"
|
| | | #property strict
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | #include <TSN\\PHash\\Main.mqh>
|
| | | #include "..\\Basic.mqh"
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | input string InpFileNameOut = "MQLArticles\\Temp\\Main.mqh";
|
| | | input bool InpFolderInC = true;
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | const int g_tf_values[21] =
|
| | | {
|
| | | PERIOD_M1, PERIOD_M2, PERIOD_M3, PERIOD_M4, PERIOD_M5, PERIOD_M6,
|
| | | PERIOD_M10, PERIOD_M12, PERIOD_M15, PERIOD_M20, PERIOD_M30,
|
| | | PERIOD_H1, PERIOD_H2, PERIOD_H3, PERIOD_H4, PERIOD_H6, PERIOD_H8, PERIOD_H12,
|
| | | PERIOD_D1, PERIOD_W1, PERIOD_MN1
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CHasher0
|
| | | {
|
| | | public:
|
| | | CHasher0(void) {}
|
| | | ~CHasher0(void) {}
|
| | | static __forceinline int Hash(const int v)
|
| | | {
|
| | | return v;
|
| | | }
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | class CHasher1
|
| | | {
|
| | | public:
|
| | | CHasher1(void) {}
|
| | | ~CHasher1(void) {}
|
| | | static __forceinline ulong Hash(const int v, const ulong seed)
|
| | | {
|
| | | ulong h = ((ulong)v ^ seed) * 0x9E3779B97F4A7C15;
|
| | | h ^= h >> 32;
|
| | | return h;
|
| | | }
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Script program start function |
|
| | | //+------------------------------------------------------------------+
|
| | | void OnStart()
|
| | | {
|
| | | //---
|
| | | TSN::CPerfectHashByLeo<int, CHasher0, CHasher1> ph;
|
| | | ph.InitAlg(21, 0.98, 4);
|
| | |
|
| | | //---
|
| | | int out_k[];
|
| | | ArrayResize(out_k, ph.m_final_table_size);
|
| | | ArrayInitialize(out_k, -1);
|
| | |
|
| | | ulong out_seeds[];
|
| | | Print(ph.Run(g_tf_values, out_seeds, out_k));
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < 21; i++)
|
| | | {
|
| | | const int v = g_tf_values[i];
|
| | | const int seed_index = int(v & ph.m_buckets_size_last);
|
| | | ulong h = ((ulong)v ^ out_seeds[seed_index]) * 0x9E3779B97F4A7C15;
|
| | | h ^= h >> 32;
|
| | |
|
| | | //--- Pos
|
| | | const int fi = int(h & ph.m_final_table_size_last);
|
| | | PrintFormat("Index final = %d | valor = %s", fi, EnumToString((ENUM_TIMEFRAMES)out_k[fi]));
|
| | | }
|
| | |
|
| | | //---
|
| | | ::ResetLastError();
|
| | | const int fh = FileOpen(InpFileNameOut, FILE_WRITE | FILE_ANSI | FILE_TXT | (InpFolderInC ? FILE_COMMON : 0));
|
| | | if(fh == INVALID_HANDLE)
|
| | | {
|
| | | FastLog(FUNCION_ACTUAL, FATAL_ERROR_TEXT, StringFormat("Fallo al abrir el archivo = %s, ultimo err = %d",
|
| | | InpFileNameOut, ::GetLastError()));
|
| | | return;
|
| | | }
|
| | | //---
|
| | | const int fnt = int(ph.m_final_table_size_last);
|
| | |
|
| | | //--- Escritura del archivo
|
| | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "//| Main.mqh |");
|
| | | FileWrite(fh, "//| Copyright 2026, Niquel Mendoza |");
|
| | | FileWrite(fh, "//| https://www.mql5.com |");
|
| | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "#property copyright \"Copyright 2026, Niquel Mendoza\"");
|
| | | FileWrite(fh, "#property link \"https://www.mql5.com\"");
|
| | | FileWrite(fh, "#property strict");
|
| | | FileWrite(fh, "#ifndef MQLARITCLES_UTILS_TFI_MAIN_MQH");
|
| | | FileWrite(fh, "#define MQLARITCLES_UTILS_TFI_MAIN_MQH");
|
2026-07-31 13:43:33 -05:00 | | | FileWriteString(fh, "\r\n");
|
2026-07-31 13:06:41 -05:00 | | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "//| |");
|
| | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "/*");
|
| | | FileWrite(fh, "La idea con este mqh es poder mapear los valores de enumtimeframe (Que estan dispersos) en una talba");
|
| | | FileWrite(fh, "de 32 entradas por ejemplo un fast period seconds, o un swith jump table o(1)");
|
| | | FileWrite(fh, "O un timeframe to string");
|
| | | FileWrite(fh, "*/");
|
| | | FileWrite(fh, "");
|
2026-07-31 13:43:33 -05:00 | | | FileWrite(fh, "namespace TSN {");
|
2026-07-31 13:06:41 -05:00 | | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "//| |");
|
| | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, StringFormat("#define MQLARTICLES_TFI_BUCKETS_SIZE (%I64uULL)", ph.m_buckets_size));
|
| | | FileWrite(fh, StringFormat("#define MQLARTICLES_TFI_BUCKETS_SIZE_L (%I64uULL)", ph.m_buckets_size_last));
|
| | | FileWrite(fh, StringFormat("#define MQLARTICLES_TFI_FINAL_TSIZE (%I64uULL)", ph.m_final_table_size));
|
| | | FileWrite(fh, StringFormat("#define MQLARTICLES_TFI_FINAL_TSIZE_L (%I64uULL)", ph.m_final_table_size_last));
|
| | | FileWrite(fh, "");
|
| | | FileWrite(fh, "/* Algoritmo completo");
|
| | | FileWrite(fh, "const int seed_index = int(v & MQLARTICLES_TFI_BUCKETS_SIZE_L);");
|
| | | FileWrite(fh, "ulong h = ((ulong)v ^ g_mqlarticles_tfi_out_seeds[seed_index]) * 0x9E3779B97F4A7C15;");
|
| | | FileWrite(fh, "h ^= h >> 32;");
|
| | | FileWrite(fh, "const int fi = int(h & MQLARTICLES_TFI_FINAL_TSIZE_L);");
|
| | | FileWrite(fh, "*/");
|
| | | FileWrite(fh, "");
|
| | | FileWrite(fh, "//--- Tabla de seeds");
|
| | | FileWrite(fh, "const ulong g_mqlarticles_tfi_out_seeds[MQLARTICLES_TFI_BUCKETS_SIZE] =");
|
| | | FileWrite(fh, "{");
|
| | | int v = int(ph.m_buckets_size_last);
|
| | | for(int i = 0; i < v; i++)
|
| | | {
|
| | | FileWrite(fh, StringFormat("%I64uULL,", out_seeds[i]));
|
| | | }
|
| | | FileWrite(fh, StringFormat("%I64uULL", out_seeds[v]));
|
| | | FileWrite(fh, "};");
|
| | | FileWrite(fh, "");
|
| | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "//-- Ahora empezamos con otras tablas ");
|
| | | // tabla 1 period seconds
|
| | | FileWrite(fh, "const int g_mqlarticles_tfi_period_s[MQLARTICLES_TFI_FINAL_TSIZE] = {");
|
| | | for(int i = 0; i < fnt; i++)
|
| | | {
|
| | | const int v = out_k[i];
|
| | | if(v == -1)
|
| | | {
|
| | | FileWrite(fh, "-1, // Invalid ");
|
| | | }
|
| | | else
|
| | | {
|
| | | const ENUM_TIMEFRAMES vt = (ENUM_TIMEFRAMES)v;
|
| | | FileWrite(fh, StringFormat("%d, // %s ", PeriodSecondsFastSeg(vt), EnumToString(vt)));
|
| | | }
|
| | | }
|
| | |
|
| | | //--- final
|
| | | v = out_k[fnt];
|
| | | if(v == -1)
|
| | | {
|
| | | FileWrite(fh, "-1 // Invalid ");
|
| | | }
|
| | | else
|
| | | {
|
| | | const ENUM_TIMEFRAMES vt = (ENUM_TIMEFRAMES)v;
|
| | | FileWrite(fh, StringFormat("%d // %s ", PeriodSecondsFastSeg(vt), EnumToString(vt)));
|
| | | }
|
| | | FileWrite(fh, "};");
|
| | |
|
| | |
|
| | | //--- Ahora namings
|
| | | FileWrite(fh, "");
|
| | | FileWrite(fh, "//--- Ahora namigs");
|
| | | FileWrite(fh, "struct MqlArticlesTfiDesc {");
|
| | | FileWrite(fh, " string full_name; // Nombre compleato eg: PERIOD_M1 ");
|
| | | FileWrite(fh, " string short_name_up; // Short name upper M1, etc.. ");
|
| | | FileWrite(fh, " string short_name_lo; // Short name lowe m1, etc.. ");
|
| | | FileWrite(fh, " string desc; // Short name lowe m1, etc.. ");
|
| | | FileWrite(fh, "}; ");
|
| | | FileWrite(fh, "");
|
| | | FileWrite(fh, "const MqlArticlesTfiDesc g_mqlarticles_tfi_desc[MQLARTICLES_TFI_FINAL_TSIZE] = {");
|
| | | for(int i = 0; i < fnt; i++)
|
| | | {
|
| | | const int v = out_k[i];
|
| | | if(v == -1)
|
| | | {
|
| | | FileWrite(fh, "{\"\", \"\",\"\",\"\"}, // Invalid ");
|
| | | }
|
| | | else
|
| | | {
|
| | | const ENUM_TIMEFRAMES vt = (ENUM_TIMEFRAMES)v;
|
| | | const string str_base = EnumToString(vt);
|
| | | string s = str_base;
|
| | | StringReplace(s, "PERIOD_", "");
|
| | | string low = s;
|
| | | low.Lower();
|
| | | FileWrite(fh, StringFormat("{\"%s\",\"%s\",\"%s\",\"\"}, ", str_base, s, low));
|
| | | }
|
| | | }
|
| | |
|
| | | //---
|
| | | v = out_k[fnt];
|
| | | if(v == -1)
|
| | | {
|
| | | FileWrite(fh, "{\"\", \"\",\"\",\"\"} // Invalid ");
|
| | | }
|
| | | else
|
| | | {
|
| | | const ENUM_TIMEFRAMES vt = (ENUM_TIMEFRAMES)v;
|
| | | const string str_base = EnumToString(vt);
|
| | | string s = str_base;
|
| | | StringReplace(s, "PERIOD_", "");
|
| | | string low = s;
|
| | | low.Lower();
|
| | | FileWrite(fh, StringFormat("{\"%s\",\"%s\",\"%s\",\"\"} ", str_base, s, low));
|
| | | }
|
| | | FileWrite(fh, "}; ");
|
| | | FileWrite(fh, "");
|
2026-07-31 13:43:33 -05:00 | | | FileWrite(fh, "}"); // namespace
|
2026-07-31 13:06:41 -05:00 | | | FileWrite(fh, "//+------------------------------------------------------------------+");
|
| | | FileWrite(fh, "#endif // MQLARITCLES_UTILS_TFI_MAIN_MQH");
|
| | | FileClose(fh);
|
| | | // Termino
|
| | | }
|
| | | //+------------------------------------------------------------------+
|