2025-09-30 07:58:30 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| RandomSimple.mqh |
|
| | | //| Copyright 2025, Niquel Mendoza. |
|
| | | //| https://www.mql5.com/es/users/nique_372/news |
|
| | | //+------------------------------------------------------------------+
|
| | | #property copyright "Copyright 2025, Niquel Mendoza."
|
| | | #property link "https://www.mql5.com/es/users/nique_372/news"
|
| | | #property strict
|
| | |
|
2025-11-10 09:33:53 -05:00 | | | #ifndef MQLARTICLES_UTILS_RANDOMSIMPLE_MQH
|
| | | #define MQLARTICLES_UTILS_RANDOMSIMPLE_MQH
|
2025-09-30 07:58:30 -05:00 | | |
|
2025-11-10 09:33:53 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
2025-09-30 07:58:30 -05:00 | | | //#define RANDOM_SIMPLE_STRICT
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| Clase para la generacion de valores random |
|
| | | //+------------------------------------------------------------------+
|
| | | class CRandomSimple
|
| | | {
|
| | | private:
|
| | | uint m_seed;
|
| | |
|
| | | public:
|
| | | CRandomSimple() : m_seed(0) { }
|
| | |
|
| | | //--- Seed
|
| | | inline uint Seed() const { return m_seed; }
|
| | | inline void Seed(const uint new_value) { MathSrand((m_seed = new_value)); } // operator = devuleve new_value
|
| | |
|
| | | //--- Randoms
|
| | | //- Random Short
|
| | | short RandomShort(short start, short step, short stop);
|
| | | short RandomShort(short start, short stop);
|
| | |
|
| | | //- Random long
|
| | | long RandomLong(long start, long step, long stop);
|
| | | long RandomLong(long start, long stop);
|
| | |
|
| | | //- Random int
|
| | | int RandomInt(int start, int step, int stop);
|
| | | int RandomInt(int start, int stop);
|
| | |
|
| | | //- Random double
|
| | | double RandomDouble(double start, double step, double stop);
|
| | | double RandomDouble(double start, double stop);
|
| | |
|
| | | //- Random float
|
| | | float RandomFloat(float start, float step, float stop);
|
| | | float RandomFloat(float start, float stop);
|
| | |
|
| | | //- Random bool
|
| | | bool RandomBool();
|
| | |
|
2025-09-30 09:33:24 -05:00 | | | //- Random string
|
| | | string RandomString(int lenth, const string &chars[]);
|
| | |
|
2025-09-30 07:58:30 -05:00 | | | //--- Select
|
| | | template <typename T>
|
| | | T RandomSelect(const T &arr[]);
|
| | |
|
| | | template <typename T>
|
| | | void RandomSelectMultiple(const T &arr[], T &out[], short elements_to_select);
|
| | |
|
| | | template <typename T>
|
| | | void RandomSelectMultiple(const T &arr[], T &out[], int elements_to_select);
|
| | | };
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomLong con step |
|
| | | //+------------------------------------------------------------------+
|
| | | long CRandomSimple::RandomLong(long start, long step, long stop)
|
| | | {
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(step <= 0 || start >= stop)
|
| | | return 0;
|
| | | #endif
|
| | |
|
| | | long range = (stop - start) / step;
|
| | | long rand_val = 0;
|
| | | if(range <= 32767)
|
| | | {
|
| | | rand_val = MathRand() % (range + 1);
|
| | | }
|
| | | else
|
| | | {
|
| | | rand_val = ((long)MathRand() << 16) | MathRand();
|
| | | rand_val = rand_val % (range + 1);
|
| | | }
|
| | |
|
| | | return start + rand_val * step;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomLong sin step |
|
| | | //+------------------------------------------------------------------+
|
| | | long CRandomSimple::RandomLong(long start, long stop)
|
| | | {
|
| | | return RandomLong(start, 1, stop);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomInt con step |
|
| | | //+------------------------------------------------------------------+
|
| | | int CRandomSimple::RandomInt(int start, int step, int stop)
|
| | | {
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(step <= 0 || start >= stop)
|
| | | return 0;
|
| | | #endif
|
| | |
|
| | | int range = (stop - start) / step;
|
| | | int rand_val = 0;
|
| | | if(range <= 32767)
|
| | | {
|
| | | rand_val = MathRand() % (range + 1);
|
| | | }
|
| | | else
|
| | | {
|
| | | rand_val = (MathRand() << 15) | MathRand();
|
| | | rand_val = rand_val % (range + 1);
|
| | | }
|
| | |
|
| | | return start + rand_val * step;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandonInt sin step |
|
| | | //+------------------------------------------------------------------+
|
| | | int CRandomSimple::RandomInt(int start, int stop)
|
| | | {
|
| | | return RandomInt(start, 1, stop);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomShort con step |
|
| | | //+------------------------------------------------------------------+
|
| | | short CRandomSimple::RandomShort(short start, short step, short stop)
|
| | | {
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(step <= 0 || start >= stop)
|
| | | return 0;
|
| | | #endif
|
| | | short range = (stop - start) / step;
|
| | | short rand_val = (short)MathRand() % (range + 1); // No hya problema con el cast mathrand solo retorna de 0 - SHORT_MAX
|
| | | return start + rand_val * step;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomShort sin step |
|
| | | //+------------------------------------------------------------------+
|
| | | short CRandomSimple::RandomShort(short start, short stop)
|
| | | {
|
| | | return RandomShort(start, 1, stop);
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomDouble con step |
|
| | | //+------------------------------------------------------------------+
|
| | | double CRandomSimple::RandomDouble(double start, double step, double stop)
|
| | | {
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(step <= 0.00000000000001 || start >= stop)
|
| | | return 0.00;
|
| | | #endif
|
| | |
|
| | | int steps = (int)MathAbs((stop - start) / step);
|
| | | int rand_val = 0;
|
| | | if(steps <= 32767)
|
| | | {
|
| | | rand_val = MathRand() % (steps + 1);
|
| | | }
|
| | | else
|
| | | {
|
| | | rand_val = (MathRand() << 15) | MathRand();
|
| | | rand_val = rand_val % (steps + 1);
|
| | | }
|
| | |
|
| | | return start + rand_val * step;
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomDouble sin step |
|
| | | //+------------------------------------------------------------------+
|
| | | double CRandomSimple::RandomDouble(double start, double stop)
|
| | | {
|
| | | double rand_val = (double)MathRand() / 32767.0;
|
| | | return start + rand_val * (stop - start);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomFloat con step |
|
| | | //+------------------------------------------------------------------+
|
| | | float CRandomSimple::RandomFloat(float start, float step, float stop)
|
| | | {
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(step <= 0.00000f || start >= stop)
|
| | | return 0.0f;
|
| | | #endif
|
| | |
|
| | | int steps = (int)MathAbs((stop - start) / step);
|
| | | int rand_val = 0;
|
| | | if(steps <= 32767)
|
| | | {
|
| | | rand_val = MathRand() % (steps + 1);
|
| | | }
|
| | | else
|
| | | {
|
| | | rand_val = (MathRand() << 15) | MathRand();
|
| | | rand_val = rand_val % (steps + 1);
|
| | | }
|
| | |
|
| | | return (float)(start + rand_val * step);
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomFloat sin step |
|
| | | //+------------------------------------------------------------------+
|
| | | float CRandomSimple::RandomFloat(float start, float stop)
|
| | | {
|
| | | float rand_val = (float)MathRand() / 32767.0f;
|
| | | return start + rand_val * (stop - start);
|
| | | }
|
2025-09-30 09:33:24 -05:00 | | |
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| RandomBool |
|
| | | //+------------------------------------------------------------------+
|
| | | bool CRandomSimple::RandomBool()
|
| | | {
|
| | | return (MathRand() % 2) == 1;
|
| | | }
|
| | |
|
| | | //+------------------------------------------------------------------+
|
| | | //| |
|
| | | //+------------------------------------------------------------------+
|
| | | string CRandomSimple::RandomString(int lenth, const string &chars[])
|
| | | {
|
| | | const int size_chars = ArraySize(chars);
|
| | | string str = "";
|
| | |
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(lenth <= 0 || size_chars < 1)
|
| | | return str;
|
| | |
|
| | | #endif
|
| | | for(int i = 0; i < lenth; i++)
|
| | | {
|
| | | const int idx = MathRand() % size_chars;
|
| | | str += chars[idx];
|
| | | }
|
| | | return str;
|
| | | }
|
| | |
|
| | |
|
2025-09-30 07:58:30 -05:00 | | | //+------------------------------------------------------------------+
|
| | | //| RandomSelect - selecciona elemento aleatorio del array |
|
| | | //+------------------------------------------------------------------+
|
| | | template <typename T>
|
| | | T CRandomSimple::RandomSelect(const T &arr[])
|
| | | {
|
| | | T empty_value;
|
| | | const int size = ArraySize(arr);
|
| | | return size == 0 ? empty_value : arr[RandomInt(0, size - 1)];
|
| | | }
|
| | | //+--------------------------------------------------------------------------+
|
| | | //| RandomSelect - selecciona varios elementos aleatorios del array |
|
| | | //+--------------------------------------------------------------------------+
|
| | | template <typename T>
|
| | | void CRandomSimple::RandomSelectMultiple(const T &arr[], T &out[], short elements_to_select)
|
| | | {
|
| | | const int size = ArraySize(arr);
|
| | | if(size < 1)
|
| | | return;
|
| | |
|
| | | //---
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(elements_to_select > size)
|
| | | elements_to_select = size;
|
| | |
|
| | | if(elements_to_select < 1)
|
| | | return;
|
| | | #endif
|
| | |
|
| | | //---
|
| | | ArrayResize(out, elements_to_select);
|
| | |
|
| | | //---
|
| | | int indices[];
|
| | | ArrayResize(indices, size);
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < size; i++)
|
| | | indices[i] = i;
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < elements_to_select; i++)
|
| | | {
|
| | | //---
|
| | | const int randIdx = MathRand() % (size - i);
|
| | |
|
| | | //---
|
| | | out[i] = arr[indices[randIdx]];
|
| | |
|
| | | //---
|
| | | const int temp = indices[randIdx];
|
| | | indices[randIdx] = indices[size - i - 1];
|
| | | indices[size - i - 1] = temp;
|
| | | }
|
| | | }
|
| | |
|
| | | //+--------------------------------------------------------------------------+
|
| | | //| RandomSelect - selecciona varios elementos aleatorios del array |
|
| | | //+--------------------------------------------------------------------------+
|
| | | template <typename T>
|
| | | void CRandomSimple::RandomSelectMultiple(const T &arr[], T &out[], int elements_to_select)
|
| | | {
|
| | | const int size = ArraySize(arr);
|
| | | if(size < 1)
|
| | | return;
|
| | |
|
| | | //---
|
| | | #ifdef RANDOM_SIMPLE_STRICT
|
| | | if(elements_to_select > size)
|
| | | elements_to_select = size;
|
| | |
|
| | | if(elements_to_select < 1)
|
| | | return;
|
| | | #endif
|
| | |
|
| | | //---
|
| | | ArrayResize(out, elements_to_select);
|
| | |
|
| | | //---
|
| | | int indices[];
|
| | | ArrayResize(indices, size);
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < size; i++)
|
| | | indices[i] = i;
|
| | |
|
| | | //---
|
| | | for(int i = 0; i < elements_to_select; i++)
|
| | | {
|
| | | //---
|
| | | const int randIdx = RandomInt(0, size - i - 1);
|
| | |
|
| | | //---
|
| | | out[i] = arr[indices[randIdx]];
|
| | |
|
| | | //---
|
| | | const int temp = indices[randIdx];
|
| | | indices[randIdx] = indices[size - i - 1];
|
| | | indices[size - i - 1] = temp;
|
| | | }
|
| | | }
|
| | | //+------------------------------------------------------------------+
|
2025-11-10 09:33:53 -05:00 | | | #endif // MQLARTICLES_UTILS_RANDOMSIMPLE_MQH
|