滚动(静态)数组?
Rolling (static) array?
基于 (ticksLastSecond
),我现在想计算最后一分钟的 平均 每秒滴答声。为此,我需要一个 rolling 数组,我假设大小 = 60,每秒将数组元素向前推最新的 ticksLastSecond
值(最好在数组的 开头 (0) 处)和最旧的值。这是如何实现的?
非常感谢!
您可以使用数组,但请记住以下几点:如果您需要 60 (x) 个值的平均值,则您的数组的大小可能为 60(这是非常不切实际的:您需要将元素 1 到 59 复制到每秒 0 到 58)或 120(每分钟复制一次)更多。所以,我觉得120是首选,没必要再多了。
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);
}
也可以保留平均值的计算值,然后最后加,先减-这样会更快,考虑回测的情况。
这些都放在一个结构中可能会更好。
使用 CArrayInt
或 CArrayObj
相同但更容易 - 在这种情况下,您不必担心大小,使用方法 Add()
和 DeleteRange(0,size-1)
进行循环:
Total() and
在(i);
另一种方法是在 mql5 中使用链表,可以轻松访问第一个和最后一个元素。它已经实现,所以尝试 CLinkedList<T> : public ICollection
here
我认为使用列表更有效率。
MQL5 提供了一系列机制来处理列表。
例如,我要做的是声明一个 CList 并为具有必要属性的列表项创建一个 class。在你的情况下,滴答时间。
#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;
};
然后,在 OnTick
函数中,我将检查列表是否已满以删除头项。最后,我将在列表末尾插入新项目:
if(listTicks.Total() == storedTicks)
listTicks.Delete(0);
listTicks.Add(new listItem(tick_time));
不是复制、删除、插入...数组中的项目,列表只修改指向上一个和下一个项目的指针。所以它的计算效率更高。
基于 ticksLastSecond
),我现在想计算最后一分钟的 平均 每秒滴答声。为此,我需要一个 rolling 数组,我假设大小 = 60,每秒将数组元素向前推最新的 ticksLastSecond
值(最好在数组的 开头 (0) 处)和最旧的值。这是如何实现的?
非常感谢!
您可以使用数组,但请记住以下几点:如果您需要 60 (x) 个值的平均值,则您的数组的大小可能为 60(这是非常不切实际的:您需要将元素 1 到 59 复制到每秒 0 到 58)或 120(每分钟复制一次)更多。所以,我觉得120是首选,没必要再多了。
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);
}
也可以保留平均值的计算值,然后最后加,先减-这样会更快,考虑回测的情况。 这些都放在一个结构中可能会更好。
使用 CArrayInt
或 CArrayObj
相同但更容易 - 在这种情况下,您不必担心大小,使用方法 Add()
和 DeleteRange(0,size-1)
进行循环:
Total() and
在(i);
另一种方法是在 mql5 中使用链表,可以轻松访问第一个和最后一个元素。它已经实现,所以尝试 CLinkedList<T> : public ICollection
here
我认为使用列表更有效率。
MQL5 提供了一系列机制来处理列表。 例如,我要做的是声明一个 CList 并为具有必要属性的列表项创建一个 class。在你的情况下,滴答时间。
#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;
};
然后,在 OnTick
函数中,我将检查列表是否已满以删除头项。最后,我将在列表末尾插入新项目:
if(listTicks.Total() == storedTicks)
listTicks.Delete(0);
listTicks.Add(new listItem(tick_time));
不是复制、删除、插入...数组中的项目,列表只修改指向上一个和下一个项目的指针。所以它的计算效率更高。