//+------------------------------------------------------------------+ //| RandFile.mq4 | //| Dubovik | //| | //+------------------------------------------------------------------+ #property copyright "Dubovik" #property link "" #property version "1.00" #property strict #property script_show_inputs //--- input parameters input string S1 = "Number of millions of four-byte words"; input int Millions = 1; input bool CalcSeries = false; const int MillionsMultiplier = 1000000; void OnStart() { // PRNG initialization MathSrand(GetTickCount()); // Writing random data and stat files WriteFiles(); } void WriteFiles() { // Open the files for writing int iRandFile = FileOpen("RandFile.bin", FILE_BIN | FILE_WRITE); int iStatFile = FileOpen("RandStat.csv", FILE_CSV | FILE_WRITE, "\t"); int iOnesSeriesFile = FileOpen("RandOnesSeries.csv", FILE_CSV | FILE_WRITE, "\t"); int iZerosSeriesFile = FileOpen("RandZerosSeries.csv", FILE_CSV | FILE_WRITE, "\t"); // If the files are opened successfully... if ( (iRandFile != INVALID_HANDLE) && (iStatFile != INVALID_HANDLE) && (iOnesSeriesFile != INVALID_HANDLE) && (iZerosSeriesFile != INVALID_HANDLE) ) { // Random numbers will be here uint uiRand; // The arrays, in which each byte's occurrence rate is stored when // collecting random data int iRandBytesTable [256] = {0}; // Dynamic arrays for gathering series length occurrence rate long lOnesSeries[]; long lZerosSeries[]; // The last bit detected uint iLastBit = 0; // Consecutive bits counter int iBitsCount = 0; // For measuring performance uint iStart = GetTickCount(); int iSize = Millions * MillionsMultiplier; // Iteration for gathering the necessary amount of random data using PRNG for (int i = 0; i < iSize; i++) { uiRand = Rand32(); FileWriteInteger(iRandFile, uiRand); // Place the amount of detected bytes to the cells with a byte number iRandBytesTable[uiRand & 0xff]++; iRandBytesTable[(uiRand & 0xff00) >> 8]++; iRandBytesTable[(uiRand & 0xff0000) >> 16]++; iRandBytesTable[(uiRand & 0xff000000) >> 24]++; if (CalcSeries) BitSeries(uiRand, lOnesSeries, lZerosSeries, iLastBit, iBitsCount); } Print(Millions * 4, " millions of random bytes in ", GetTickCount() - iStart, " milliseconds."); // The total amount of single bits in the generated random data is displayed here long lTotalOneBitsRand = 0; // Amount of single bits in a byte int iBits; for (int i = 0; i < 256; i++) { iBits = 0; // Calculate the amount of single bits containing the binary representation of i for (int j = 0; j < 8; j++) { iBits += (i >> j) & 1; } // Add the amount of bits detected in random data lTotalOneBitsRand += iBits * iRandBytesTable[i]; // Write the byte occurrence rate to the file FileWrite(iStatFile, i, iRandBytesTable[i]); } // Print the amount of single bits to log Print("Amount of bit units: ", lTotalOneBitsRand); for (int i = 0; i < ArraySize(lOnesSeries); i++) { FileWrite(iOnesSeriesFile, i, lOnesSeries[i]); } for (int i = 0; i < ArraySize(lZerosSeries); i++) { FileWrite(iZerosSeriesFile, i, lZerosSeries[i]); } // Close the files FileClose(iRandFile); FileClose(iStatFile); FileClose(iOnesSeriesFile); FileClose(iZerosSeriesFile); } else { Print("Failed to open files"); } } // Gather the stats on identical bits coming in a row void BitSeries(uint a_uiRand, long& a_lOnesSeries[], long& a_lZerosSeries[], uint& a_uiLastBit, uint& a_uiBitsCount) { uint uiCurrentBit; for (int i = 31; i >= 0; i--) { uiCurrentBit = (a_uiRand >> i) & 1; if (uiCurrentBit == a_uiLastBit) { a_uiBitsCount++; } else { if (a_uiLastBit == 0) { WriteValue(a_lZerosSeries, a_uiBitsCount); } else { WriteValue(a_lOnesSeries, a_uiBitsCount); } a_uiBitsCount = 0; a_uiLastBit = uiCurrentBit; } } } // Add the value to the array. Increase and initialize it if necessary. void WriteValue(long& a_lSeries[], uint a_uiValue) { // Check the array size if ((uint)ArraySize(a_lSeries) <= a_uiValue) { int iOldSize = ArraySize(a_lSeries); ArrayResize(a_lSeries, a_uiValue + 1, 1000); // Initialize new elements. // In fact, they are initialized already, though this fact is not mentioned in the documentation for (int i = iOldSize; i < ArraySize(a_lSeries); i++) { a_lSeries[i] = 0; } } // Writing the value a_lSeries[a_uiValue]++; } // Returns a random number - 32 bits based on the standard PRNG uint Rand32() { int iResult = 0; iResult |= MathRand(); iResult |= MathRand() << 15; iResult |= (MathRand() & 0x3) << 30; return iResult; }