外汇智能EA交易示例教程

交易原理:

对于做多(BUY)入场,当MACD指标位于零轴下方时,自下而上并穿越低端信号线,可作为参考信号。

外汇智能EA交易示例

对于做空(SELL)入场,当MACD指标位于零轴上方时,自上而下并穿越顶端信号线,同样可作为参考信号。

外汇智能EA交易示例

止盈上限的触发,可结合追踪止损的执行,或当价格穿越MACD信号线(MACD指标位于零轴上方,自上而下穿越顶端信号线)时考虑平仓。

同样,止盈上限的触发,也可结合追踪止损的执行,或当价格穿越MACD信号线(MACD指标位于零轴下方,自下而上穿越低端信号线)时考虑平仓。

重要提示:为排除MACD指标中微不足道的变化(图表上呈现的小‘山丘’形态),我们引入一种补充检测‘山丘’大小的方法。具体来说,指标的大小应参考最低价的最后5个单元(即5*Point,例如USD/CHF为0.0005,USD/JPY为0.05)。

步骤 1 – 编写智能交易的描述

外汇智能EA交易示例

步骤 2 – 创建程序的基本结构

测试智能交易的源代码虽然占用篇幅不大,但其中有些内容可能不易理解,尤其对非专业程序编写者而言。当然,这些描述并非绝对必要,但为了清晰起见,我们仍会进行说明。

一个标准智能交易的结构构想,可参考以下几部分描述:

1、初始变量

所有在智能交易程序中使用的变量,需按照MetaQuotes Language 4的规范进行指定。因此,我们在程序开头插入初始变量。

extern double TakeProfit = 50; extern double Lots = 0.1; extern double TrailingStop = 30; extern double MACDOpenLevel=3; extern double MACDCloseLevel=2; extern double MATrendPeriod=26; 在MetaQuotes语言4中,需要借助“外部变量”来增强灵活性。外部变量可以在程序外部设定,而在源代码中设定后则不可修改。在我们的程序中,MATrendPeriod变量即为外部变量,并在程序开始时插入。extern double MATrendPeriod=26;

2、初始数据检测

检测图表及图表中的柱数。

检测外部变量值,包括标准手数、止损、止盈和追踪止损。

3、为快速数据通道设置内部变量

4、检测交易终端状态,若处于非活动状态,则:

检测账户上的可用保证金等。

是否可开设看涨仓位(BUY)?若可以,则开设并退出。

是否可开设卖空仓位(SELL)?若可以,则开设并退出。

随后退出智能交易。

5、周期循环检验先前开仓

若是看涨仓位,考虑是否应平仓或重新设定追踪止损。

若是卖空仓位,同样考虑是否应平仓或重新设定追踪止损。

整体流程可归纳为四种情况。

现在,让我们尝试一步一步地完成上述计划:

这样,我们就能够逐步编写智能交易了。

初始变量部分,所有在智能交易程序中使用的变量需按MetaQuotes Language 4规范指定,故在程序开头插入。例如:extern double TakeProfit = 50; extern double Lots = 0.1; extern double TrailingStop = 30; extern double MACDOpenLevel=3; extern double MACDCloseLevel=2; extern double MATrendPeriod=26; 在MetaQuotes语言4中,常借助“外部变量”来增加灵活性,这些变量可在程序外部设定,源代码中设定后不可修改。我们的程序中,MATrendPeriod作为外部变量,在程序开始时插入。extern double MATrendPeriod=26;

检测初始数据,这段代码通常适用于所有智能交易,属于标准检测流程:

// 初始数据检测 // 确认智能交易运行正常非常重要 // 图表和用户设置应无错误 // 变量(Lots、StopLoss、TakeProfit、TrailingStop)需检测,这里我们关注TakeProfit // 若图表中柱数少于100 if(Bars<100) { Print("少于100柱"); return(0); } if(TakeProfit<10) { Print("赢利少于10"); return(0); // 检测TakeProfit }

对于数据的快速通道,需经常关注指标值或计算值,为简化代码,可将数据存入内部变量。int start() { double MacdCurrent, MacdPrevious, SignalCurrent; double SignalPrevious, MaCurrent, MaPrevious; int cnt, ticket, total; // 简化代码 // 数据放置在内部变量中 MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1); 现在,我们可以使用MacdCurrent代替iMACD(...)调用。

检测交易终端状态,若为空,则:在我们的智能交易中,仅使用开单和挂单操作。但为更安全,需对先前订单进行检测:total=OrdersTotal(); if(total<1) {return(0); }

检测账户上的可用保证金:在分析市场状况前,需确认可用保证金是否足够开仓。if(AccountFreeMargin()<(1000*Lots)) { Print("没有资金.自由保证金 = ", AccountFreeMargin()); return(0); }

是否可开设看涨仓位(BUY)?进入看涨仓位的条件:MACD低于零,向上穿过信号线。在MQL4中描述如下(注意指标值已存于变量中):

// 检测看涨仓位 (BUY) if(MacdCurrent<0 && MacdCurrentSignalCurrent && MacdPrevious MathAbs(MacdCurrent)(MACDOpenLevel*Point) && MaCurrentMaPrevious) { ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,3,0,Ask+TakeProfit*PLMAX外汇平台oint, "macd sample",16384,0,Green); if(ticket0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("BUY 开单 : ",OrderOpenPrice()); } else Print("错误 opening BUY order : ",GetLastError()); return(0); }

附加的‘山丘’大小检验:上述已有描述,MACDOpenLevel变量由用户指定,它无需改动程序文本即可调整,增加了灵活性。我们在程序开始插入此变量的描述。

是否可开设卖空仓位(SELL)?进入卖空仓位的条件:MACD高于零,向下穿过信号线。注释如下:

// 检测卖空仓位 (SELL) if(MacdCurrent0 && MacdCurrentSignalPrevious && MacdCurrent(MACDOpenLevel*Point)&& MaCurrent { ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,3,0,Bid-TakeProfit*Point, "macd sample",16384,0,Red); if(ticket0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) Print("SELL 开单 : ",OrderOpenPrice()); } else Print("错误SELL定单开仓 : ",GetLastError()); return(0); }

周期循环检验先前开仓:// 进入市场非常重要,但安全退出更关键... for(cnt=0;cnt { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderType()<=OP_SELL && // 检测开仓 OrderSymbol()==Symbol()) // 检测货币对 { “cnt”是循环变量,需在程序开始指定:int cnt = 0;

若是看涨仓位,则:if(OrderType()==OP_BUY) // 打开看涨仓位 { 我们停止操作符。}

是否需要平仓?退出看涨仓位的条件:MACD穿过信号线,MACD高于零并向下穿过信号线。if(MacdCurrent0 && MacdCurrentSignalPrevious && MacdCurrent(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Bid,3,Violet); //平仓 return(0); //退出 }

是否需要重设追踪止损?我们设定追踪止损只有在仓位盈利超过追踪水平点,且新止损水平优于先前水平时才进行。// 检测追踪止损 if(TrailingStop0) { if(Bid-OrderOpenPrice()Point*TrailingStop) { if(OrderStopLoss() { OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*TrailingStop, OrderTakeProfit(),0,Green); return(0); } } }

若是卖空仓位,则:else //卖空仓位 { 关闭所有残留开仓。} } } return(0); }

是否需要平仓?退出卖空仓位的条件:MACD穿过信号线,MACD低于零并向上穿过信号线。if(MacdCurrent<0 && MacdCurrentSignalCurrent && MacdPrevious(MACDCloseLevel*Point)) { OrderClose(OrderTicket(),OrderLots(),Ask,3,Violet); //平仓 return(0); // 退出 }

是否需要重设追踪止损?同样,只有仓位盈利超过追踪水平点且新止损更优时才执行。// 检测追踪止损 if(TrailingStop0) { if((OrderOpenPrice()-Ask)(Point*TrailingStop)) { if((OrderStopLoss()(Ask+Point*TrailingStop)) || (OrderStopLoss()==0)) { OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*TrailingStop, OrderTakeProfit(),0,Red); return(0); } } }

这样,我们就逐步编写了智能交易。步骤3 – 集中程序的结果代码

接下来,打开智能交易的设定:使用按钮打开“属性…”菜单,在窗口内指定运行参数的外部设定。

外汇智能EA交易示例

从先前部分集中全部代码,最终代码如下:

//+------------------------------------------------------------------+ //| MACD Sample.mq4 | //| Copyright © 2005, MetaQuotes Software Corp. | //+------------------------------------------------------------------+ extern double TakeProfit = 50; extern double Lots = 0.1; extern double TrailingStop = 30; extern double MACDOpenLevel=3; extern double MACDCloseLevel=2; extern double MATrendPeriod=26; //+------------------------------------------------------------------+ //| | //+------------------------------------------------------------------+ int start() { double MacdCurrent, MacdPrevious, SignalCurrent; double SignalPrevious, MaCurrent, MaPrevious; int cnt, ticket, total; // 检测初始化数据 // 确定智能交易在图表中运行正常非常重要 // 用户在外部变量交易中不会产生任何错误 // 外部变量 (标准手数, 止损,赢利, // 追踪止损) 在这种情况下,我们检测图表中赢利水平要小于100 柱 if(Bars<100) { Print("少于 100柱"); return(0); } if(TakeProfit<10) { Print("赢利少于10"); return(0); // 检测赢利水平 } // 简化代码和加速通道 // 数据被放置在内部变量中 MacdCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,0); MacdPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_MAIN,1); SignalCurrent=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,0); SignalPrevious=iMACD(NULL,0,12,26,9,PRICE_CLOSE,MODE_SIGNAL,1); MaCurrent=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,0); MaPrevious=iMA(NULL,0,MATrendPeriod,0,MODE_EMA,PRICE_CLOSE,1); total=OrdersTotal(); if(total<1) { // 没有指定开单 if(AccountFreeMargin()<(1000*Lots)) { Print("没有资金. 自由保证金 = ", AccountFreeMargin()); return(0); } // 尽可能检测看涨仓位 (BUY) if(MacdCurrent<0 && MacdCurrentSignalCurrent && MacdPrevious

最后,确认智能交易时,只需指定外部变量值,例如“Lots = 1”, “Stop Loss (S/L) = 0” (不使用), “Take Profit (T/P) = 120” (适合一小时周期), “Trailing Stop (T/S) = 30”。当然,你可以使用自己的设定。点击“编写”按钮,若无错误信息(可从MetaEditor列表中复制),再按“保存”键保存智能交易即可。