MQL4如何使数组清晰?

时间:2016-01-21 14:30:33

标签: arrays mql4

我需要选择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选入数组?

2 个答案:

答案 0 :(得分:1)

数组相似对象和特殊数组函数的

MQL4概念

首先要说的是,MQL4阵列仪器并不像第一眼看上去那样微不足道。

导致上述错误的原因是什么?

数组大小的编译时声明(int xxx,取决于先验未知的OrdersTotal()实际结果,在运行时纪内本身也是可变的),应该被解决通过数组的静态预分配,比如int magicsARRAY[10000];,它允许编译器预先分配内存并在运行时决定正确的数组处理(可以实现一个人自己的堆栈机制不会溢出指向数组后面的单元格 [参考警告下面]

对于编译器阶段,可以仅为int magicsARRAY[]; 声明一个数组作为可变大小的数组,并允许运行时使用上下文感知的 {重新分配实际的大小调整按需提供{1}} 功能。

可以说,高性能/低延迟代码中的良好做法应避免&amp;防止每个&amp;在运行期间每次内存重新分配

接下来,在家政服务上,将ArrayResize(...);转换为数组

如果内存(MagNUM)重新分配在运行时很昂贵,那么所有ArrayResize()体操dbPOOL +以下所有OP)都越多

请记住,您的 EA交易 代码已输入并执行当且仅当出现市场事件时(价格已经过去)只是感动了),而不是在任何其他情况下。因此,您的代码是被动的(响应价格变动),因此您无法在职责上花费更多的时间,这是可以避免的。

因此,专业代码将静态数组维护为OrderSelect() - 哈希表,只是为了避免通过 MagNUM 进行盲目重复迭代。如果您经常运行 策略测试程序 ,您必须已经知道,在优化批处理过程中重新迭代dbPOOL OP的成本是多少以及速度有多快如果你有零{ - 1}} OP,你的优化问题就会运行。

因此,最好的方法是在整个交易周期的整个生命周期中保持MagNUM-s从dbPOOL实例化开始,并使用数组函数而不是dbPOOL + OrderSend()环路。

阵列可能非常有毒&amp;在MQL4中很危险

如果尝试访问阵列范围之外的单元格,执行子系统将生成严重错误,程序将停止。实时交易引擎永远不会受到影响!

答案 1 :(得分:0)

试试这段代码。它将创建一个数组,遍历History选项卡中的所有订单,检查数组中是否存在订单的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 );
}