为了开发出一种参与“2010 自动交易锦标赛”的“EA 交易”,我们使用一个即用的、来自《交易机器人的原型》一文的“EA 交易”模板。 即便是 MQL5 程序员初哥也能胜任此任务,因为您策略的基类、函数和模板都已经开发完毕。 编写少量的代码来实现您的交易理念就足够了。
我们需要准备的内容:
人们相信随势交易比区间交易更有利可图,而且盘中量发生的反弹,要比通道边界的崩溃更加频繁。
基于上述假设,我们会向着通道边界(轨道线)反弹的当前趋势建仓。 我们会根据平仓信号或在达到 Stop Loss(止损)或 Take Profit(获利)水平时平仓。
与趋势信号一样,我们会利用 MACD 增长或在日线图上的减少,还会根据小时时间表上的通道边界反弹进行交易。
图 1. EURUSD 日线图上的 MACD 指标
如果 MACD 指标连续于两个柱上增长 - 此为买入信号。 如连续在两个柱上减少 - 则为卖出信号。
图 2. 轨道线边界价格反弹
2.1. 包含的模块
专家会采用来自 ExpertAdvisor.mqh 模块的“EA 交易”类。
#include <ExpertAdvisor.mqh>
2.2. 输入变量
input int SL = 50; // 止损距离 input int TP = 100; // 获利距离 input int TS = 50; // 追踪止损距离 input int FastEMA = 15; // 快速 EMA input int SlowEMA = 26; // 慢速 EMA input int MACD_SMA = 1; // MACD 信号线 input int EnvelPer = 20; // 轨道线周期 input double EnvelDev = 0.4; // 轨道线方差 input double Risk = 0.1; // 风险
2.3. 创建一个继承自 CExpertAdvisor 的类
class CMyEA : public CExpertAdvisor { protected: double m_risk; // 风险大小 int m_sl; // 止损 int m_tp; // 获利 int m_ts; // 追踪止损 int m_pFastEMA; // 快速 EMA int m_pSlowEMA; // 慢速 EMA int m_pMACD_SMA; /// MACD 信号线 int m_EnvelPer; // 轨道线周期 double m_EnvelDev; // 轨道线方差 int m_hmacd; // MACD指标句柄 int m_henvel; // 轨道线指标句柄 public: void CMyEA(); void ~CMyEA(); virtual bool Init(string smb,ENUM_TIMEFRAMES tf); // 初始化 virtual bool Main(); // 主函数 virtual void OpenPosition(long dir); // 根据信号开仓 virtual void ClosePosition(long dir); // 根据信号平仓 virtual long CheckSignal(bool bEntry); // 检查信号 }; //------------------------------------------------------------------2.4. 删除指标
//------------------------------------------------------------------ void CMyEA::~CMyEA() { IndicatorRelease(m_hmacd); // 删除MACD指标 IndicatorRelease(m_henvel); // 删除轨道线指标 } //------------------------------------------------------------------2.5. 初始化变量
//------------------------------------------------------------------ Init bool CMyEA::Init(string smb,ENUM_TIMEFRAMES tf) { if(!CExpertAdvisor::Init(0,smb,tf)) return(false); // initialize parent class // 复制参数 m_risk=Risk; m_tp=TP; m_sl=SL; m_ts=TS; m_pFastEMA=FastEMA; m_pSlowEMA=SlowEMA; m_pMACD_SMA=MACD_SMA; m_EnvelPer = EnvelPer; m_EnvelDev = EnvelDev; m_hmacd=iMACD(m_smb,PERIOD_D1,m_pFastEMA,m_pSlowEMA,m_pMACD_SMA,PRICE_CLOSE); // 创建MACD指标 m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // 创建轨道线指标 if(m_hmacd==INVALID_HANDLE ||m_henvel==INVALID_HANDLE ) return(false); //如果报错,则退出 m_bInit=true; return(true); // 允许交易 }
2.6. 交易函数
//------------------------------------------------------------------ CheckSignal long CMyEA::CheckSignal(bool bEntry) { double macd[4], // MACD 指标值数组 env1[3], // 轨道线上轨值数组 env2[3]; // 轨道线下轨值数组 MqlRates rt[3]; // 最近3个柱形的价格数组 if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // 将最近3个柱形的价格值复制到数组中 { Print("CopyRates ",m_smb," history is not loaded"); return(WRONG_VALUE); } // 将指标值复制到数组 if(CopyBuffer(m_hmacd,0,0,4,macd)<4 || CopyBuffer(m_henvel,0,0,2,env1)<2 ||CopyBuffer(m_henvel,1,0,2,env2)<2) { Print("CopyBuffer - no data"); return(WRONG_VALUE); } // 如果MACD在增长并且价格从轨道线下轨反弹,买入 if(rt[1].open<env2[1] && rt[1].close>env2[1] && macd[1]<macd[2] && macd[2]<macd[3]) return(bEntry ?ORDER_TYPE_BUY:ORDER_TYPE_SELL); // 买入的条件 // 如果MACD在下降并且价格从轨道线上轨向下反弹,卖出 if(rt[1].open>env1[1] && rt[2].close<env1[1]&& macd[1]>macd[2] && macd[2]>macd[3]) return(bEntry ?ORDER_TYPE_SELL:ORDER_TYPE_BUY); // 卖出条件 return(WRONG_VALUE); // 如果没有信号 } CMyEA ea; // 类的实例
所以,编写代码后,将作为结果的“EA 交易”发送至策略测试程序。
在策略测试程序中,周期为 "去年" ,货币对为 EURUSD 时 ,我们得到下述图表:
图 3. 带初始化参数的交易系统的测试结果
结果不是那么令人满意,所以我们开始优化 Stop Loss 和 Take Profit 的水平。
我们会以 10-500 的间隔、50 的步幅,优化 Stop Loss 和 Take Profit 参数。
最佳结果: Stop Loss = 160,Take Profit = 310。优化 Stop Loss 与 Take Profit 之后,我们收到 67% 的可盈利交易(之前是 36%)和 $1522.97 的净利润。 由此,通过简单的处理,我们升级好的系统已经实现了收支平衡,甚至还有一些盈利。
图 4. 带有优化 Stop Loss 与 Take Profit 的交易系统的测试结果
接下来,我们来优化轨道线周期与方差。
轨道线周期会以 4 为步幅,从 10 变到 40,而方差则从 0.1 变到 1,步幅为 0.1。
最佳优化结果为: 轨道线周期 = 22,轨道线方差 = 0.3。 即使现在,我们已经获得了 $14418.92 的净利润和 79% 的可盈利交易。
图 5. 带有优化轨道线周期与方差的交易系统的测试结果
如果我们将风险加到 0.8,我们就会获得 $77330.95 的净利润。
图 6. 带有优化风险的交易系统的测试结果
策略优化可能包含下述步骤:
5.1. 更改趋势指标
通过《在 MQL5 中寻找趋势的几种方法》一文我们可以看出,最佳的趋势指标是移动平均线和移动平均“扇形图”。
我们用简单的移动平均线来替代 MACD 指标。 EA 代码请见随附的 Macena.mq5 文件。
5.2. 选择另一条轨道线
在 Envelopes (轨道线)旁边,您也可以自行选择另一条轨道线。 例如:Price Channel(价格通道)、Bollinger Bands (布林带)或是某条基于移动平均线的轨道线。
随附的 Maboll.mq5 文件中,有一份使用 MA 与布林带的 EA 示例。
5.3. 选择另一个时间表
我们将时间表改大或改小。 大时间表用 H4,小时间表则用 M15,然后测试并优化您的系统。
为达此目的,只需替换代码中的一行:
m_henvel=iEnvelopes(m_smb,PERIOD_H1,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // 创建轨道线指标
如是 H4 时间表:
m_henvel=iEnvelopes(m_smb,PERIOD_H4,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // 创建轨道线指标
如是 M15 时间表:
m_henvel=iEnvelopes(m_smb,PERIOD_M15,m_EnvelPer,0,MODE_SMA,PRICE_CLOSE,m_EnvelDev); // 创建轨道线指标
5.4. 更改交易条件
作为一次试验,我们还要更改交易条件。
//------------------------------------------------------------------ 检查信号 long CMyEA::CheckSignal(bool bEntry) { double env1[3], // 轨道线上轨值数组 env2[3]; // 轨道线下轨值数组 MqlRates rt[3]; // 最近3个柱形的价格数组 if(CopyRates(m_smb,m_tf,0,3,rt)!=3) // 将最近3个柱形的价格值复制到数组中 { Print("CopyRates ",m_smb," history is not loaded"); return(WRONG_VALUE); } // 将指标值复制到数组 if(CopyBuffer(m_henvel,0,0,2,env1)<2 || CopyBuffer(m_henvel,1,0,2,env2)<2) { Print("CopyBuffer - no data"); return(WRONG_VALUE); } // 如果MACD在增长并且价格从轨道线下轨反弹,买入 if(rt[1].open<env2[1] && rt[1].close>env2[1]) return(bEntry ?ORDER_TYPE_BUY:ORDER_TYPE_SELL); // 买入的条件 // 如果MACD在下降并且价格从轨道线上轨向下反弹,卖出 if(rt[1].open>env1[1] && rt[2].close<env1[1]) return(bEntry ?ORDER_TYPE_SELL:ORDER_TYPE_BUY); // 卖出条件 return(WRONG_VALUE); // 如果没有信号 } CMyEA ea; // 类的实例 //------------------------------------------------------------------ OnInit
3. 如果价格未大幅下滑、而是转而向上,我们就会平卖出持仓。
4. 如果价格未大幅上扬、而是转而向下,我们就会平买入持仓。
您可以自创方法来优化交易策略,相关文献中也有一些介绍。
更深入的研究,就靠您自己了。
按相同的时间间隔测试我们的“EA 交易”,每次 1 个月。 我们将 "去年" 作为一个测试周期。 时间周期 - 3 个月。
测试间隔 |
利润,以美元计 |
可盈利交易 |
---|---|---|
1.01.2010 - 30.03.2010 |
7239.50 | 76.92% |
1.02.2010 - 30.04.2010 | -6577.50 | 0% |
1.03.2010 - 30.05.2010 | -8378.50 | 50% |
1.04.2010 - 30.06.2010 | -6608.00 | 0% |
1.05.2010 - 30.07.2010 | 41599.50 | 80% |
1.06.2010 - 30.08.2010 | 69835.50 | 85% |
简要总结: 以此模板为基础,您可以用最少的时间和精力,快速实现您的交易理念。
对于系统参数和交易标准的优化也没有任何问题。
要创建一套稳定性更高的交易系统,有必要在更长的时间间隔内对所有参数进行优化。
参考资源列表:本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程