欢迎访问 外汇EA下载与MT4/MT5自动交易资源 - 聚合外汇EA、黄金EA、量化交易工具与自动化交易实战内容。
登录 注册

有用的 #define 语句 - MetaTrader 5 脚本

author emer | 327 人阅读 | 0 人评论 |
// 蜡烛(将 g_rates 定义为:MqlRates g_rates[];)
#定义CANDLELOW(i)    g_rates[i].low#定义CANDLEHIGH(i)   g_rates[i].high#定义CANDLEOPEN(i)   g_rates[i].open#定义CANDLECLOSE(i)  g_rates[i].close#定义 CANDLETIME(i)   g_rates[i].time

此外,您可以像我下面那样使用 MqlTick 获取 ASK 和 BID 值,或者如果您愿意,也可以调用 SymbolInfoDouble(_Symbol,SYMBOL_ASK)。它对返回的值没有任何影响。

// 价格(将 g_tick 定义为:MqlTick g_tick;))
#定义询问             g_tick.ask#定义出价             g_tick.bid

最后,还为移动平均线、atr 或您需要的任何其他数组定义了数组。示例:要使用蜡烛 1 的平均真实波动范围,请使用 ATR(1)。
重要提示:假设数组是 AsSeries(例如, 数组集为系列(g_MA20_arr,真); )。这在后面显示的 #define 语句中至关重要。 

// 将这些数组定义为: double g_MA20_arr[];
// 移动平均线和 ATR
#定义MOVAVG20(i)     g_MA20_arr[i]#定义MOVAVG40(i)     g_MA40_arr[i]#定义MOVAVG50(i)     g_MA50_arr[i]#定义MOVAVG200(i)    g_MA200_arr[i]#定义ATR(i)          g_atr_arr[i]


一旦定义了上述语句,您就不需要更改任何其他内容。如果需要,还可以添加适合您的 EA 的其他 #define 语句。

蜡烛图具有在开发 EA 时非常有用的功能,特别是当 EA 基于价格行为时。以下定义的名称说明了它们所代表的含义。 WICK 指顶部蜡烛的阴影,TAIL 指底部蜡烛的阴影。示例:要获取最后一根蜡烛体中间的价格,请使用 CANDLEBODYMIDDLE(1)。

// 蜡烛特征
#定义烛体顶部(i)      最大频率(蜡烛开盘 (i),蜡烛收盘 (i))#定义蜡烛体机器人(i)      最小频率(蜡烛开盘 (i),蜡烛收盘 (i))#定义蜡烛中位数(i)       (0.5*(蜡烛高点(i)+蜡烛低点(i)))#定义烛光加权(i)     (0.25*(蜡烛高点(i)+蜡烛低点(i)+2*蜡烛关闭(i)))#定义蜡烛图典型(i)      (1./3.*(蜡烛高点(i)+蜡烛低点(i)+蜡烛收盘(i)))#定义烛体中(i)   (0.5*(CANDLEBODYTOP(i)+CANDLEBODYBOT(i)))#定义蜡烛大小(i)        (蜡烛高位(i)-蜡烛低位(i))#定义烛体尺寸(i)    晶圆厂(蜡烛收盘(i)-蜡烛开盘(i))#定义CANDLEWICKSIZE(i)    (CANDLEHIGH(i)-CANDLEBODYTOP(i))#定义CANDLETAILSIZE(i)    (CandlebodyBOT(i)-CANDLELOW(i))

此外,我们以 ATR 为参考定义了两种尺寸。示例:您想知道蜡烛 4 相对于 Atr 有多大,请使用 ATRCANDLESIZE(4)。

#定义ATRCANDLESIZE(i)      (蜡烛尺寸 (i)/ATR(i))#定义ATTR 蜡烛体尺寸 (i)  (蜡烛体尺寸 (i)/ATR(i))

此外,上涨的蜡烛(收盘价>开盘价)据说具有 +1 方向,而下跌的蜡烛则具有 -1 方向。如果收盘价==开盘价,则方向 = 0。 示例: if(CANDLEDIRECTION(10)==1) Print("蜡烛 10 是上涨蜡烛");

#定义蜡烛方向 (i)    (蜡烛收盘 (i)> 蜡烛开盘 (i)?1:(蜡烛收盘(i)<蜡烛开盘(i)?-10))

定义了两种类型的“运行”:向上和向下。 runUP 在上升蜡烛中定义为收盘低点,否则为 0。runDOWN 在下降蜡烛中定义为高收盘价,否则为 0; “运行”可用于捕捉价格在一个方向上的强劲变动。例如,要获取蜡烛 3 的启动,请使用 CANDLERUNUP(3)。

#定义CANDLERUNUP(i)        ((CANDLECLOSE(i)>KANDLEOPEN(i))?(CANDLECLOSE(i)-CANDLELOW(i)):0#定义CANDLERUNDOWN(i)      ((CANDLECLOSE(i)0)


蜡烛功能查询

这些定义是布尔变量,告诉我们一个或一组蜡烛的行为。他们使用之前的 #define 语句来缩短长度。

如果candle(i)方向等于dir,isCANDLERIGHTDIR(i,dir)将为真,否则为假;

有两种类型的分形:一种使用五个蜡烛,另一种(弱分形)使用三个蜡烛。在分形#definitions 中,蜡烛 (i) 下方是具有最高高点 (TOP) 或最低低点 (BOT) 的中间蜡烛。确保五蜡烛分形有蜡烛 i-2,i-1,i,i+1,i+2 的数据。还有其他使用严格不等式“">”或“<”以及使用“<=”或“">=”的变体。最后,还有#definitions 来识别顶部(TOP)或底部(BOT)分形。查看定义,您可以找出要使用哪个定义。

is3CANDLEGAPUP(i,gap,size) 用于查找向上缺口(其中一根蜡烛的最高价低于随后两根蜡烛的最低价)。 Candle(i) 将是相关三支蜡烛中最新的一支。再次假设蜡烛是“AsSeries”。 “缺口”是缺口的最小价格增量,“尺寸”是中间烛体尺寸的最小价格增量。

is3CANDLEGAPDOWN(i,gap,size) 用于使用相同的逻辑查找向下间隙。

is3CANDLEGAPUPTREND(i,​​gap,size) 与 is3CANDLEGAPUP(i,间隙,尺寸) 但添加一个附加条件为真:三根蜡烛中最早的一根必须为正方向。

有两种方法可以查询蜡烛是否为十字星:isCANDLEDOJIPOINTS(i,n) 和 isCANDLEDOJIFRACTION(i,f)。第一个版本使用 n*_Point,第二个版本使用 f*CANDLESIZE(i) 来确定蜡烛是否(真或假)是十字星。

示例:如果您想知道蜡烛 20 是否是非严格(使用等式)分形顶部,请使用 isCANDLEFRACTALEQTOP(20),输出将为 true 或 false。

正如您所看到的,定义是查询的压缩形式,使您的 EA 代码更短且更易于阅读。

// 蜡烛特征查询(布尔值)
#定义isCANDLEUP(i)               (CANDLEDIRECTION(i)==1#定义isCANDLEDOWN(i)             (CANDLEDIRECTION(i)==-1#定义isCANDLEFLAT(i)             (CANDLEDIRECTION(i)==0#定义isCANDLEWICKLESS(i)         (CANDLEWICKSIZE(i)==0#定义isCANDLETAILLESS(i)         (CANDLETAILSIZE(i)==0#定义isCANDLESOLID(i)            (CANDLEWICKSIZE(i)==0&& 烛尾尺寸(i)==0#定义isCANDLERIGHTDIR(i,dir)     (dir*(CANDLECLOSE(i) - CANDLOPEN(i))>0#定义isCANDLEFRACTALTOP(i)       (CANDLEHIGH(i) > CANDLEHIGH(i-1) && CANDLEHIGH(i-1) > 蜡烛高点(i-2) && CANDLEHIGH(i) > CANDLEHIGH(i+1) && 蜡烛高(i+1) > 蜡烛高点(i+2))#定义isCANDLEFRACTALBOT(i)       (CANDLELOW(i) < CANDLELOW(i-1) && 烛光(i-1) < 烛光(i-2) && CANDLELOW(i) < CANDLELOW(i+1) && 烛光(i+1) < 烛光(i+2))#定义isCANDLEFRACTALEQTOP(i)     (CANDLEHIGH(i) >= CANDLEHIGH(i-1) && CANDLEHIGH(i-1) >= CANDLEHIGH(i-2) && CANDLEHIGH(i) >= CANDLEHIGH(i+1) && 蜡烛高(i+1) >= 烛高 (i+2))#定义isCANDLEFRACTALEQBOT(i)     (CANDLELOW(i) <= CANDLELOW(i-1) && 烛光(i-1) <= CANDLELOW(i-2) && CANDLELOW(i) <= CANDLELOW(i+1) && 烛光(i+1) <= 烛光(i+2))#定义isCANDLEWEAKFRACTALTOP(i)   (CANDLEHIGH(i) > CANDLEHIGH(i-1) && CANDLEHIGH(i) > CANDLEHIGH(i+1))#定义isCANDLEWEAKFRACTALBOT(i)   (CANDLELOW(i) < CANDLELOW(i-1) && CANDLELOW(i) < CANDLELOW(i+1))#定义isCANDLEWEAKFRACTALQBOT(i) (CANDLELOW(i) <= CANDLELOW(i-)1) && CANDLELOW(i) <= CANDLELOW(i+1))#定义isCANDLEWEAKFRACTALQTOP(i) (CANDLEHIGH(i) >= CANDLEHIGH(i-1) && CANDLEHIGH(i) >= CANDLEHIGH(i+1))#定义is3CANDLEGAPUP(i,gap,size)  (CANDLELOW(i)-CANDLEHIGH(i+2)>缺口 && CANDLEBODYSIZE(i+1)>=尺寸)#定义is3CANDLEGAPDOWN(i,间隙,尺寸) (CANDLELOW(i+2)-CANDLEHIGH(i)>gap && CANDLEBODYSIZE(i+1)>=尺寸)#定义is3CANDLEGAPUPTREND(i,​​gap,size)  (CANDLELOW(i)-CANDLEHIGH(i+2)>缺口 && CANDLEBODYSIZE(i+1)>=尺寸 && isCANDLEUP(i+2))#定义is3CANDLEGAPDOWNTREND(i,​​缺口,大小) (CANDLELOW(i+2)-CANDLEHIGH(i)>gap && CANDLEBODYSIZE(i+1)>=尺寸 && isCANDLEDOWN(i+2))#定义isCANDLEDOJIPOINTS(i,n)     (CANDLEBODYSIZE(i) <= n*_观点#定义isCANDLEDOJIFRACTION(i,f)   (CANDLEBODYSIZE(i) <= f*CANDLESIZE(i))


我们现在定义一些在 EA 中有用的数学函数和运算。其中一些是专门针对我开发的 EA 的,但如果您愿意,您可以更改或删除它们。

BRACKET(x,minV,maxV) 将返回区间 [minV,maxV] 内的 x 值。这对于 EA 中的框约束输入变量很有用。

CONVEXCOMB(a,x1,x2) 是 x1 和 x2 的凸组合,即 a*x1+x2。当计算 x1 和 x2 之间的中间值时,此函数非常有用,但您需要的不仅仅是平均值 (a=0.5)。

EVALLINE(x,x1,y1,x2,y2,ymin,ymax) 是对由两点 [x1,y1] 和 [x2,y2] 定义的直线的评估。一旦在 x 处求值,它就会返回 [ymin, ymax] 内的括号内的值。 

MAPAB11(x,A,B) 将值 x 从括号 [A,B] 映射到括号 [-1,1]。 MAP11AB(x,A,B) 将值 x 从括号 [-1,1] 映射到括号 [A,B]。这两个函数对于处理 [-1,1] 范围内的标准化变量非常有用。

最后四个函数在我的 EA 中使用,可能不一定对每个人都有用,但我将它们留在那里,以防万一。

#定义括号(x,minV,maxV)                 (xmaxV?maxV:x))#定义凸梳(a,x1,x2)                  (a*x1+(1.0-a)*x2)#定义EVALLINE(x,x1,y1,x2,y2,ymin,ymax)    括号((y2-y1)/(x2-x1)*(x-x1)+y1,ymin,ymax)#定义MAPAB11(x,A,B)                       (2./(B-A)*(括号(x,A,B)-A)-1.)#定义MAP11AB(x,A,B)                   ((B-A)/2.*(括号(x,-1,1)-1)+B)#定义SIGMOID(x,a)                         (1.0/(1.0+经验值(-斧头)))#定义NN1(x,w,b)                          (w*x+b)#定义EVALPOLY(X,X0,X1,Y0,Y1,EX,ymin,ymax) 支架(Y1*战俘((X-X0)/(X1-X0),EX)+Y0,ymin,ymax)#定义EVALPOLY2P(X,X0,X1,Y0,Y1,EX,ymn,ymx) 支架((Y1-Y0)*战俘((X-X0)/(X1-X0),EX)+Y0,ymn,ymx)


此外,作为函数和运算,还存在差异的计算(作为斜率的代理)。 

MA20DIFF(i,n) 给出由 n 个蜡烛分隔的 20 周期移动平均线的两个值之间的差值。其余功能遵循相同的逻辑。示例:要计算第 3 根蜡烛和第 13 根蜡烛的 200 周期移动平均线之间的差异,请使用 MA200DIFF(3,10)。

#定义MA20DIFF(i,n)                        (MOVAVG20(i)-MOVAVG20(i+n))#定义MA40DIFF(i,n)                        (MOVAVG40(i)-MOVAVG40(i+n))#定义MA50DIFF(i,n)                        (MOVAVG50(i)-MOVAVG50(i+n))#定义MA200DIFF(i,n)                       (MOVAVG200(i)-MOVAVG200(i+n))#定义CANDLECLOSEDIFF(i,n)                 (CANDLECLOSE(i)-CANDLECLOSE(i+n))#定义CANDLEOPENDIFF(i,n)                  (KANDLEOPEN(i)-KANDLEOPEN(i+n))#定义CANDLEHIGHDIFF(i,n)                  (CANDLEHIGH(i)-CANDLEHIGH(i+n))#定义CANDLELOWDIFF(i,n)                   (CANDLELOW(i)-CANDLELOW(i+n))#定义CANDLEMEDIANDIFF(i,n)                (CANDLEMEDIAN(i)-CANDLEMEDIAN(i+n))#定义蜡烛加权DIFF(i,n)              (蜡烛加权(i)-蜡烛加权(i+n))#定义CANDLETYPICALDIFF(i,n)               (CANDLETYPICAL(i)-CANDLETYPICAL(i+n))#定义CANDLEBODYMIDDLEDIF(i,n)            (CANDLEBODYMIDDLE(i)-CANDLEBODYMIDDLE(i+n))

 查询也包含在数学函数中。下面检查包围和凸度。

#定义isINBRACKET(x,minV,maxV)             (x<=最大V && x>=最小V)#定义isINBRACKETSTRICT(x,minV,maxV)       (x<最大电压&& x>最小V)#定义isOUTBRACKET(x,minV,maxV)            (x>=maxV || x<=最小V)#定义isOUTBRACKETSTRICT(x,minV,maxV)      (x>最大V || x<最小V)#定义isCONVEX(yl,yc,yr)                   (yl>=yc && yc<=年)#定义isCONCAVE(yl,yc,yr)                  (yl<=yc && yc>=年)#定义isCONVEXTSTRICT(yl,yc,yr)            (yl>yc && yc<#定义isCONCAVESTRICT(yl,yc,yr)            (yl年)


常数

我定义了一些我使用的常量。使用它们是您的选择。

// 常量
#定义PIVALUE                              (M_PI#定义MINSTOPINTS                        (30#定义最小冻结点                      (30#定义停止级别                            (最大频率(MINSTOPINTS,(双倍的符号信息整数_象征,SYMBOL_TRADE_STOPS_LEVEL))*_观点#定义冻结级别                          (最大频率(最小冻结点,(双倍的符号信息整数_象征,SYMBOL_TRADE_FREEZE_LEVEL))*_观点


任何经验丰富的程序员都知道调试代码的最佳工具是 Print 语句。以下定义允许在整个程序中设置 Print 语句,并根据您感兴趣的调试级别的值打开/关闭它们。

首先,您需要使用#define DEBUG_LEVEL0 定义调试级别, #定义DEBUG_LEVEL1,  或者 #定义DEBUG_LEVEL2。使用时 DEBUG_LEVEL0,Metatrader 5 终端的 Journal 选项卡上不会有打印。和 DEBUG_LEVEL1,只有 PRINTVARn 语句将处于活动状态并将打印在“日志”选项卡上。和 DEBUG_LEVEL2,两者,打印自变量和 VPRINT自变量报表将打印在日记帐选项卡上。这 DEBUG_LEVEL2 是使用 VPRINT 的“V”erbose 情况VARn

PRINTVARn 将打印 n 个变量。例如,如果要打印 i、x 和 z,请使用 PRINTVAR3(i,x,z);要打印字符串,请使用 PRINTTEXT("any string");打印输出将包括函数名称和插入 PRINTVARn 语句的文件的行号。

// 使用打印进行调试
// 在代码开头将调试级别 x={0,1,2} 定义为:#define DEBUG_LEVELx      
#ifdef调试_LEVEL0#定义打印文本(文本)#定义打印变量(x1)#定义打印变量1(x1)#定义PRINTVAR2(x1,x2)#定义PRINTVAR3(x1,x2,x3)#定义PRINTVAR4(x1,x2,x3,x4)#定义PRINTVAR5(x1,x2,x3,x4,x5)#定义PRINTVAR6(x1,x2,x3,x4,x5,x6)#定义VPRINTTEXT(文本)#定义VPRINTVAR(x1)#定义VPRINTVAR1(x1)#定义VPRINTVAR2(x1,x2)#定义VPRINTVAR3(x1,x2,x3)#定义VPRINTVAR4(x1,x2,x3,x4)#定义VPRINTVAR5(x1,x2,x3,x4,x5)#定义VPRINTVAR6(x1,x2,x3,x4,x5,x6)#endif
                                                                                                #ifdef调试_级别1#定义打印文本(文本)          打印“*/*/*/*”,__功能__,“(”,__线__,”):“,文本)#定义打印变量(x1)              打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义打印变量1(x1)            打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义PRINTVAR2(x1,x2)          打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2))#定义PRINTVAR3(x1,x2,x3)      打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3))#定义PRINTVAR4(x1,x2,x3,x4)    打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4))#定义PRINTVAR5(x1,x2,x3,x4,x5)打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5))#定义PRINTVAR6(x1,x2,x3,x4,x5,x6)打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5),“,” #x6+”=, (x6))#定义VPRINTTEXT(文本)#定义VPRINTVAR(x1)#定义VPRINTVAR1(x1)#定义VPRINTVAR2(x1,x2)#定义VPRINTVAR3(x1,x2,x3)#定义VPRINTVAR4(x1,x2,x3,x4)#定义VPRINTVAR5(x1,x2,x3,x4,x5)#定义VPRINTVAR6(x1,x2,x3,x4,x5,x6)#endif#ifdef  调试_级别2#定义打印文本(文本)          打印“*/*/*/*”,__功能__,“(”,__线__,”):“,文本)#定义打印变量(x1)              打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义打印变量1(x1)            打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义PRINTVAR2(x1,x2)          打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2))#定义PRINTVAR3(x1,x2,x3)      打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3))#定义PRINTVAR4(x1,x2,x3,x4)    打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4))#定义PRINTVAR5(x1,x2,x3,x4,x5)打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5))#定义PRINTVAR6(x1,x2,x3,x4,x5,x6)打印“*/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5),“,” #x6+”=, (x6))#定义VPRINTTEXT(文本)          打印“V/*/*/*”,__功能__,“(”,__线__,”):“,文本)#定义VPRINTVAR(x1)              打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义VPRINTVAR1(x1)            打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1))#定义VPRINTVAR2(x1,x2)          打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2))#定义VPRINTVAR3(x1,x2,x3)      打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3))#定义VPRINTVAR4(x1,x2,x3,x4)    打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4))#定义VPRINTVAR5(x1,x2,x3,x4,x5)打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5))#定义VPRINTVAR6(x1,x2,x3,x4,x5,x6)打印“V/*/*/*”,__功能__,“(”,__线__,”):“,#x1+”=, (x1),“,” #x2+”=, (x2),“,” #x3+”=, (x3),“,” #x4+”=, (x4),“,” #x5+”=, (x5),“,” #x6+”=, (x6))#endif



附件下载

📎 define_statements.mqh (21.46 KB)

📎 tester4define.mq5 (1.47 KB)

Source: MQL5 #56149

🔐
请登录后参与评论
注册满12小时后评论,即可解锁附件下载
立即登录