MQL5绘制矩形报错:全局域不能放if语句及FVG区间绘制需求
问题解决:MQL4绘制FVG缺口矩形的代码修正
问题说明
尝试在FVG(Fair Value Gap)缺口位置绘制矩形,但代码报错不能在全局域中使用if语句,核心需求是:
- 当蜡烛3的低点高于蜡烛1的高点(向上缺口),或蜡烛3的高点低于蜡烛1的低点(向下缺口)时,在对应缺口区域绘制矩形
错误根源
- 代码结构违规:MQL4要求所有执行逻辑(如if判断、函数调用)必须封装在函数(如
OnTick()、OnCalculate())内部,原代码直接将执行逻辑放在全局域,触发语法错误 - 多余闭合大括号:原代码中
ObjectDelete(_Symbol,"Rectangle");后多了一个},破坏了代码结构完整性 - 变量类型错误:
Bull、Bear应为布尔类型(bool)而非double,且未定义为数组,导致无法访问多根K线的牛熊状态 - 逻辑与参数错误:
ArrayMaximum使用逻辑错误,无法正确获取缺口高低点;ObjectCreate参数格式错误,数组访问逻辑混乱
修正后的完整代码
//+------------------------------------------------------------------+ //| FVG_Rectangle.mq4 | //| Copyright 2024, MetaQuotes Software Corp. | //+------------------------------------------------------------------+ #property copyright "Copyright 2024, MetaQuotes Software Corp." #property version "1.00" #property strict // 全局变量仅用于声明,执行逻辑全部放入函数内 double Highs[]; double Lows[]; bool Bulls[]; bool Bears[]; MqlRates PriceData[]; //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { // 初始化数组,加载最近4根K线数据(索引0=当前K线,3=倒数第3根K线) int barsToLoad = 4; if(!ArrayResize(Highs, barsToLoad) || !ArrayResize(Lows, barsToLoad)) return; if(!ArrayResize(Bulls, barsToLoad) || !ArrayResize(Bears, barsToLoad)) return; if(!ArrayResize(PriceData, barsToLoad)) return; // 设置数组为倒序(最新K线在前) ArraySetAsSeries(Highs, true); ArraySetAsSeries(Lows, true); ArraySetAsSeries(Bulls, true); ArraySetAsSeries(Bears, true); ArraySetAsSeries(PriceData, true); // 复制K线数据到数组 if(CopyHigh(_Symbol, _Period, 0, barsToLoad, Highs) != barsToLoad) return; if(CopyLow(_Symbol, _Period, 0, barsToLoad, Lows) != barsToLoad) return; if(CopyRates(_Symbol, _Period, 0, barsToLoad, PriceData) != barsToLoad) return; // 标记每根K线的牛熊状态 for(int i=0; i<barsToLoad; i++) { Bulls[i] = PriceData[i].open < PriceData[i].close; Bears[i] = PriceData[i].open > PriceData[i].close; } // 删除之前绘制的矩形 ObjectDelete(_Symbol, "FVG_Rectangle"); // 情况1:向下缺口(蜡烛3为阴线,蜡烛2、1为阳线,且蜡烛3高点 < 蜡烛1低点) if(Bears[3] && Bulls[2] && Bulls[1] && Highs[3] < Lows[1]) { if(ObjectCreate(_Symbol, "FVG_Rectangle", OBJ_RECTANGLE, 0, PriceData[2].time, Highs[3], PriceData[0].time, Lows[1])) { ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_COLOR, clrLime); ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_FILL, true); ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_FILL_COLOR, clrLime); } } // 情况2:向上缺口(蜡烛3为阳线,蜡烛2、1为阴线,且蜡烛3低点 > 蜡烛1高点) if(Bulls[3] && Bears[2] && Bears[1] && Lows[3] > Highs[1]) { if(ObjectCreate(_Symbol, "FVG_Rectangle", OBJ_RECTANGLE, 0, PriceData[2].time, Highs[1], PriceData[0].time, Lows[3])) { ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_COLOR, clrRed); ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_FILL, true); ObjectSetInteger(_Symbol, "FVG_Rectangle", OBJPROP_FILL_COLOR, clrRed); } } } //+------------------------------------------------------------------+
关键修正细节
- 所有执行逻辑移入
OnTick()函数,符合MQL4代码结构规范 - 改用数组存储多根K线的高低点、牛熊状态,正确访问历史K线数据
- 调整缺口判断逻辑,准确对应蜡烛3和蜡烛1的价格关系
- 修正
ObjectCreate参数格式,确保矩形的时间范围和价格范围正确 - 添加数组初始化和数据复制的错误判断,提升代码稳定性
内容的提问来源于stack exchange,提问作者pebs
相关产品推荐
相关产品推荐

