//+------------------------------------------------------------------+ //| MT64.mqh | //| Copyright 2026, Niquel Mendoza | //| https://www.mql5.com | //+------------------------------------------------------------------+ #property copyright "Copyright 2026, Niquel Mendoza" #property link "https://www.mql5.com" #property strict #ifndef PRNGBYLEO_SRC_IMP_MT64_MT64_MQH #define PRNGBYLEO_SRC_IMP_MT64_MT64_MQH //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ namespace TSN { //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ // referencias: // https://www.mql5.com/en/articles/14413 //--- #define UM 0xFFFFFFFF80000000 #define LM 0x7FFFFFFF #define NN 312 #define MM 156 //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ class CMersenneTwister64 { protected: //--- ulong m_MT[NN]; int m_index; //--- void Twist(); //--- uint m_uinteger; public: CMersenneTwister64(); ~CMersenneTwister64() {} //--- void Seed(ulong seed); //--- ulong nextUInt64(); uint nextUInt32(); }; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ CMersenneTwister64::CMersenneTwister64() { ulong v = (ulong)TerminalInfoInteger(TERMINAL_PING_LAST) ^ (ulong)TerminalInfoInteger(TERMINAL_MEMORY_USED); v ^= (ulong)GetTickCount64(); v ^= (ulong)TerminalInfoDouble(TERMINAL_RETRANSMISSION) * 100000ULL; v ^= (ulong)MQLInfoInteger(MQL_GLOBAL_COUNTER); Seed(v); } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMersenneTwister64::Seed(ulong seed) { m_uinteger = 0U; m_index = NN; m_MT[0] = seed; for(int i = 1; i < NN; i++) { m_MT[i] = (6364136223846793005ULL * (m_MT[i - 1] ^ (m_MT[i - 1] >> 62)) + i); } } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ ulong CMersenneTwister64::nextUInt64() { if(m_index >= NN) { Twist(); } //--- ulong y = m_MT[m_index]; y ^= (y >> 29) & 0x5555555555555555; y ^= (y << 17) & 0x71D67FFFEDA60000; y ^= (y << 37) & 0xFFF7EEE000000000; y ^= (y >> 43); //--- m_index++; return y; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ void CMersenneTwister64::Twist() { //--- const ulong mag01[2] = {0ULL, 0xB5026F5AA96619E9}; //--- ulong x; int i; for(i = 0; i < NN - MM; i++) { x = (m_MT[i] & UM) | (m_MT[i + 1] & LM); m_MT[i] = m_MT[i + MM] ^ (x >> 1) ^ mag01[(x & 1)]; } for(; i < NN - 1; i++) { x = (m_MT[i] & UM) | (m_MT[i + 1] & LM); m_MT[i] = m_MT[i + (MM - NN)] ^ (x >> 1) ^ mag01[(x & 1)]; } x = (m_MT[311] & UM) | (m_MT[0] & LM); m_MT[311] = m_MT[155] ^ (x >> 1) ^ mag01[(x & 1)]; //--- m_index = 0; } //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ uint CMersenneTwister64::nextUInt32(void) { if(m_uinteger) // en caso no haya un valor previo { const uint t = m_uinteger; // temporal m_uinteger = 0; // reset return t; // retornamos } const ulong next = nextUInt64(); m_uinteger = (uint)(next >> 32); return (uint)(next); } //---- #undef UM #undef LM #undef NN #undef MM } #endif // PRNGBYLEO_SRC_IMP_MT64_MT64_MQH