使用 MQL4 的反向数组

Reversed array with MQL4

使用 MetaTrader 终端 ( MQL4 ), 我尝试一个反向数组,我附加(前置)项目到。

因此,在每个订单号上,myArray[0] 变为 'newest' 值,而之前的值变为 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 );
for( int i = arraylength - 1; i >= 1; i-- ) {
    value[i] = value[i-1];
    }
value[0] = newValue;

简介:

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

为什么?

MQL4 TimeSeries(反向)数组仅在当前 TimeFrame 的 aNewBarEVENT 上进行系统驱动的事件锁定单元格索引重新洗牌,而不是仅基于每个 anFxQuoteArrivalEVENT (正如在 O/P 中所要求的那样,在每次报价到达时移动/更新 [0] " ...,在每次报价时,")。


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

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

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

经过大约 100.000 多个引号后,数组增长到单个内存页面的大小将无法容纳整个数组 + 愚蠢的单元格移动的处理时间在 [ 中增长(线性) =16=],但是到了这样的尺度,开始破坏能力还是一样快终于可以等几个ms / us 下一个外汇市场事件以非阻塞模式到达,因此 MetaTrader 终端 内部架构失去了持有能力与外部事件虚假同步的错觉。

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

换句话说,这样的代码将启动 "missing" 事件 ( 将丢弃数据 ( 它在到达时永远不会看到,因为仍在单元格中洗牌数据-移动循环 ) ).


如何让它工作得又快又聪明?

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

1 ) 避免任何阻塞步骤。

2 ) 避免任何形式的愚蠢的单元格改组 - 如 value[i] = value[i-1];.

3 ) 避免任何ArrayResize()

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

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

这既是非阻塞(永远)也是快速智能limitless (如果您的算法交易需要).

感谢所有好的情报!我从解释中学到了很多:)

我遇到的问题是,如何将值附加到反向数组的 'beginning'(写入 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 );
}

为了获得最佳性能,可以根据指针链表创建自己的动态数组 class。您可以定义一个自定义运算符 [] 来访问它的元素,就像您对普通数组所做的那样。 class 可以实现一个非常快的 Prepend() 方法,因为它只需要执行一些指针操作和一次内存分配。

但是,这样的 class 编码起来并不简单,因此根据您的目标,它可能不是您案例的最佳解决方案。