问题描述
我正在尝试创建 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]
检查动态数组,而无需先调整它的大小。与 FastDnPts
、SlowDnPts
和 SlowUpPts
相同。我相信那些是您的指标代码中的指标缓冲区,因此它们不需要任何调整大小。最好使用对指标的 iCustom()
调用来构建 EA,而不是重新构建指标代码以用作 EA。