2

使用MetaTrader TerminalMQL4),我尝试有一个反向数组,我将(前置)项目附加到。

因此,在每个刻度上,myArray[0]成为“最新”值,之前的值转移到myArray[1],依此类推。

但它听起来更难。

我试过这样->

       double myArray        = [];                        // GLOBAL Dynamic array
extern int    maxArrayLength = 50;                        // EXTERN iterable

// -----------------------------------------------------------------------
bool   prependToReversedDoubleArray( double& theArray[], double value, int maxLength ) {

       int size = ArraySize( theArray );                 // LOCAL size
       ArraySetAsSeries(     theArray, false );          // Normalize the array ( left to right )
       ArrayResize(          theArray, size + 1 );       // Extend array length

       Alert( "test = ", size );

       theArray[size] = value;                           // Insert the new value
       ArraySetAsSeries(     theArray, true );           // Reverse the array again
       if ( ArraySize(       theArray ) > maxLength ) {
            ArrayResize(     theArray,    maxLength );
       }
       return( true );
}

prependToReversedDoubleArray( myArray, 0.1234, maxArrayLength );
4

4 回答 4

3

介绍:

幸运的是,TimeSeries 组织的默认 MQL4工具在这种情况下不起作用。

为什么?

MQL4TimeSeries ( reversed ) 数组确实仅在当前 TimeFrame 上获得系统驱动的事件锁定单元索引重新洗牌aNewBarEVENT,而不是仅基于每个anFxQuoteArrivalEVENT(如在 O/P 中要求在[0]每个滴答到达时移动/更新“.. .,在每个刻度上,“)。


如何让它以某种方式工作?

前面提出的一种微不足道for(){ shift 'em all / store new}的循环,乍一看似乎是一个简单的可以做的黑客。

危险是魔鬼隐藏在细节中。

在大约 100.000+ 引号之后,数组增长到单个内存页面的大小将无法容纳整个数组 + 哑单元移位的处理时间(线性)增长O(1),但是到这样的规模,这开始破坏仍然能够像最终能够以非阻塞模式等待几个ms/等待下一个外汇市场事件的到来一样快,因此内部架构失去了与外部事件保持错误同步错觉的能力。usMetaTrader Terminal

ArrayResize()是另一个隐藏的恶魔。

换句话说,这样的代码将开始“丢失”事件(将丢弃数据(它在到达时永远不会看到,因为仍然在单元格移动循环中打乱数据))。


如何让它快速和智能地工作?

0 ) 避免内存页面交换 - 留在内存中。

1 ) 避免任何阻塞步骤。

2 ) 避免任何类似的哑单元改组value[i] = value[i-1];

3)避免任何ArrayResize()在飞行中。

解决方案导致采用分布式循环缓冲区架构形式的代理(唯一可能的非阻塞帮助具有严格的、用户不可控制的线程架构的代码执行)MT4 MQL4

通过这种方式,MQL4代码可以包含一个轻量级代理对象(内部是一个本地的、类似缓存的托管环形缓冲区),它还可以无缝访问几乎无限量的单元数据,存储并实际维护在远程进程/快速计算网格中。

这既无阻塞(永远)又快速智能无限 (如果您的算法交易需要)

于 2015-12-16T14:47:17.953 回答
3
for( int i = arraylength - 1; i >= 1; i-- ) {
    value[i] = value[i-1];
    }
value[0] = newValue;
于 2015-12-16T13:32:47.963 回答
2

感谢所有好的英特尔!我从解释中学到了很多:)

我遇到的问题是,如何将值附加到反转数组的“开始”(写入 array[0] 并将其余部分向上移动)

它仍然不是非阻塞的,可能不是最快的方式,但它现在可以工作。

这是解决方案,它还需要一个“maxLength”值,以保持所需的数组大小:)

int prependToReversedDoubleArray(  double &theArray[],
                                   double  value,
                                   int     maxLength
                                   )
{   int newSize = ArraySize( theArray ) + 1;
    ArraySetAsSeries( theArray, false );     // Normalize the array (left to right)
    ArrayResize(      theArray, newSize );   // Extend array length

    theArray[newSize-1] = value;             // Insert the new value

    ArraySetAsSeries( theArray, true );      // Reverse the array again

    if (  maxLength > 0
       && newSize   > maxLength )            // Check if the max length is reached
    {     newSize   = maxLength;
          ArrayResize( theArray, maxLength );
    }
    return( newSize );
}
于 2015-12-18T11:44:59.073 回答
0

这可以通过基于指针链接列表创建您自己的动态 Array 类来实现最佳性能。您可以定义自定义运算符[]来访问其元素,就像使用普通数组一样。这个类可以实现一个Prepend()非常快的方法,因为它只需要使用指针执行一些操作和一个内存分配。

但是,这样的类并不是一件简单的代码,因此根据您的目标,它可能不是您案例的最佳解决方案。

于 2018-06-21T15:19:31.343 回答