А можно (действительно!) стартовать рандомайзер с одной точки - стартуем его из индикатора, который генерирует синтетику, запоминаем в Гл. Пер, и читаем из 2-го индюка ;)
<<Чтобы переинициализировать генератор (т.е. установить генератор в предыдущее начальное состояние), необходимо использовать значение 1 в качестве инициализирующего параметра.>>
Хотя общепринято -1. Но я не настаиваю. Дальше:
<<Вызов MathRand перед любым вызовом MathSrand генерирует ту же самую последовательность, что и запрос MathSrand с параметром 1.>>
Этот пассаж, честно говоря, вообще ниасилил. Что хотел сказать автор?
int start_value = 0; int start() { same_func1(); other_func(); same_func2(); return(0); } void same_func1() { start_value = GetTickCount(); MathSrand( start_value ); string res = "same_func1: "; for ( int i = 0; i < 10; i ++ ) { res = StringConcatenate( res, ", ", MathRand() ); } Print( res ); } void other_func() { Sleep(10); MathSrand( GetTickCount() ); string res = "other_func: "; for ( int i = 0; i < 10; i ++ ) { res = StringConcatenate( res, ", ", MathRand() ); } Print( res ); } void same_func2() { MathSrand( start_value ); string res = "same_func2: "; for ( int i = 0; i < 10; i ++ ) { res = StringConcatenate( res, ", ", MathRand() ); } Print( res ); }
2007.04.04 00:45:04 RandomTest EURUSD,H1: removed
2007.04.04 00:45:04 RandomTest EURUSD,H1: same_func2: , 2317, 28082, 3577, 8814, 9570, 15106, 16476, 14479, 26207, 19491
2007.04.04 00:45:04 RandomTest EURUSD,H1: other_func: , 2369, 3448, 27260, 611, 10763, 12397, 739, 411, 28248, 19426
2007.04.04 00:45:04 RandomTest EURUSD,H1: same_func1: , 2317, 28082, 3577, 8814, 9570, 15106, 16476, 14479, 26207, 19491
2007.04.04 00:45:04 RandomTest EURUSD,H1: loaded successfully
Если при генерации чисел встретилось, скажем, 23281, то всегда ли следующим будет 16827? (при затравке 1 будет 41, 18467, 6334, 26500, 19169, 15724, 11478, 29358, 26962, 24464, 5705, 28145, 23281, 16827, 9961, 491, 2995, 11942, 4827, 5436, ... )
А можно ли этого избежать? Если нет, то получается, что при достаточной длине последовательности начиная с некоторого номера MathRand() вырождается в периодическую последовательность... Вопрос не праздный, так как генерировать приходится длинные последовательности. ОК, результаты такого микроисследования я выложу чуть позднее.
#property show_inputs extern int init_start = 0; extern int init_end = 100000; extern int interations = 10000; int start() { int tmp, pre_tmp, count_23281 = 0, count_16827 = 0, count_23281_16827 = 0; string res; for ( int start = init_start; start < init_end; start ++ ) { MathSrand( start ); for ( int i = 0; i < interations; i ++ ) { pre_tmp = tmp; tmp = MathRand(); if ( pre_tmp == 23281 ) { count_23281 ++; if ( tmp == 16827 ) { count_23281_16827 ++; res = StringConcatenate( res, count_23281_16827, ": Init value = ", start, ", interation # ", i, "\n" ); } } if ( pre_tmp == 16827 ) count_16827 ++; } } Comment( "Чисел 23281 - ", count_23281, "\nЧисел 16827 - ", count_16827, "\nЧередований 23281 с 16827 - ", count_23281_16827, ":\n", res ); return(0); }
Счетчик инициализируется значениями с 0 до 100 000, после этого берется 10 000 случайных чисел.
Я взял твой код и слегка упростил его, убрав внешний цикл и инициализировав start=1. Результат меня приятно удивил: на миллиарде итераций (примерно 100 секунд вычислений) чередований было выявлено только 2, хотя самих чисел - как и надо по равномерному распределению, примерно по 30500. Проверки по другим парам соседних чисел дали примерно такие же результаты. Браво MQ! Генератор действительно весьма качественный, и периодичности совсем не видно.
Все наши математические функции являются обёртками для соответствующих стандартных сишных функций из crt
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
- надо сформировать на текущем чарте некую синтетическую историю по одной цене (Open) и отобразить ее в основном окне (нулевом),
- потом сформировать некий осциллятор от этой генерированной истории (скажем, MACD) и отобразить его в новом окне (скажем, первом).
Никакие комбинации #property indicator_xxx_window и галочек в свойствах индикатора ("Show in the data window") не позволяют сделать это с помощью одного индюкатора (хотя при #property indicator_separate_window и включенной "Show in the data window" осциллу можно отобразить и в центре основного окна).
Значит, надо работать двумя кодами. ОК. В коде первого индюкатора заполняем графический буфер "синтетикой", отображая его на чарте, а во втором, который нужен для отображения осциллятора, вызываем первый с помощью iCustom("GenerateSynthetic", ...), который генерит синтетику, по которой вычисляем MACD и отображаем его в новом окошке для осциллятора.
Все бы хорошо, но проблема в том, что "синтетика" генерится с использованием MathRand(). Поэтому вызов iCustom() генерит другую синтетику, не совпадающую с отображенной в первом индюкаторе!
Хорошо. Тогда, так как массив нельзя передать через глобальные переменные, вроде бы остается только одна возможность: вместе с генерацией синтетики в первом индюкаторе писать весь массив в файл, а потом считывать содержимое файла для обработки в коде второго индюкатора. Естественно, надо позаботиться о том, чтобы обработка шла не на каждом тике...
Вот такая ситуация. Кто-то знает, что можно сделать, чтобы попроще? Вроде бы где-то проскакивало что-то такое про переинициализацию MathRand() с той же самой точки...