我正在尝试创建 EA(MQL4) 并且出现严重错误数组超出范围的 EA 错误

问题描述

我正在尝试创建 EA(MQL4) 并且出现了 EA 错误中的严重错误数组超出范围。事实上,我正在尝试将指标转变为专家。我以前做过这个。但是在这种情况下,我遇到了标题错误添加void FindZones()后出现这个问题。这部分代码在指标中正常工作。我想我在重写代码时犯了一个错误,我没有意识到这一点。

extern double zone_fuzzfactor = 0.75;
extern bool zone_merge = true;
extern bool zone_extend = true;

double zone_hi[1000],zone_lo[1000];
double FastDnPts[],FastUpPts[];
double SlowDnPts[],SlowUpPts[];
bool ExpertLock = false; // قفل روی اکانت و زمان
bool zone_turn[1000];
int BackLimit = 1000;
int TimeFrame = 0; // تایم فریم
int time_offset = 0; // بررسی کندل جدید
int zone_count = 0; // شمارنده منطقه ها
int zone_start[1000],zone_hits[1000],zone_type[1000],zone_strength[1000];

#define ZONE_SUPPORT 1
#define ZONE_RESIST  2

#define ZONE_WEAK      0
#define ZONE_TURNCOAT  1
#define ZONE_UNTESTED  2
#define ZONE_VERIFIED  3
#define ZONE_PROVEN    4

int OnInit()
  {
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   DeleteZones();
  }

void OnTick()
   {

   datetime TrialEndDate = D'02.02.2021'; // تاریخ انقضای اکسپرت
   if(TimeCurrent() > TrialEndDate)
      {
       Alert("ORT - Your 3-month time credit has expired | اعتبار 3 ماهه شما منقضی شده است"); 
       ExpertLock = true;
      }
   int AcctNbr = 10031782; // شماره اکانتی ک اکسپرت روی اون قفل میشه
   if(AcctNbr != AccountNumber())
      {
       Alert("ORT - This account is not allowed to use | این حساب مجاز به استفاده نمی باشد"); 
       ExpertLock = true;
      }

   if (NewBar() == true && ExpertLock !=true)
      {
       int old_zone_count = zone_count;
       DeleteZones();
       FindZones();
      }

   }

bool NewBar()
   {
   static datetime LastTime = 0;
   if (iTime(NULL,TimeFrame,0) != LastTime)
      {
       LastTime = iTime(NULL,0)+time_offset;
       return (true);
      }
   else
       return (false);
      }

void DeleteZones()
   {
    int len = 5;
    int i = 0;

    while (i < ObjectsTotal())
      {
       string objName = ObjectName(i);
       if (StringSubstr(objName,len) != "SSSR#")
      {
       i++;
       continue;
      }
       ObjectDelete(objName);
      }
   }
//---------------------------------------------------------------------------------------------------
// فانکشن محدوده های مقاومت و حمایت
//---------------------------------------------------------------------------------------------------
void FindZones()
{
   int i,j,shift,bustcount = 0,testcount = 0;
   double hival,loval;
   bool turned = false,hasturned = false;

   double temp_hi[1000],temp_lo[1000];
   int    temp_start[1000],temp_hits[1000],temp_strength[1000],temp_count = 0;
   bool   temp_turn[1000],temp_merge[1000];
   int merge1[1000],merge2[1000],merge_count = 0;

   // iterate through zones from oldest to youngest (ignore recent 5 bars),// finding those that have survived through to the present...
   for (shift = MathMin(iBars(NULL,TimeFrame)-1,BackLimit); shift>5; shift--)
   {
      double atr = iATR(NULL,7,shift);
      double fu = atr/2 * zone_fuzzfactor;
      bool isWeak;
      bool touchOk = false;
      bool isBust = false;
      double close = iClose(NULL,shift);
      double high  = iHigh(NULL,shift);
      double low   = iLow(NULL,shift);
      double hi_i;
      double lo_i;

      if (FastUpPts[shift] > 0.001)
      {
         // a zigzag high point
         isWeak = true;
         if (SlowUpPts[shift] > 0.001)
            isWeak = false;

         hival = high;
         if (zone_extend == true)
            hival += fu;

         loval = MathMax(MathMin(close,high-fu),high-fu*2);
         turned = false;
         hasturned = false;
         isBust = false;

         bustcount = 0;
         testcount = 0;

         for (i=shift-1; i>=0; i--)
         {
            hi_i = iHigh(NULL,i);
            lo_i = iLow(NULL,i);

            if ((turned == false && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||
                (turned == true && FastDnPts[i] <= hival && FastDnPts[i] >= loval))
            {
               // Potential touch,just make sure its been 10+candles since the prev one
               touchOk = true;
               for (j=i+1; j<i+11; j++)
               {
                  if ((turned == false && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||
                      (turned == true && FastDnPts[j] <= hival && FastDnPts[j] >= loval))
                  {
                     touchOk = false;
                     break;
                  }
               }

               if (touchOk == true)
               {
                  // we have a touch.  If its been busted once,remove bustcount
                  // as we kNow this level is still valid & has just switched sides
                  bustcount = 0;
                  testcount++;
               }
            }

            if ((turned == false && hi_i > hival) ||
                (turned == true && lo_i < loval))
            {
               // this level has been busted at least once
               bustcount++;

               if (bustcount > 1 || isWeak == true)
               {
                  // busted twice or more
                  isBust = true;
                  break;
               }

               if (turned == true)
                  turned = false;
               else if (turned == false)
                  turned = true;

               hasturned = true;

               // forget prevIoUs hits
               testcount = 0;
            }
         }

         if (isBust == false)
         {
            // level is still valid,add to our list
            temp_hi[temp_count] = hival;
            temp_lo[temp_count] = loval;
            temp_turn[temp_count] = hasturned;
            temp_hits[temp_count] = testcount;
            temp_start[temp_count] = shift;
            temp_merge[temp_count] = false;
            
            if (testcount > 3)
               temp_strength[temp_count] = ZONE_PROVEN;
            else if (testcount > 0)
               temp_strength[temp_count] = ZONE_VERIFIED;
            else if (hasturned == true)
               temp_strength[temp_count] = ZONE_TURNCOAT;
            else if (isWeak == false)
               temp_strength[temp_count] = ZONE_UNTESTED;
            else
               temp_strength[temp_count] = ZONE_WEAK;

            temp_count++;
         }
      }
      else if (FastDnPts[shift] > 0.001)
      {
         // a zigzag low point
         isWeak = true;
         if (SlowDnPts[shift] > 0.001)
            isWeak = false;

         loval = low;
         if (zone_extend == true)
            loval -= fu;

         hival = MathMin(MathMax(close,low+fu),low+fu*2);
         turned = false;
         hasturned = false;

         bustcount = 0;
         testcount = 0;
         isBust = false;

         for (i=shift-1; i>=0; i--)
         {
            hi_i = iHigh(NULL,i);

            if ((turned == true && FastUpPts[i] >= loval && FastUpPts[i] <= hival) ||
                (turned == false && FastDnPts[i] <= hival && FastDnPts[i] >= loval))
            {
               // Potential touch,just make sure its been 10+candles since the prev one
               touchOk = true;
               for (j=i+1; j<i+11; j++)
               {
                  if ((turned == true && FastUpPts[j] >= loval && FastUpPts[j] <= hival) ||
                      (turned == false && FastDnPts[j] <= hival && FastDnPts[j] >= loval))
                  {
                     touchOk = false;
                     break;
                  }
               }

               if (touchOk == true)
               {
                  // we have a touch.  If its been busted once,remove bustcount
                  // as we kNow this level is still valid & has just switched sides
                  bustcount = 0;
                  testcount++;
               }
            }

            if ((turned == true && hi_i > hival) ||
                (turned == false && lo_i < loval))
            {
               // this level has been busted at least once
               bustcount++;

               if (bustcount > 1 || isWeak == true)
               {
                  // busted twice or more
                  isBust = true;
                  break;
               }

               if (turned == true)
                  turned = false;
               else if (turned == false)
                  turned = true;

               hasturned = true;

               // forget prevIoUs hits
               testcount = 0;
            }
         }

         if (isBust == false)
         {
            // level is still valid,add to our list
            temp_hi[temp_count] = hival;
            temp_lo[temp_count] = loval;
            temp_turn[temp_count] = hasturned;
            temp_hits[temp_count] = testcount;
            temp_start[temp_count] = shift;
            temp_merge[temp_count] = false;

            if (testcount > 3)
               temp_strength[temp_count] = ZONE_PROVEN;
            else if (testcount > 0)
               temp_strength[temp_count] = ZONE_VERIFIED;
            else if (hasturned == true)
               temp_strength[temp_count] = ZONE_TURNCOAT;
            else if (isWeak == false)
               temp_strength[temp_count] = ZONE_UNTESTED;
            else
               temp_strength[temp_count] = ZONE_WEAK;

            temp_count++;
         }
      }
   }

   // look for overlapping zones...
   if (zone_merge == true)
   {
      merge_count = 1;
      int iterations = 0;
      while (merge_count > 0 && iterations < 3)
      {
         merge_count = 0;
         iterations++;

         for (i = 0; i < temp_count; i++)
            temp_merge[i] = false;

         for (i = 0; i < temp_count-1; i++)
         {
            if (temp_hits[i] == -1 || temp_merge[j] == true)
               continue;

            for (j = i+1; j < temp_count; j++)
            {
               if (temp_hits[j] == -1 || temp_merge[j] == true)
                  continue;

               if ((temp_hi[i] >= temp_lo[j] && temp_hi[i] <= temp_hi[j]) ||
                   (temp_lo[i] <= temp_hi[j] && temp_lo[i] >= temp_lo[j]) ||
                   (temp_hi[j] >= temp_lo[i] && temp_hi[j] <= temp_hi[i]) ||
                   (temp_lo[j] <= temp_hi[i] && temp_lo[j] >= temp_lo[i]))
               {
                  merge1[merge_count] = i;
                  merge2[merge_count] = j;
                  temp_merge[i] = true;
                  temp_merge[j] = true;
                  merge_count++;
               }
            }
         }

         // ... and merge them ...
         for (i=0; i<merge_count; i++)
         {
            int target = merge1[i];
            int source = merge2[i];

            temp_hi[target] = MathMax(temp_hi[target],temp_hi[source]);
            temp_lo[target] = MathMin(temp_lo[target],temp_lo[source]);
            temp_hits[target] += temp_hits[source];
            temp_start[target] = MathMax(temp_start[target],temp_start[source]);
            temp_strength[target] = MathMax(temp_strength[target],temp_strength[source]);
            if (temp_hits[target] > 3)
               temp_strength[target] = ZONE_PROVEN;

            if (temp_hits[target] == 0 && temp_turn[target] == false)
            {
               temp_hits[target] = 1;
               if (temp_strength[target] < ZONE_VERIFIED)
                  temp_strength[target] = ZONE_VERIFIED;
            }

            if (temp_turn[target] == false || temp_turn[source] == false)
               temp_turn[target] = false;
            if (temp_turn[target] == true)
               temp_hits[target] = 0;

            temp_hits[source] = -1;
         }
      }
   }

   // copy the remaining list into our official zones arrays
   zone_count = 0;
   for (i=0; i<temp_count; i++)
   {
      if (temp_hits[i] >= 0 && zone_count < 1000)
      {
         zone_hi[zone_count]       = temp_hi[i];
         zone_lo[zone_count]       = temp_lo[i];
         zone_hits[zone_count]     = temp_hits[i];
         zone_turn[zone_count]     = temp_turn[i];
         zone_start[zone_count]    = temp_start[i];
         zone_strength[zone_count] = temp_strength[i];
         
         if (zone_hi[zone_count] < Close[4])
            zone_type[zone_count] = ZONE_SUPPORT;
         else if (zone_lo[zone_count] > Close[4])
            zone_type[zone_count] = ZONE_RESIST;
         else
         {
            for (j=5; j<1000; j++)
            {
               if (iClose(NULL,j) < zone_lo[zone_count])
               {
                  zone_type[zone_count] = ZONE_RESIST;
                  break;
               }
               else if (iClose(NULL,j) > zone_hi[zone_count])
               {
                  zone_type[zone_count] = ZONE_SUPPORT;
                  break;
               }
            }

            if (j == 1000)
               zone_type[zone_count] = ZONE_SUPPORT;
         }

         zone_count++;
      }
   }
}

解决方法

您通过 FastUpPts[shift] 检查动态数组,而无需先调整它的大小。与 FastDnPtsSlowDnPtsSlowUpPts 相同。我相信那些是您的指标代码中的指标缓冲区,因此它们不需要任何调整大小。最好使用对指标的 iCustom() 调用来构建 EA,而不是重新构建指标代码以用作 EA。