外汇EA智能交易使用教程详解

交易原理:

做多(买入)入场——MACD指标在零轴下方,自下而上穿越信号线,形成金叉信号。

外汇EA智能交易使用方法

做空(卖出)入场——MACD指标在零轴上方,自上而下穿越信号线,形成死叉信号。

外汇EA智能交易使用方法

做多平仓——当达到止盈目标,或触发追踪止损,或MACD指标在零轴上方自上而下穿越信号线时,进行平仓操作。

做空平仓——当达到止盈目标,或触发追踪止损,或MACD指标在零轴下方自下而上穿越信号线时,进行平仓操作。重要提示:为排除MACD指标中微小波动(图表上的小‘山丘’)的干扰,可引入一种补充检测方法,即指标变动幅度应不低于最后5个最低价单元(5*Point,对于USD/CHF为0.0005,USD/JPY为0.05)。

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

外汇EA智能交易使用方法在智能交易的导航窗口处,点击鼠标右键,在菜单中选择“创建新智能交易”。系统会弹出初始提醒,要求进入数据中心。在显示窗口中,填写智能交易的名称(如MACD Sample)、作者(填写您的名字)、链接(可留空)以及注解(如MACD-基本智能交易的测试范例)。

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

测试智能交易的源代码虽然只占用少量空间,但对于非专业编程人员来说,仍可能感到有些复杂。不过,我们并不需要完全理解每个细节,只需按照以下结构框架来组织代码即可。

一个标准智能交易的结构通常包含以下部分:

初始变量定义

初始数据检测——检查图表及图表中的柱数是否满足条件。

检测外部变量值:标准手数、止损、止盈、追踪止损等参数。

为加快数据处理,设置内部变量存储常用指标值。

检测交易终端是否无未平仓订单,若是,则:检测账户可用保证金是否充足。

判断是否具备做多条件(BUY)?若满足,则开设多单并退出。

判断是否具备做空条件(SELL)?若满足,则开设空单并退出。

退出智能交易流程。

周期循环检测已开仓位若是多单,判断是否应平仓?是否应调整追踪止损?

若是空单,同样判断是否应平仓?是否应调整追踪止损?整体流程相对简单,KCM外汇仅包含四种情况。

接下来,我们逐步完成上述计划:

初始变量定义

所有在智能交易程序中使用的变量,必须按照MetaQuotes Language 4(MQL4)的规范进行声明。因此,在程序开头,我们会插入初始变量定义部分。

示例变量声明如下: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; MQL4语言允许使用“外部变量”,这些变量可从外部调整,在源代码编译后仍可修改,为程序提供了灵活性。在本例中,MATrendPeriod被定义为外部变量。在程序开始处,我们插入该变量的声明。

extern double MATrendPeriod=26;

检测初始数据

该代码段通常适用于所有智能交易,用于确保程序运行环境正常。标准检测逻辑如下:

// 初始数据检测// 确认智能交易运行正常非常重要// 图表和用户设置不能出现任何错误// 检查止损、止盈等变量(本例中需检查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); 现在,KCM外汇在源代码中可以使用MacdCurrent等变量来代替冗长的函数调用。

检测交易终端是否无未平仓订单,若是:

在本智能交易中,我们主要处理开仓和挂单操作。为了更安全,我们来学习如何检测交易终端中是否有未平仓订单:

total=OrdersTotal(); if(total<1) { 检测: 账户上的可用保证金…

在分析市场状况之前,需确认账户可用保证金是否足以开仓。

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*Point, "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); }

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指标高于零轴,且自上而下穿越信号线。

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 //空单 { 应该平仓吗?

平空单的条件: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); } } }

关闭所有残留开仓。

} } } return(0);}

这样,我们就一步步完成了智能交易的编写。

步骤3 – 汇总程序代码

打开智能交易的设置窗口,点击“属性…”按钮,在弹出窗口中设置外部运行参数:

外汇EA智能交易使用方法 将先前部分的所有代码集中到一起:

//+------------------------------------------------------------------+//| MACD Sample.mq4 |//| Copyright © 2005, MetaQuotes Software Corp. |//| http://www.metaquotes.net/ |//+------------------------------------------------------------------+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;// 检测初始化数据// 确定智能交易在图表中运行正常非常重要// 用户在外部变量中不会产生错误// 外部变量(标准手数, 止损, 止盈, 追踪止损)// 在这种情况下,我们检查止盈水平是否小于10,图表柱数是否小于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