Rolling (static) array?

自古美人都是妖i 提交于 2019-12-11 09:53:09

问题


Based on ticks per second (ticksLastSecond), I would now like to calculate the average ticks per second over the last minute. For this, I would need a rolling array with size = 60 I assume, each second pushing the array elements forward by the newest ticksLastSecond value (preferrably at the beginning (0) of the array) and the oldest one out. How could this be achieved?

Many thanks in advance!


回答1:


you can use arrays, keeping in mind the following: if you need average of 60 (x) values, your array could be of size 60(which is very impractical: you will need to copy elements 1 to 59 into 0 to 58 each second) or 120(copying once per minute) more. So, 120 is preferred I think, more is of no need.

input int size = 60;
int array[];
ArraySize(array,2*size);
int cursor=0; //- shows position of the last element

void add(const int element){
   if(cursor>=2*size-1)resize();
   array[cursor++]=element;
}
void resize(){
   ArrayCopy(array,array,0,size);
   cursor=size;
}
//for array average: iMAOnArray() or manually:
double getAvg(){
   if(cursor+1<size)return 0;
   double sum=0;
   for(int i=0;i<size;i++){
      sum+=array[cursor-1-i];
   }
   return(sum/cursor);
}

also possible to keep computed value of average and then add last, subtract first-this will speed up even more, think in case of backtesting. This all might be better to put in a structure.

Same but easier is use of CArrayInt or CArrayObj - in such case you do not worry about size, use methods Add() and DeleteRange(0,size-1), for looping : Total() andAt(i);

Another approach is to use a linked list in mql5, with easy access to first and last element. It is already implemented so try CLinkedList<T> : public ICollection here




回答2:


I think that using lists is more efficient.

MQL5 provides a series of mechanisms to work with lists. For instance, what I would do is to declare a CList and create a class for the items of the list with the necessary attributes. In your case the time of the tick.

#include <Arrays\List.mqh>
#include <Object.mqh>

int storedItems = 60;
CList *listTicks = new CList;

class listItem : public CObject {
    public:
        listItem(double n){value=n;};
        double getValue(){return value;};
    private:
        double value;
};

Then, in the OnTick function, I'd check if the list is full to delete the head item. Finally, I'd insert the new item at the end of the list:

if(listTicks.Total() == storedTicks)
    listTicks.Delete(0);
listTicks.Add(new listItem(tick_time));

Instead of copying, deleting, inserting... items in an array, a list only modifies the pointer to the previous and the next item. So it's much more computationally efficient.



来源:https://stackoverflow.com/questions/48608058/rolling-static-array

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!