移动均线SMA、EMA等指标为常用的均线指标,特别适用于趋势市场中。但这些指标对趋势的判定具有一定的滞后性,当趋势出现反转时这种滞后性容易导致亏损。然而,在技术性投资章节中指出,这种趋势性策略在中国并不一定适用,因为中国投资者更多是投机,而不是投资,因此利用长期趋势策略并不合适。此处为了弥补这种趋势上的缺陷,加入止损策略。
基于此,本节借用John F. Ehlers提出的SuperSmoother指标,这个指标在在很多交易软件如Tradestation中存在。其中John F. Ehlers是电气工程师,获得密苏里大学的电气工程专业的本科和硕士学位,获得华盛顿大学的博士学位,擅长波动和信号理论,从1976年开始从事个人交易。他把信号工程中的理论运用到技术性指标的构建中,从一个信号分析和频域的视角分析技术性指标,并提出大量新的技术性指标,获得了大量投资者的认可。其中SuperSmoother为超滑动平均线,主要弥补移动平均线的滞后性问题,得到的指标在一定程度上可以类似于小波信号指标的结果,而且计算方法从小波分析的方法简单的多。SuperSmoother计算公式如下:
超平滑均线来自于信号理论数字信号处理(Digital Signal Processing),与移动均线的差异见图6.3。其中红色实线为SuperSmoother均线,蓝色虚线为一般EMA均线,可以看出,其中超平滑均线一方面具有平滑性特征,同时在一定程度上紧随K线,滞后性要远远小于一般的移动均线。
图6.3 SuperSmoother指标与EMA指标在期货CF1609上的表现这种均线究竟表现如何,下面构建超平滑移动均线策略进行分析。以商品期货为例,具体选择玻璃、棉花和甲醇期货的15分钟K线数据,交易规则与一般均线交叉策略一致,即当收盘价上穿超平滑均线进入,收盘价下穿超平滑均线时退出,并根据风险调整买卖仓位,对应的策略设定见表6.2。
表6.2 超平滑移动均线策略
策略 | 设定 | 参数 |
数据 | 玻璃、棉花和甲醇期货1609 | 15分钟线 |
指标 | SuperSmoother | 10期 |
进入 | 均线交叉类似 | - |
退出 | 均线交叉类似 | - |
成交量 | OsDollarATR函数 | - |
在此基础上,基于SMA策略,并利用上述指标进行止损,对期货市场的15分钟数据构建策略进行分析。
- #----------------------------------------加载工具包及数据获取--------------------------------------
- 加载相关工具包:
- >library(IKTrading)
- >library(DSTrading)
- >library(quantstrat)
- 具体基于15分钟K线进行分析,读取期货数据,具体选择三个期货,分别为玻璃1609(FG1609),棉花1609(CF1609)和甲醇1609(MA1609),对应命令如下:
- >FG1609<-read.csv(file='E://datasets//Future//sina//FG1609.15m.txt', header=T,sep=',')
- >CF1609<-read.csv(file='E://datasets//Future//sina//CF1609.15m.txt', header=T,sep=',')
- >MA1609<-read.csv(file='E://datasets//Future//sina//MA1609.15m.txt', header=T,sep=',')
- 设置代码:
- >symbols<-c('FG1609','CF1609','MA1609')
- 把对应的数据转换成时间序列格式,并删除多余的列:
- >for (i in 1:length(symbols)){
- > tmp<-get(symbols[i])
- > tmp.date<-as.POSIXct(tmp$Time,format='%Y-%m-%d %H:%M')
- > assign(symbols[i],xts(tmp[,-1],tmp.date))
- >}
- >rm(tmp)
- >rm(tmp.date)
- #----------------------------------------创建SuperSmoother函数---------------------------------
- SuperSmoother函数其实IKTrading工具包中已经存在,但函数比较粗糙,开发者没有后续动作,笔者在他基础上进一步完善。对应的函数命令如下:
- >superSmoother<-function (x,n){
- > a1 <- exp(-1.414 * pi/n)
- > b1 <- 2 * a1 * cos(1.414 * pi/n)
- > c2 <- b1
- > c3 <- -a1 * a1
- > c1 <- 1 - c2 - c3
- > filt <- c1 * (x + lag(x))/2
- > leadNAs <- sum(is.na(filt))
- > filt <- filt[-c(1:leadNAs)]
- > filt <- filter(filt, c(c2, c3), method = "recursive")
- > filt <- c(rep(NA, leadNAs), filt)
- > filt <- xts(filt, order.by = index(x))
- > colnames(filt) = "superSmoother"
- > return(filt)
- >}
- #-----------------------------------------参数设定及策略初始化---------------------------------------
- >tradeSize=100000
- >initEq<-tradeSize*length(symbols)
- >initDate<-'2016-04-22'
- >period<-10
- >pctATR<-0.02
- >nSMA<-10
- #parameters for SuperSmoother
- >nFast=10
- >nSlow=60
- >TxnFees=5
- >portfolio.st<-account.st<-strategy.st<-'SuperSmoother'
- >currency('CNY')
- >Sys.setenv(TZ='UTC')
- >.blotter<-.strategy<-new.env()
- >stock(symbols,currency='CNY',multiplier=1)
- 在此基础上初始化投资组合、账户、委托单和策略:
- >initPortf(portfolio.st,symbols,initDate=initDate,currency='CNY')
- >initAcct(account.st,portfolio.st,initDate=initDate,currency='CNY',initEq=initEq)
- >initOrders(portfolio.st,initDate=initDate)
- >strategy(strategy.st,store=T)
- #-----------------------------------------------增加策略指标--------------------------------------------
- 具体增加短期和长期Supersmoother、lagATR共三个指标。
- 此处增加lagATR指标,主要考虑到后续的委托数量函数自定义用osDollarATR,需要利用ATR指标,osDollarATR委托数量如何随着ATR指标变化,从而减少交易风险,可见上章的描述。对应的命令分别如下:
- >add.indicator(strategy.st,name='lagATR',
- > arguments=list(HLC=quote(HLC(mktdata)), n=period),label='atrX')
- >add.indicator(strategy.st,name='superSmoother',
- > arguments=list(x=quote(Cl(mktdata)), n=nFast),label='fastsmooth')
- >add.indicator(strategy.st,name='superSmoother',
- > arguments=list( x=quote(Cl(mktdata)),n=nSlow),label='slowsmooth')
- #---------------------------------------------增加策略信号---------------------------------------------
- 基于长期超平滑线与短期超平滑线创建策略信号。当短期向上交叉长期超平滑线为买入信号,反之为卖出信号。具体如下:
- >add.signal(strategy.st,name='sigCrossover', arguments = list(
- > columns=c('fastsmooth','slowsmooth'),relationship='gt'), label='enterlong')
- >add.signal(strategy.st,name='sigCrossover',arguments=list(
- > columns=c('fastsmooth','slowsmooth'),relationship='lt'), label='exitlong')
- #--------------------------------------------增加交易规则---------------------------------------------
- 基于策略信号增加交易规则,其中交易数量依赖于osDollarATR函数,具体进入和退出规则如下:
- >add.rule(strategy.st,name='ruleSignal',
- > arguments=list(sigcol='enterlong',sigval=T,ordertype='market',
- > orderside='long',replace=F,prefer='Open',osFUN=osDollarATR,
- > tradeSize=tradeSize,pctATR=pctATR, atrMod='X'),
- > type='enter', label='EnterLong')
- >add.rule(strategy.st,name='ruleSignal',
- > arguments = list(sigcol='exitlong',sigval=T,orderside='long', ordertype='market',
- > replace=F,orderqty='all', TxnFees=-TxnFees,prefer='open'),
- > type='exit',label='ExitLong')
- #-------------------------------------------策略运行及统计------------------------------------------
- >out<-try(applyStrategy(strategy.st,portfolio.st))
[1] "2016-05-25 01:30:00 CF1609 33 @12435"
[1] "2016-05-30 02:00:00 CF1609 -33 @13060"
[1] "2016-05-30 02:30:00 CF1609 30 @13170"
[1] "2016-05-30 15:15:00 CF1609 -30 @13170"
……
[1] "2016-08-29 03:15:00 MA1609 -446 @1863"
[1] "2016-09-01 03:30:00 MA1609 542 @1845"
[1] "2016-09-08 07:00:00 MA1609 -542 @1872"
[1] "2016-09-13 01:15:00 MA1609 96 @1880"
[1] "2016-09-20 06:15:00 MA1609 -96 @2082"
在此基础上对投资组合、账户和最终资产进行更新,对应的命令分别为:
>updatePortf(portfolio.st)
>dateRange<-time(getPortfolio(portfolio.st)$summary)[-1]
>updateAcct(portfolio.st,dateRange)>updateEndEq(account.st)
分别对三种期货统计图显示,具体命令为:
>chart.Posn(portfolio.st,'MA1609')
图6.4 甲醇期货1609交易头寸、累积收益和回撤统计图
在此基础上查看具体绩效统计结果:
>stats<-t(tradeStats(portfolio.st)) CF1609 FG1609 MA1609 Portfolio "OHV" "OHV" "OHV" Symbol "CF1609" "FG1609" "MA1609" Num.Txns "82" "74" "76" Num.Trades "41" "37" "38" Net.Trading.PL " 77080" "111351" " 36309" Avg.Trade.PL "1880.000" "3009.486" " 955.500" Med.Trade.PL "-1310" " -767" " -857" Largest.Winner "36795" "39055" "30499" Largest.Loser "-12305" " -9698" " -7313" Gross.Profits "166925" "182073" "111138" Gross.Losses "-89840" "-70722" "-74819" Std.Dev.Trade.PL "10379.465" "10322.876"" 7778.482"Std.Err.Trade.PL "1621.000" "1697.070" "1261.836" Percent.Positive "34.14634" "37.83784" "31.57895" Percent.Negative "63.41463" "62.16216" "63.15789" Profit.Factor "1.858025" "2.574489" "1.485425" Avg.Win.Trade "11923.21" "13005.21" " 9261.50" Med.Win.Trade " 6532.5" "12418.0" " 7700.0" Avg.Losing.Trade "-3455.385" "-3074.870""-3117.458"Med.Losing.Trade "-3037.5" "-2409.0" "-3002.5" Avg.Daily.PL "2141.111" "3275.029" "1100.273" Med.Daily.PL "-1207.5" " -733.0" "-1714.0" Std.Dev.Daily.PL "10599.994" "10607.983"" 8043.178"Std.Err.Daily.PL "1766.666" "1819.254" "1400.138" Ann.Sharpe "3.206519" "4.900977" "2.171566" Max.Drawdown "-62265" "-31439" "-49313" Profit.To.Max.Draw "1.2379346""3.5418111" "0.7362967"Avg.WinLoss.Ratio "3.450619" "4.229517" "2.970850" Med.WinLoss.Ratio "2.150617" "5.154836" "2.564530" Max.Equity "104575" "116763" " 48896" Min.Equity "-1485" "-4820" "-6691" End.Equity " 77080" "111351" " 36309" 可以看出,这种策略效果非常理想,每种期货都出现了较大的盈利。其中棉花期货盈利77080元、玻璃期货盈利111351元,甲醇期货盈利36309元。估计很多人要飘飘然了,这么好的绩效,还呆在这里干什么,赶紧赚钱去!冷静冷静,这只是Paper Trading而已,很多实际因素并没有考虑在内。一定要对比思考,这种交易与实盘交易不同之处在哪里,有哪些因素会对上面的最终收益造成影响。切记,这种思考对实盘交易非常重要。