滚动(静态)数组?

Posted

技术标签:

【中文标题】滚动(静态)数组?【英文标题】:Rolling (static) array? 【发布时间】:2018-02-04 12:30:11 【问题描述】:

基于ticks per second (ticksLastSecond),我现在想计算最后一分钟每秒的平均滴答声。为此,我需要一个 rolling 数组,我假设它的大小 = 60,每秒将数组元素向前推最新的 ticksLastSecond 值(最好在 开始 (0) 数组)和最旧的一个。这怎么可能实现?

非常感谢!

【问题讨论】:

【参考方案1】:

您可以使用数组,请记住以下几点:如果您需要 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);

也可以保留计算的平均值,然后最后加,先减——这会更快,考虑回测的情况。 这一切可能会更好地放在一个结构中。

使用CArrayIntCArrayObj 相同但更容易 - 在这种情况下您不必担心大小,使用方法Add()DeleteRange(0,size-1) 进行循环: Total() andAt(i);

另一种方法是在 mql5 中使用链表,可以轻松访问第一个和最后一个元素。它已经实现了,所以试试CLinkedList&lt;T&gt; : public ICollection here

【讨论】:

再次感谢您,丹尼尔!您声明了 add() 函数并且可能还想调用它?我不完全理解的是:您将每秒每个新的刻度总和附加到数组的末尾,然后用 ArrayCopy 覆盖(使用这个函数的好主意)用旧的值(从元素 @ [size ]),我不确定,因为 ArrayCopy 的最后一个函数参数已被省略,因此它默认为整个数组?无论如何,非常感谢,您的回答对我帮助很大! 当数组变得太大时,resize 会删除一半的数组(长度的两倍,肯定是你需要的两倍) 嗨,我刚刚测试了你的代码,但似乎 ArrayCopy(array,array,0,size);不起作用。我非常喜欢这个想法,但你确定可以将数组复制到自身中吗? 是的,数组可以复制到自身中。通过编辑您的帖子来显示问题,我们会看看可能是什么问题 是的,你是对的,非常感谢!我只需要先将整个数组初始化为 0,否则会出现奇怪的(=巨大的!)数字并扭曲平均值!但是请告诉我:为什么我必须写“double div = 5.0/3;”而不是“双 div = 5/3;”只是为了得到正确的结果(1.66666)而不是1???【参考方案2】:

我认为使用列表更有效。

MQL5 提供了一系列处理列表的机制。 例如,我要做的是声明一个 CList 并为具有必要属性的列表项创建一个类。在你的情况下,滴答声的时间。

#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));

列表不会在数组中复制、删除、插入...项目,而是仅修改指向上一项和下一项的指针。所以它的计算效率要高得多。

【讨论】:

以上是关于滚动(静态)数组?的主要内容,如果未能解决你的问题,请参考以下文章

滚动数组

java的静态数组和动态数组有啥区别?

滚动数组

在python中滚动数组

java 静态数组 和非静态数组的区别

01背包+滚动数组