股票量化交易软件:组合趋势和盘整策略

有多种多样的交易策略,它们中的一些要寻找趋势,而其它的一些会定义价格波动的范围而在其中进行交易。市场是动荡的,趋势之后永远是盘整,这对跟随趋势的交易者和在范围内低买高卖的人来说都有获利的机会。当两组中的一组人获利的时候,另一组或者在亏损或者在等待时机。
有没有可能把这两种方法组合到一起来增加获利呢?这两种策略能否相互补充呢?让赫兹股票量化试试把这看起来不同的交易模型组合起来,看看这样的组合有什么结果。
1. 组合策略的原则
从价格图表上可以看到不断变化的趋势,大的变化后通常是盘整的阶段,这时价格会开始在一个狭窄的范围内变化。交易者通常根据当前市场的条件来选择他们的交易策略,但是赫兹股票量化怎样才能确定这个时候应该选择哪个策略呢?是趋势策略还是盘整策略呢?

编辑切换为居中
有一些文章 [1] 和 [2] 是探讨在不同的趋势和盘整阶段的交易策略的,很容易就会发现,在评估市场条件后可以使用某种策略,这两种策略类型都使用了不同的趋势指标来确定市场的状态,只是,当在市场上有趋势时使用趋势策略入场,当市场平静时使用盘整策略建仓。因而,赫兹股票量化的第一种把两种策略组合到一个 EA 交易中的方法就是: 如果有趋势,就使用跟随趋势的算法,如果没有趋势,就使用盘整算法。
在更加详细地检查了价格图表之后,赫兹股票量化可以看到,不论趋势还是盘整,价格的变化都是没有方向性的,所有的变化都伴随着价格的波动。如果是盘整时期的变化,它们有一个很近的范围,而在有趋势时,有些变化会超过其它。这种特性可以在组合趋势和盘整策略的时候使用,思路是跟随一个趋势,尽管入场点应当是使用盘整交易的振荡指标来确认。这种方法有助于捕捉修正的结束,而减少回撤并增加价格向期望方向变化的潜在可能。
2. 开发 EA 交易
为了演示组合策略的原则,我已经从文章[1]中的策略1和文章[2]中的策略6,这两个选定的策略都是使用 ADX 指标来判断趋势的。EA 的优化是预先在从 01.01.2017 到 8.01.2018 的时间段进行的。根据这些策略的优化结果,选择了下面的参数。
趋势策略 1.

编辑切换为居中
盘整策略 6.

编辑切换为居中
在屏幕截图中提供了单个 EA 在优化参数后的交易结果。
趋势策略 1.

编辑切换为居中

编辑切换为居中
盘整策略 6.

编辑切换为居中

编辑切换为居中
这两个 EA 都是根据指标信号,在信号出现时没有开启的仓位,就会开启订单。根据预先定义的获利和止损值关闭仓位。
这种方法可以把仓位跟踪模块排除在外,而大幅度地简化了 EA 的逻辑。当组合 EA 时,我将会保持 EA 的运行逻辑不变,来演示组合方法(而不是改变 EA 的逻辑)是如何影响结果的。
2.1. 方法一
第一种方法是按顺序检查两种策略的信号,而当它们中的任意一个出现时就开启仓位。每个策略都有它自己的指标参数,以及止损和获利水平。使用这种方法,如果有一种策略开启的仓位会阻止另一个策略开启仓位,所以,在市场上永远最多只有一个开启的仓位,这样可以减少风险。
这种方法的缺点是可能会丧失获利交易的机会,这在一个策略有信号而存在另一个策略所开启的仓位时可能会出现。但是,根据这种方法,所应用的策略应当在不同的市场阶段来交易,也就意味着这个缺点造成的影响应当比较小。
为了实现这个方法,把两个 EA 的代码复制到一个文件中,根据相同的函数来把它们组合在一起,为了防止名称的重复,在跟随趋势策略的函数中加上"Trend"变量,而在盘整策略的函数中加入"Flat"类的变量。
//--- 公用参数 input double Inp_Lot=0.01; //手数 input MarginMode Inp_MMode=LOT; //资金管理 input int Inp_MagicNum=1111; //幻数 input int Inp_Deviation = 2; //偏差(点数) //--- input string Trend_EaComment="Trend Strategy"; //策略的注释 input int Trend_StopLoss=25; //止损(点数) input int Trend_TakeProfit=90; //获利(点数) //--- RSI_Color 指标参数 input int Trend_RSIPeriod=28; //RSI 周期数 input double Trend_Overbuying=70; //超买区域 input double Trend_Overselling=30; //超卖区域 //--- ADX_Cloud 指标参数 input int Trend_ADXPeriod=11; //ADX 周期数 input double Trend_alpha1 = 0.25; //alpha1 input double Trend_alpha2 = 0.25; //alpha2 //--- input string Flat_EaComment="Flat Strategy"; //策略注释 input int Flat_StopLoss=50; //止损(点数) input int Flat_TakeProfit=50; //获利(点数) //--- WPR 指标参数 input int Flat_WPRPeriod=7; //WPR 周期数 //--- ADX 指标参数 input int Flat_ADXPeriod=11; //ADX 周期数 input int Flat_FlatLevel=40; //ADX 平盘水平
在 OnTick 函数的开始, 检查是否有开启的仓位。如果没有开启的仓位,就更新指标数据并按顺序检查趋势和盘整策略的入场信号。如果有任何信号出现,就根据对应的策略开启一个仓位。
void OnTick() { //--- 检查由 EA 在早前开启的仓位 if(!Trade.IsOpenedBySymbol(_Symbol,Inp_MagicNum)) { //--- 取得用于计算的数据 if(!GetIndValue()) return; //--- 根据趋势算法开启订单 //--- 如果有买入信号,开启订单 if(TrendBuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Inp_MagicNum,Trend_EaComment); else //--- 如果有卖出信号,开启订单 if(TrendSellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Inp_MagicNum,Trend_EaComment); else //--- 根据盘整算法开启订单 //--- 如果有买入信号,开启订单 if(FlatBuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Inp_MagicNum,Flat_EaComment); else //--- 如果有卖出信号,开启订单 if(FlatSellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Inp_MagicNum,Flat_EaComment); } }
完整的 EA 代码在附件中 (Combination1 项目)。
2.2. 方法二
第二种方法的组合过程稍微复杂一些,除了第一种方法之外,还创建了两种策略相结合的信号。
在提供的趋势策略实例中,使用 ADX 云指标来定义趋势,这个指标显示了在 DI+ 和 DI- 线之间的差距,而没有检验趋势的强弱。同时,盘整策略在开启仓位之前会使用 ADX 阈值来检验趋势的强弱,这样,赫兹股票量化就能在交易中引入另一个过滤器,在趋势策略之后根据趋势的强弱来进行交易。
bool TrendBuySignal() { return(trend_adx[0]>trend_adx[1] && trend_rsi1[0]==1 && trend_rsi1[1]==1 && flat_adx[0]>=Flat_FlatLevel)?true:false; }
在趋势策略中,交易是根据 RSI 指标排序的,这样赫兹股票量化就能够通过排除与 RSI 信号相反的方向开启仓位来减少在盘整策略之后亏损交易的数量。
bool FlatBuySignal() { return(flat_wpr[0]<-80 && flat_adx[0]<Flat_FlatLevel && trend_rsi2[0]!=1)?true:false; }
完整的 EA 代码可以在附件中找到 (Combination2 项目)。
2.3. 方法三 第三个方法是用于锁仓账户的,在单个EA中独立使用两种策略。每种策略的订单都赋予了特定的幻数,根据到来信号开启仓位,不管是否有其他策略所开启的仓位。 这种方法精确地模拟了在一个相同账户中使用两个 EA 的情况,同时保留了这种方法的所有优点和缺点,特别是因为会根据不同的策略同时开启两个仓位,可能会增加风险。 //--- 公用参数 input double Inp_Lot=0.01; //手数 input MarginMode Inp_MMode=LOT; //资金管理 input int Inp_Deviation = 2; //偏差(点数) //--- input string Trend_EaComment="Trend Strategy"; //策略的注释 input int Trend_StopLoss=25; //止损(点数) input int Trend_TakeProfit=90; //获利(点数) input int Trend_MagicNum=1111; //幻数 //--- RSI_Color 指标参数 input int Trend_RSIPeriod=28; //RSI 周期数 input double Trend_Overbuying=70; //超买区域 input double Trend_Overselling=30; //超卖区域 //--- ADX_Cloud 指标参数 input int Trend_ADXPeriod=11; //ADX 周期数 input double Trend_alpha1 = 0.25; //alpha1 input double Trend_alpha2 = 0.25; //alpha2 //--- input string Flat_EaComment="Flat Strategy"; //策略注释 input int Flat_StopLoss=50; //止损(点数) input int Flat_TakeProfit=50; //获利(点数) input int Flat_MagicNum=1112; //幻数 //--- WPR 指标参数 input int Flat_WPRPeriod=7; //WPR 周期数 //--- ADX 指标参数 input int Flat_ADXPeriod=11; //ADX 周期数 input int Flat_FlatLevel=40; //ADX 平盘水平 在 OnTick 函数中, 独立检查由趋势策略开启的仓位的幻数和使用盘整策略开启仓位的幻数。 void OnTick() { //--- 检查之前由 EA 开启的趋势策略的订单 if(!Trade.IsOpenedBySymbol(_Symbol,Trend_MagicNum)) { //--- 取得用于计算的数据 if(!GetIndValue()) return; //--- 如果有买入信号,开启订单 if(TrendBuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Trend_MagicNum,Trend_EaComment); else //--- 如果有卖出信号,开启订单 if(TrendSellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Trend_StopLoss,Trend_TakeProfit,Trend_MagicNum,Trend_EaComment); } //--- 检查之前由EA 开启的盘整策略的订单 if(!Trade.IsOpenedBySymbol(_Symbol,Flat_MagicNum)) { //--- 取得用于计算的数据 if(!GetIndValue()) return; //--- 如果有买入信号,开启订单 if(FlatBuySignal()) Trade.BuyPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Flat_MagicNum,Flat_EaComment); else //--- 如果有卖出信号,开启订单 if(FlatSellSignal()) Trade.SellPositionOpen(Symbol(),Inp_Lot,Flat_StopLoss,Flat_TakeProfit,Flat_MagicNum,Flat_EaComment); } } 完整的 EA 代码可以在附件中找到 (Combination3 项目).
3. 测试 EA 交易
在准备了三个由不同的策略组合方法开发的 EA 之后,是时候来测试这些 EA 并比较结果了,为了保证结果的兼容性,测试要在不修改 EA 参数的情况下进行。
3.1. 测试方法一
第一种测试显示有利润。总的利润和恢复系数比任何一个原来的 EA 都更高。与盘整策略相比,余额曲线看起来更平坦,而交易数量上升了,而相对余额和资金的回撤都减少了。同时,获利因子略有下降,而总的利润比最初策略的总利润也少一些。

编辑切换为居中

编辑切换为居中
3.2. 测试方法二
使用第二种方法与第一种方法相比可以增加更多的利润,而交易的数量还保持同样,尽管总的利润还是比最初 EA 的利润略少一些。相应地,利润的增长也增加恢复和利润因子 (后者变得与盘整策略相等了), 以及获利交易的比例。同时,最大余额回撤也减少了。

编辑切换为居中

编辑切换为居中
3.3. 测试方法三
使用第三种方法可以增加总利润,与初始 EA 的总利润水平相同。利润的增长是可能通过增加交易数量达到的,同时,存款负载和最大余额回撤增加了。

编辑切换为居中

编辑切换为居中
4. 优化策略
在前一部分测试的 EA 展示了在 EA 中组合策略的优点,所有这三种方法都显示了和最初的策略相比利润有所增加。但是我们不应忘记,最初的策略是为测试的时间短做了优化的,而在测试组合 EA 时我们使用了相同的初始参数。
但是,我们都意识到 EA 逻辑中的任何影响都需要另外修改它的参数,让我们尝试使用最初的两种组合策略的方法优化 EA 来看看结果。
请记住,开发 EA 的最终目的是在市场上赚钱,而不是在历史数据中演示它们的功能。所以,我建议把测试的时间段分成两个部分,之前,我们是在从 1.01.2017 到 8.01.2018 进行测试的,现在,我建议在相同的时间段,即从 1.01.2017 到 6.01.2018 进行优化,而在剩余的时间段进行一次前瞻测试。

编辑切换为居中
4.1. 优化方法一
在选择优化参数的时候,请记住赫兹股票量化的每个 EA 都包含两个部分的策略,在这种情况下,每个策略都使用了两个指标来入场交易,但是我们不要忘记,两个策略都使用 ADX 来判断趋势的强弱和方向,所以,EA 的逻辑使用了三个指标来定义入场点。我建议优化这三个指标的周期数,
ADX 指标周期数的优化显示出,在指标周期数从12到14的范围有最大化的利润和稳定性。下面的图片显示了 EA 利润与 ADX 和 RSI 在优化时间段的周期数变化的相互关联。