Доброго времени суток. Подскажите, я при начале работы заполняю массив котировками следующим образом:
при этом, при появлении нового бара мне нужно его занести в этот массив как элемент с индексом 0. Я работаю на виртуальном сервере, и порой пока советник запустит повторное заполнение массива уже может появиться 2 или 3 новых бара. Поэтому при добавлении 1 нового элемента в начале массива и добавлении нового бара бывает такое, что некоторые бары просто не заполняются в массив и следовательно все вычисления идут неправильно. Как можно решить эту проблему? Мне нужно оптимизировать этот процесс, т.к. при заполнении каждый раз массива с 0 всеми элементами тратится слишком много времени
А почему бы не добавить бар последним?
При работе с Copy-функциями можно учитывать "серийный" признак приёмного массива. Из книги:
Однако копировать все бары каждый раз не имеет смысла, можно копировать лишь те, что появились позже последнего запроса. Этот маленький массив можно дописывать в большой массив котировок с помощью ArrayCopy, задав индекс to равным длине приемного массива - массив будет автоматически расширен под новые элементы. Опять же, чтобы дописывать в начало, а не конец, включите признак серийности.
В частности, легко расширять динамический массив спереди, а не сзади.
// наращиваем массив p спереди ArraySetAsSeries(p, true); const int n = ArraySize(p); ArrayResize(p, n + 1); p[n] = ...; ArraySetAsSeries(p, false);Под индексом 0 оказывается бывший только что последним новый элемент.
- www.mql5.com
При работе с Copy-функциями можно учитывать "серийный" признак приёмного массива. Из книги:
Однако копировать все бары каждый раз не имеет смысла, можно копировать лишь те, что появились позже последнего запроса. Этот маленький массив можно дописывать в большой массив котировок с помощью ArrayCopy, задав индекс to равным длине приемного массива - массив будет автоматически расширен под новые элементы. Опять же, чтобы дописывать в начало, а не конец, включите признак серийности.
В частности, легко расширять динамический массив спереди, а не сзади.
Под индексом 0 оказывается бывший только что последним новый элемент.Вы думаете два раза перевернуть массив, изменить размер массива и скопировать данные в массив, а это не единичное значение, а структура, будет быстрей чем скопировать повторно все данные? У меня нет желания и времени на замеры, но сомнение есть. Вы не замеряли?
ps; Всё-же я не удержался от замера…
/****************Custom indicator iteration function*****************/ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- if(prev_calculated > 0 && rates_total-prev_calculated > 1) return 0; // Если во время работы индикатора подгрузились новые бары, запустим пересчёт индикатора с нуля… //--- Основной цикл int i = 0; MqlRates rates[]; ulong start = GetMicrosecondCount(); do { CopyRates(_Symbol, PERIOD_CURRENT, rates_total, 0, rates); i++; } while(i < rates_total && !IsStopped()); Print("Первый замер ", rates_total, " ", GetMicrosecondCount()-start); //--- i = 0; MqlRates p[], r[]; start = GetMicrosecondCount(); do { ArraySetAsSeries(p, true); const int n = ArraySize(p); ArrayResize(p, n + 1); CopyRates(_Symbol, PERIOD_CURRENT, i, 1, r); p[n] = r[0]; ArraySetAsSeries(p, false); //BufferClose[i]=close[i]; i++; } while(i < rates_total && !IsStopped()); Print("Второй замер ", rates_total, " ", GetMicrosecondCount()-start); return(rates_total); }/*******************************************************************/
И вот такой результат
2024.01.21 10:57:52.362 !!00 (USDJPY,M15) Первый замер 5480 35 2024.01.21 10:57:53.162 !!00 (USDJPY,M15) Второй замер 5480 803058 2024.01.21 10:58:10.962 !!00 (USDJPY,M15) Первый замер 5480 40 2024.01.21 10:58:11.752 !!00 (USDJPY,M15) Второй замер 5480 793128 2024.01.21 10:58:38.514 !!00 (USDJPY,M15) Первый замер 5480 41 2024.01.21 10:58:39.294 !!00 (USDJPY,M15) Второй замер 5480 784119 2024.01.21 11:00:03.608 !!00 (USDJPY,M15) Первый замер 5480 35 2024.01.21 11:00:04.368 !!00 (USDJPY,M15) Второй замер 5480 762086 2024.01.21 11:00:14.598 !!00 (USDJPY,M15) Первый замер 5480 41 2024.01.21 11:00:15.358 !!00 (USDJPY,M15) Второй замер 5480 767572 2024.01.21 11:04:09.801 !!00 (USDJPY,M15) Первый замер 5480 40 2024.01.21 11:04:10.571 !!00 (USDJPY,M15) Второй замер 5480 774958
А в каком месте он переворачивается?
Тут
Форум по трейдингу, автоматическим торговым системам и тестированию торговых стратегий
Обновление массива Rates с каждым новым баров. Или как добавить в массив только последний бар.
Stanislav Korotky, 2024.01.20 15:26
При работе с Copy-функциями можно учитывать "серийный" признак приёмного массива. Из книги:
Однако копировать все бары каждый раз не имеет смысла, можно копировать лишь те, что появились позже последнего запроса. Этот маленький массив можно дописывать в большой массив котировок с помощью ArrayCopy, задав индекс to равным длине приемного массива - массив будет автоматически расширен под новые элементы. Опять же, чтобы дописывать в начало, а не конец, включите признак серийности.
В частности, легко расширять динамический массив спереди, а не сзади.
// наращиваем массив p спереди ArraySetAsSeries(p, true); const int n = ArraySize(p); ArrayResize(p, n + 1); p[n] = ...; ArraySetAsSeries(p, false);Под индексом 0 оказывается бывший только что последним новый элемент.
Не придирайтесь к словам. Смена порядка индексации это и есть переворачивание массива.
И посмотрите дополнение в моём сообщении. Я не удержался и сделал замер скорости…
ArrayResize(), тем более на 1 элемент, крайне длительная операция, вы в основном его замеряли :-) Чтобы было шустро надо резервировать память, то есть использовать 3-й параметр
И смена порядка индексации - это всё-тами просто инверсия флага.
да ещё никто отчего-то не проверил корректность полученных данных :-) но это традиция
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Доброго времени суток. Подскажите, я при начале работы заполняю массив котировками следующим образом:
при этом, при появлении нового бара мне нужно его занести в этот массив как элемент с индексом 0. Я работаю на виртуальном сервере, и порой пока советник запустит повторное заполнение массива уже может появиться 2 или 3 новых бара. Поэтому при добавлении 1 нового элемента в начале массива и добавлении нового бара бывает такое, что некоторые бары просто не заполняются в массив и следовательно все вычисления идут неправильно. Как можно решить эту проблему? Мне нужно оптимизировать этот процесс, т.к. при заполнении каждый раз массива с 0 всеми элементами тратится слишком много времени