【问题标题】:MQL4 How to make an array distinct?MQL4 如何使数组不同?
【发布时间】:2016-01-21 14:30:33
【问题描述】:

我需要将 MagicNumbers 挑选到一个数组中,然后使数组与众不同(有多个订单组,每个订单组都有唯一的 MagicNumbers)。但是有问题。我的代码是:

      int xxx = OrdersTotal();
      int magics[xxx];                               // here is an error:
                                                     //      invalid index value
      for ( int i = OrdersTotal() - 1; i >= 0; i-- ){

         if ( OrderSelect( i, SELECT_BY_POS ) ){

              magics[i] = OrderMagicNumber();        // choosing magics
              ArrayResize( magics,
                           ArraySize( magics ) + 1,
                           0
                           );
         }
      }

      ArraySort( magics );                           // making distinct
      int sorted[];
      int x = 0;
      for ( int i = 0; i < OrdersTotal() - 1; i++ ){ // duplicates = 0

         if ( magics[i] != magics[i+1] ){

              sorted[x] = magics[i];
              Print( "Sorted array: " + DoubleToStr( sorted[x] ) );
              x = x + 1;
         }
      }

如何将不同的 MagicNumbers 挑选到数组中?

【问题讨论】:

    标签: arrays mql4


    【解决方案1】:

    试试这个代码。它将创建一个数组,遍历历史选项卡中的所有订单,检查订单的 MagicNumber 是否存在于数组中。如果不存在,则将其添加到数组中。您将以一组独特的 MagicNumbers 结束。

    //+------------------------------------------------------------------+
    //|                                                  UniqueMagic.mq4 |
    //+------------------------------------------------------------------+
    #property copyright "Copyright 2016, joseph dot lee at fs dot com dot my"
    #property link      "https://www.facebook.com/joseph.fhlee"
    #property strict
    void OnTick() {
       int vaiMagicNumbers[];  //Array containing list of MagicNumbers
    
       //Loop through all the Orders (in History tab)
       for(int viIndex=OrdersTotal()-1; viIndex>=0; viIndex--) {
          if(OrderSelect(viIndex, SELECT_BY_POS, MODE_HISTORY) ){
             //Check if the selected Order (in History tab) already exists in the array
             if(  fniGetElementIndex( vaiMagicNumbers, OrderMagicNumber() ) == -1 ) {
                //If not exists, then increase the array by 1, and add the MagicNumber into the array
                ArrayResize(vaiMagicNumbers, ArrayRange(vaiMagicNumbers,0)+1);
                vaiMagicNumbers[ArrayRange(vaiMagicNumbers,0)-1] = OrderMagicNumber();
             }
          }
       };
       Comment( ArrayRange(vaiMagicNumbers,0) ); //Show the number of unique MagicNumbers in the History tab.
    }
    
    //Function to return the index (position) of viValue within a given array
    int fniGetElementIndex( int &vaiArray[], int viValue ) {
       int   viElementCount = ArrayRange(vaiArray, 0); //Get the total number of elements within that array.
       int   viFoundAt = -1;                           //The element index where viValue is found within the array.
    
       //Loop through every element in vaiArray
       for(int viElement=0; viElement<viElementCount; viElement++) {
          if( vaiArray[viElement] == viValue ) {
             //If the element value is the same as viValue, then FOUND, break the for loop.
             viFoundAt = viElement;
             break;
          }
       }
       return( viFoundAt );
    }
    

    【讨论】:

      【解决方案2】:

      MQL4 类似数组的对象和特殊数组函数的概念

      首先要说的是,MQL4 数组检测并不像第一眼看上去那么简单。


      是什么原因导致上面报错?

      数组大小的编译时声明(int xxx,取决于先验未知的OrdersTotal() 实际结果,它本身在运行时时期也是可变的),应通过以下任一方式解决
      数组的静态预分配,比如int magicsARRAY[10000];,它允许编译器预分配内存并在运行时决定正确的数组处理(可以实现自己的堆栈机制,而不是指向数组尾单元后面时溢出[Ref. Warning below])

      可以将数组声明为可变大小数组 只需 int magicsARRAY[]; 用于编译器阶段,并允许运行时根据需要使用上下文感知 ArrayResize(...); 功能重新分配实际大小。

      公平地说,高性能/低延迟代码中的良好实践应在运行期间避免和防止每次和每次内存重新分配-时间。


      接下来,关于家政服务,将MagNUMs 变成一个数组

      如果内存 (ArrayResize()) 重新分配在运行时开销很大,dbPOOL 体操的开销就越大OrderSelect() + 以下所有 OP)。

      请记住,您的 Expert Advisor 代码会被输入并执行当且仅当发生市场事件(价格刚搬家),在任何其他情况下都没有。所以你的代码是被动的,(为了响应价格变动)所以你不能在职责上多花一微秒,这是可以避免的。

      因此,专业代码将静态数组维护为MagNUM-hash-tables,以避免通过dbPOOL进行盲目重复。如果您经常运行 Strategy Tester,您一定已经知道,在优化批处理期间重新迭代 dbPOOL OP 的成本有多大,以及优化的速度有多快问题运行,如果你有零-dbPOOL OPs 在路上。

      因此,最好的方法是在交易头寸的整个生命周期中保持 MagNUM-s 不受 OrderSend() 实例化的影响,并使用数组函数而不是 OrderSelect() + OrderMagicNumber() 循环。


      数组在 MQL4 中可能非常有毒和危险

      如果尝试访问数组范围之外的单元格,执行子系统将产生严重错误,程序将停止。这是实时交易引擎永远不会遭受的!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-25
        • 2023-03-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多