Циклический массив..

 


Привет, вот расчитал я 4500 значений в массиве, - прошел один бар надо расчитывать заново.

Расчет не меняется, должен появиться новый расчетный бар, и исчезнуть самый старый.
Как это сделать?

Пока решаю задачу в лоб. Переписываю все элементы массива на + 1 ранг. И потом добавляюю новый.

Но ведь это долго.. есть ли пути быстрее? Особенно если бар минута, тормоза в тестере стратегии - обеспечиваются.

 
TVA_11 >>:


Как это сделать?

Пока решаю задачу в лоб. Переписываю все элементы массива на + 1 ранг. И потом добавляюю новый.

Но ведь это долго.. есть ли пути быстрее? Особенно если бар минута, тормоза в тестере стратегии - обеспечиваются.

Ну дык сам же и ответил - циклический массив. Я так тики передвигаю в неотображаемых индюках. Ну т.е. наоборот. Они на месте, индекс только перерасчитывается.

Вапче тема хорошая. Все бы индикаторы так сделать. Давно такой проект собираюсь предложить. Одному влом переписывать все индюки.

На mql5 наверное надо затеять. Базовый объект слепить, потом всё на него вешать.

 
Посмотрите здесь. Алгоритм тот же. Еще конкретней - вот.
 
Svinozavr писал(а) >>
Посмотрите здесь. Алгоритм тот же. Еще конкретней - вот.


Огромное спасибо!, просто и хорошо!

 
Мне кажется, это разные задачи. Вам же надо было не расширять массив с появлением нового значения, а использовать фиксированный (сказали - старый бар маст дай).
Тогда это классический алгоритм циклического буфера. Храните индекс текущей границы, пишите новый бар по этому индексу (и инкрементируйте его), читайте с учётом не от 0, а от этого индекса. Учитывайте "заворот индекса" с 0 на конец буфера, и обратно.
 
Dali >>:
Мне кажется, это разные задачи. Вам же надо было не расширять массив с появлением нового значения, а использовать фиксированный (сказали - старый бар маст дай).

Можно сделать и фиксированный. Тогда добавится еще строчка к конец - ресайз на фиксированное, оно же предыдущее значение. А в начало - инкремент размера на 1. Только и всего.
Тогда это классический алгоритм циклического буфера. Храните индекс текущей границы, пишите новый бар по этому индексу (и инкрементируйте его), читайте с учётом не от 0, а от этого индекса. Учитывайте "заворот индекса" с 0 на конец буфера, и обратно.

Не так все просто.

 
Svinozavr писал(а) >>

Не так все просто.


Самый лучший вариант. Но не всегда им можно воспользоваться. А так очень хорошо выручает. Но в свободном доступе моих разработок с таким алгоритмом практически нету. Для себя делаю.

 
TVA_11 писал(а) >>


Привет, вот расчитал я 4500 значений в массиве, - прошел один бар надо расчитывать заново.

Расчет не меняется, должен появиться новый расчетный бар, и исчезнуть самый старый.
Как это сделать?

Пока решаю задачу в лоб. Переписываю все элементы массива на + 1 ранг. И потом добавляюю новый.

Но ведь это долго.. есть ли пути быстрее? Особенно если бар минута, тормоза в тестере стратегии - обеспечиваются.

:) Просто сделайте индикатор и его буфер будет сам сдвигаться по приходу нового бара.
 
SProgrammer >>:

:) Просто сделайте индикатор и его буфер будет сам сдвигаться по приходу нового бара.

Нет. Не пойдет. По той простой причине, что как только вы захотите что-то (xxx) передать (записать в массив) в этот индикатор iCustom(......., xxx, mode,shift), то у вас произойдет переинициализация и опустошение его буфера (буферов).

 
Svinozavr >>:

Можно сделать и фиксированный. Тогда добавится еще строчка к конец - ресайз на фиксированное, оно же предыдущее значение. А в начало - инкремент размера на 1. Только и всего.


Не так все просто.

1) Это хитрость. Это надо обдумать. Если работает, то это хак в лучшем смысле. Я же говорил про классический алгоритм без учёта особенности платформы.

2) Ну алгоритм описан во многих учебниках. Начиная с Вирта, если не ошибаюсь. И код есть готовый на C/C++.

 
Рабочий пример циклического буфера:

extern int  HistoryLen = 36;  // Размер циклического буфера
....
double BidHistoryBuffer[];
int Cur=0;
int init()
{
...
  ArrayResize(BidHistoryBuffer, HistoryLen);
 ...
}
int start()
{
.........
.......
// Запись тиков:
     BidHistoryBuffer[Cur] = Bid;
     Cur++;
     Cur%=HistoryLen;
...
...
// Доступ к нужным тикам:
   int C = shift(0);  // == Cur
   double m1 = BidHistoryBuffer[C] - BidHistoryBuffer[shift(4)]; //moment(4);
   double m2 = BidHistoryBuffer[C] - BidHistoryBuffer[shift(9)]; //moment(9);
   double m3 = BidHistoryBuffer[C] - BidHistoryBuffer[shift(15)]; //moment(15);
......
..........
}
// пересчёт индексов для доступа:
int shift(int offset)
{
  return((Cur - offset + HistoryLen) % HistoryLen);
}
Причина обращения: