程序化交易中策略的实现、测试和优化.doc
程序化交易中策略的实现、测试和优化摘要: 随着以股指期货为代表的金融衍生品的推出,我国金融市场变得日趋复杂多变,传统的投资策略由于受到人类思维可以处理的信息量的限制、容易受到人类认知偏差和个人情感的影响、缺少相应风险控制策略的考虑,越来越不适合瞬息万变的现代金融市场,引入已在国外金融市场得到广泛应用的程序化交易就显得非常必要。程序化交易是近三十年来兴起于欧美发达国家 结合现代数学理论和计算机技术的一种新的金融市场分析和投资方式,相比传统的基本面分析和技术面分析而言,具有纪律性、系统性、及时性、准确性和分散化的优点。目前程序化交易方面的研究在发达国家市场己经相当成熟,并且被广泛的应用于外汇、证券、期货等市场。而在国内,由于受到期货市场产品机构单一、交易制度不够灵活等限制,程序化交易发展缓慢。 本文结合程序化交易的发展历程和国内外程序化交易的发展现状,采用理论研究和实证分析相结合的方法,以深圳开拓者科技有限公司开发的交易开拓者软件为平台,以其自带的TB语言为基本语言,以股指期货市场为基础,探讨如何实现不同类型的可以持续盈利的交易策略。首先,本文介绍了程序化交易的意义、优缺点和交易策略的分类;其次,介绍了一般交易策略的设计流程,并依此流程开发出了若干种不同类型的交易策略,并对其进行了测试和优化;再次,介绍了对程序化交易来说极其重要的风险控制和资金管理思想、其常用的方法以及这些思想在交易策略中是如何实现的;最后,本文对程序化交易在中国金融市场发展的潜力和可能面临的问题做出了展望。关键词:程序化交易,交易策略,风险控制,资金管理目录1,概述1.1 程序化交易概述1.1.1 什么是程序化交易 程序化交易又称计算机交易、算法交易,是利用计算机技术并且采用一定的数学模型去践行投资理念,实现投资策略的过程。与传统的投资策略不同,程序化交易不是靠个人感觉或单一技术指标来管理资产,而是将适当的投资思想、投资经验反映在量化模型中,利用电脑帮助人脑处理大量复杂的金融信息,帮助人脑总结市场的规律,建立可以重复使用并且反复优化的投资策略,用来指导投资者(机构)的投资决策并自动实现交易的过程。帮助投资者不论在上涨或下跌的市场行情中,都能轻松抓住趋势波段,进而赚取波段获利。1.1.2 和传统投资策略相比的优势和劣势传统的投资策略,无论是基本面分析还是技术面分析,都存在着自身无法克服的缺点:受到人类思维可以处理的信息量的限制;容易受到认知偏差和人类情感的影响;更加强调收益率,对风险控制和资金管理缺乏考虑。程序化交易克服了这些缺点,具有纪律性、系统性、及时性、准确性、和分散化的特点。其中纪律性是指程序化交易中交易的进行时按照交易策略中的思想进行,不会随着投资者情绪的变化而随意更改,能够克服贪婪、恐惧、侥幸等人类的弱点,同时也能克服人类常见的认知偏差,如损失厌恶症(指对避免损失有一种太过强烈的偏好,不能承担风险)、沉淀效应(指更重视已经花掉的钱,而忽视未来可能花掉的钱),处置效应(指早早兑现利润,却让损失继续下去)、结果偏好(只会根据一个决策的结果来判断策略的好坏,而不是考虑决策本身的质量)、近期偏好(更重视近期的数据或经验,忽视历史数据或经验)、锚定效应(过于依赖容易获得的信息)、潮流效应(指盲目相信一件事,只因为许多人都相信它)、信奉小数(从太少的信息中得到没有一句的结论)等;系统性是指程序化交易中包括了多层次的量化模型,多角度的观察和海量数据的观察,同时还融入了资金管理和风险控制的思想;及时性是指,程序化交易中能够及时快速的跟踪市场变化,并能够迅速捕捉有利的趋势或波段,快速下单;准确性是指能够准确评价交易机会,克服主观情绪偏差,妥善运用套利思想;分散化是指在控制风险的条件下,引入投资组合的理念,靠概率而不是单个股票取胜。程序化交易的缺点是相对于它的优点而言的。首先就是严谨有余,而灵活不足,交易策略设定运行后一般不提倡随意的更改。另外,由于由于程序化交易每次的交易量很大,对市场的冲击很大,一旦系统崩溃或者错误,对金融市场可能造成毁灭性的打击,如1987年美国的股灾,程序化交易就和组合保险一起被列为最大元凶。最后,由于程序化交易的研究要求有较高的金融知识和软件背景,人才培育和硬件设施都需要大量的投资,更适合机构投资者,客观上造成了对一般个体投资者的不公平。1.1.3 国内外发展现状程序化交易起源于20世纪70年代的美国,很多的观念和技术源于数理金融和计算机及网络技术。目前程序化交易方面的研究在发达国家市场己经相当成熟,并且被广泛的应用于外汇、证券、期货等市场。据统计,伦敦股票交易所超过50%的交易额来自程序化交易,而美国市场则高达80%以上(数据来源于恒生银行2012年年度报告)。此外,香港期货交易所的恒生指数期货和新加坡交易所的日经指数期货均采用程序化交易。在欧美发达国家,大部分养老基金和信托基金公司都使用程序化策略处理大额度的交易来降低冲击成本,几乎所有的投资经理都使用程序化交易系统来辅助交易与资产管理。但是在国内,由于期货市场产品结构太过单一、交易制度不够灵活、市场流动性较差、风险管理机制不够完善等限制,程序化交易发展缓慢,直到2000年国内才有一家期货公司成立了将推广程序化交易作为战略重点的程序化交易研究小组。近年来,随着股指期货等金融衍生品的推出,程序化交易的研究和应用受到越来越多投资者特别是机构投资者的重视。但是总体而言,国内的程序化交易系统大多是复制国外的,和国内金融市场的实际现状有不少差异,和发达国家的程序化交易水平也有很大差距,程序化交易的研究和本地化在中国有着很大的发展空间。1.2 交易策略的概述1.2.1交易策略的核心意义如果说把服务器,网络带宽等基础设施看做程序化交易的躯壳的话,交易策略就是程序化交易的大脑和灵魂。它是投资者投资思想、投资经验、投资理念的体现,它决定了何时进场、何时出场、如何管理资金、怎样控制风险,它的好坏直接关系到一个程序化交易系统的性能。1.2.2交易策略的分类交易策略的分类有以下多种方式:一,根据持仓时间长短不同,策略分为:长线策略(指能够)、中线策略和短线策略。二,根据交易频率的不同,策略分为:日内高频交易和低频交易。三,根据根据所参考技术指标的不同,策略又可分为以下类型:大势型策略,指为大盘设计的专用策略,通常不在个股的分析研判中使用。趋势型策略,这类策略一般用到至少两条线,当两条或以上线交叉时,策略发出买卖信号。均线型策略:这类策略是通过不同算法得到的平均线技术指标,通过不同期限的均线穿越的情况来发出买卖信号。路径型策略:这类策略也称为阻力支撑型策略,在期货或股票的价格走势图上,常有所谓的阻力位和支撑位(如下图),也即价格会在前期高点或低点价格处反弹的倾向(只是倾向,并不一定)。因此根据投资者是否相信支撑位和阻力位坚守不破,这类策略又可分为趋势跟踪策略和反趋势策略,采用趋势跟踪策略的投资者相信价格会突破阻力位或支撑位(也即在接近阻力位时会继续上涨,在接近支撑位时会继续下跌),他们会在阻力位被突破时买入做多,在支撑位被突破时卖出做空。在市场短期突破支撑位时,他们卖出以退出多头交易,在市场短期突破阻力位时,他们买入以退出空头交易。而采用反趋势交易策略的投资者们则相信价格不会突破阻力位或支撑位(也即在接近阻力位时会反弹,在接近支撑位时也会反弹),他们会在支撑位附近买入做多,在阻力位附近卖出做空,从而赚取之间的差价。能量型策略:这类策略采用能量指标作为市场行情判断的依据,铜材采用情绪指标、心理线、成交量变异率、威廉多空力度线等能量指标来判断市场上多空力量(即买卖力量)的对比,判断多空双方的情绪是高亢还是沮丧。如果多方力量强于空方力量,此时价格有下跌趋势,应做空;相反,如果空方力量强于多方力量,此时价格有上涨趋势,应做多。成交量型策略:这类策略是指通过对与成交量存在联系的技术指标的判断来判断市场行情是利于空方还是多方,从而判断是做多还是做空。超卖超卖型策略:这种策略使用的指标大多为判断市场处于超买超卖状态,如果市场处于超买状态(对股票、期货等的过度买入),则股价随时可能下跌,应该做空;相反如果处于超卖状态(对股票、期货等的过度卖出),则股价随时可能上升,应该做多。常用的技术指标有:CCI(即顺势指标,是专门用来测量股价是否已经超出常态分布范围)、KDJ(即随机指标,是利用价格波动的真实波幅来反映价格走势的强弱和超买超卖现象,在价格尚未上升或者下降之前发出买卖信号)、RSI(即相对强弱指标,是通过特定时期内股价的变动情况计算市场买卖力量对比,来判断股票价格本质强弱,推测股票价格未来变动方向)、CMO(即ChandeMomentumOsciliator,钱德动量摆动指标,是由图莎尔钱德发明的,与其他动量指标摆动指标如相对强弱指标(RSI)和随机指标(KDJ)不同,钱德动量指标在计算公式的分子中采用上涨日和下跌日的数据。在第三章的论述中,我们将介绍一个以此指标为基础编写的超买超卖型策略)等。在本文中,我们将以最后一种分类为主,特别讨论笔者编写的常用并且适合股指期货市场的趋势型、均线型、路径型和超卖超卖型四种策略。并对每个策略所依据的原理、代码实现、测试结果、优化结果、模拟交易结果做详细的说明和解释。1.2.3研究平台、语言和市场概述在本文中,我们使用的研究平台是深圳开拓者科技有限公司开发的交易开拓者软件。这是一款移植于国外的程序化交易软件,是目前国内市场占有率仅次于文华财经的软件,但是其函数库以及系统自带公式应用比文华财经更为强大,交易稳定性方面也更为稳定。策略编写语言是交易开拓者自带的TB语言,而基本市场则选择流动性比较好的股指期货市场(但是并不局限于此,很多策略还适合于其他市场,将在第三章描述中详细介绍)。2,不同类型交易策略的实现、测试和优化2.1交易策略的设计流程在下面几节每个策略的开发中,我们都使用下图所示的设计流程:首先,介绍策略所参考的技术指标,其核心思想,开仓平仓,止盈止损等条件;其次,介绍策略的代码实现;再次,介绍策略在股指期货市场中历史数据中的测试结果,最后针对市场的具体行情进行参数的优化(可能还包括结构的优化),最后我们会进入模拟盘利用当前真实数据进行检验,根据是否达到预期效果进行模型的修改和完善。2.2趋势型策略2.2.1空中花园策略核心思想:这是一个日内策略,主要是利用当日开盘的第一根K线是收阳还是收阴来判断日内趋势可能的运动方向,在当日高开或者低开时最有效。这是最快的一种入场方式,尽管有着很高的出错概率,但是我们通过条件的判断和止盈止损的加入,努力使错误的判断带来的损失最小化,而使正确的判断带来的盈利最大化。做多条件:1,当日开盘价>=昨日收盘价*(1+K); 2,当前Bar的最高价>当日第一个Bar的最高价。如果1和2同时满足,判断当前有上涨趋势,在当前Bar做多。式中,K为浮动比例参数,用户自己根据实际情况设定。做空条件:1,当日开盘价>=昨日收盘价*(1-K); 2,当前Bar的最低价>当日第一个Bar的最高价 如果1和2同时满足,判断当前有下跌趋势,在当前Bar做空。式中,K为浮动比例参数,用户自己根据实际情况设定。止盈条件:持多仓时,如果最高价>=平均入场价*(1+止盈点) 卖出平仓持空仓时,如果最低价<=平均入场价*(1-止盈点) 买入平仓止损条件:持多仓时,如果最低价<=平均入场价*(1-止损点)卖出平仓持空仓时,如果最高价>=平均入场价*(1+止损点) 买入平仓代码实现:/-/ 简称: HangingGarden/ 名称: / 类别: 公式应用/ 类型: 用户应用/ 输出:/-ParamsNumericlots(1); /每次买卖手术NumericbeginTime(930); /交易开始时间9:30NumericendTime(1500);/交易结束时间15:00Numericfloatby(1);/大于或低于这一波动幅度时,判断为上涨或下跌NumericstopLoss(10); / 止损点NumerictakeProfit(2);/止盈点Numericoffset(1);/滑点设置VarsBoolSeriesrising(False);BoolSeriesfalling(False);NumericSeriesfirstHigh(0);NumericSeriesfirstLow(0);Numeric MyEntryPrice ; /入市价格Numeric MyExitPrice;/出市价格Numeric MinPoint;/止损时最小变动单位Numeric i_offset;/交易时可接受的价格浮动范围 BeginIf(Date!=Date1 and CurrentBar>=2)/当前bar为当日开盘的第一根barfirstHigh=High;firstLow=Low;if(Open>=CloseD(1)*(1+floatby/100) rising=True; /判断收阳if(Open<=CloseD(1)*(1-floatby/100) falling=True;/判断收阴Elserising=rising1;falling=falling1;firstHigh=firstHigh1; firstLow=firstLow1;If(Time>0.0001*beginTime And Time< endTime*0.0001 And CurrentBar>=2) /是否在交易允许时间内MyEntryPrice=AvgEntryPrice; /平均入场价i_offset = offset*MinMove*PriceScale; MinPoint=MinMove*PriceScale;if(MarketPosition=0) /当前未持仓时If(rising=True and High>firstHigh) /做多条件满足,做多Buy(lots,Open+i_offset);PlotNumeric("Open",Open);Return;If(falling=True and Low<firstLow) /做空条件满足,做空SellShort(lots,Open-i_offset);PlotNumeric("Open2",Open);Return;if(MarketPosition=1) /当前持多仓时/止盈if(High>=(MyEntryPrice*(1+TakeProfit*0.01)MyExitPrice=MyEntryPrice*(1+TakeProfit*0.01);sell(0,Max(MyExitPrice,Open);/PlotBool("sellshort",True);Return; /止损if ( Low <= (MyEntryPrice-Stoploss * MinPoint)MyExitPrice = MyEntryPrice-Stoploss * MinPoint;Sell(0,Min(MyExitPrice,Open);/PlotBool("sellshort",true);Return;/做空条件满足,平多仓,开空仓If(falling=True and Low<firstLow)SellShort(lots,Open);PlotNumeric("Open2",Open);if(MarketPosition=-1)/持空仓时/止盈if(low<=(MyEntryPrice*(1-TakeProfit*0.01)MyExitPrice=MyEntryPrice*(1-TakeProfit*0.01);BuyToCover(0,Min(MyExitPrice,Open); Return;/止损if(high>=(MyEntryPrice*(1+Stoploss*MinPoint) MyExitPrice=MyEntryPrice*(1+Stoploss*MinPoint);BuyToCover(0,Max(MyExitPrice,Open);Return;/做多条件满足,平空仓,开多仓If(rising=True and High>firstHigh)Buy(lots,AvgEntryPrice);PlotNumeric("Open",Open);End测试结果:我们测试采用的是股指1小时线,采用的数据是近三年数据(因为中国股指期货2010年上市),手续费的设置为交易总金额的3%(远高于实盘中手续费(1%左右),可以抵消其他因素造成的偏差,保证结果的有效性),保证金率设置的是10%,参数为默认参数,测试结果的表格如下:优化过程:我们将参数分别进行优化,(这里加上参数从多少到多少,步长为多少,给出最后最好的结果)优化后的交易测试结果为:模拟交易:这里补充上从什么时候到什么时候,用的是什么商品,盈利有多少总结:这个策略还适合什么商品,有什么优势和不足2.3均线型策略2.3.1MACD_MSN策略核心思想:MACD(Moving Average Convergence and Divergence)在均线策略中是一种最常用的指标,它是一种运用短期(通常为12日)移动平均线与长期(通常为26日)移动平均线之间的聚合与分离状况,对买进、卖出时机作出研判的技术指标。其计算公式为:n日EMA=2/(n+1)×当天收盘指数+(n-1)/(n+1)×昨天的n日EMADIF(12,26) =12日EMA-26日EMADEA (N)=最近N日的DIF之和/NN日MACD =(DIFF-DEA)×2本策略中根据对两个不同周期的MACD的计算,并且通过短周期MACD和长周期MACD的穿越情况,判断是做多还是做空。做多条件:前一个bar :短周期MACD<长周期MACD 而当前bar:短周期MACD>长周期MACD。做空条件:前一个bar :短周期MACD>长周期MACD 而当前bar:短周期MACD<长周期MACD。止盈条件:为了让利润充分增长,该策略未加入止盈。止损条件:持多仓时:如果当日开盘价低于前一日开盘价一定幅度,卖出平仓。代码实现:/-/ 简称: MACD_MSN/ 名称: / 类别: 公式应用/ 类型: 用户应用/ 输出:/-ParamsNumeric lots(2);Numeric shortlength(2);/短周期Numericlonglength(13);/长周期Numeric TakeProfit(2); /多少个点数时 止盈Numeric StopLoss(10); /多少个点数时 止损VarsNumericSeriesshortMACD;NumericSerieslongMACD;NumericshortMACD1;NumericShortMACD2;NumericlongMACD1;NumericlongMACD2;Boolbuycondition(False);Boolsellcondition(False);Numericp;NumericmyentryPrice(0);NumericmyexitPrice(0);NumericMinPoint(0);BeginIf(CurrentBar>Max(26,longlength) /前Max(26,longlength)个bar不执行myentryPrice=Q_AvgPrice;/平均入场价p=MinMove*PriceScale;/最小变动幅度shortMACD=calMACD3(26,12,shortlength);/计算短周期MACD/PlotNumeric("shortMACD",shortMACD);longMACD=calMACD3(26,12,longlength);/计算长周期MACD/PlotNumeric("longMACD",longMACD);shortMACD1=shortMACD0;/当前bar短周期MACDshortMACD2=shortMACD1;/前一个bar短周期MACDlongMACD1=longMACD0;/当前bar长周期MACDshortMACD2=shortMACD1;/前一个bar短周期MACD/判断做多条件是否满足If(shortMACD1>longMACD1 and shortMACD2<longMACD2) buycondition=True;sellcondition=false;/判断做空条件是否满足If(shortMACD1<longMACD1 and shortMACD2<longMACD2) sellcondition=True;buycondition=false;/如果当前持多仓,当日开盘价低于止损点,止损If(Open < OpenD(1) - StopLoss*P) And Date!= Date1 and MarketPosition=1)Sell(lots,Open);return;/做多条件满足,做多If(buycondition)Buy(lots,Open);/做空条件满足,做空If(sellcondition)SellShort(lots,Open);End/-/ 编译版本GS2010.12.08/ 用户版本2013/04/12 13:09/ 版权所有msnwzgl/ 更改声明TradeBlazer Software保留对TradeBlazer平台/每一版本的TrabeBlazer公式修改和重写的权利/-测试结果:优化记录:优化后结果:总结:2.3.2MACD_MSN5策略(实际上是MACD_MSN3)MACD_MSN5策略是MACD及其中间指标(DIFF和DEA)的另一种应用方式,它通过DIFF和DEA的正负以及二者穿越情况的判断来确定市场行情适合做多还是做空。其核心思想为:做多条件:DIFF,DEA均为正,DIFF向上突破DEA做空条件:DIFF、DEA均为负,DIFF向下跌破DEA其他条件:DEA线与K线发生背离,为行情反转信号;MACD由正变负为 做空信号,由负变正为做多信号。其中DIFF、DEA、MACD的计算公式为:n日EMA=2/(n+1)×当天收盘指数+(n-1)/(n+1)×昨天的n日EMADIF(12,26) =12日EMA-26日EMADEA (N)=最近N日的DIF之和/NN日MACD =(DIFF-DEA)×2止损条件:当当前bar的开盘价低于上一个bar的开盘价超过一定幅度时,卖出平仓。止盈条件:为了让利润充分增长,不加入止盈条件。实现代码:/-/ 简称: MACD_MSN/ 名称: / 类别: 公式应用/ 类型: 用户应用/ 输出:/-ParamsNumeric lots(1);Numeric StopLoss(10); /多少个点数时 止损Numeric shortlength(12);Numericlonglength(26);VarsNumericSeriesshortMACD;NumericSerieslongMACD;NumericSeriesDIFF;NumericSeriesDEA;Boolbuycondition(False);Boolsellcondition(False);Numericp;NumericmyentryPrice(0);NumericmyexitPrice(0);NumericMinPoint(0);BeginIf(CurrentBar>Max(26,longlength)myentryPrice=Q_AvgPrice;MinPoint=MinMove*PriceScale;DIFF=calDIFF(shortlength,longlength); /计算DIFFDEA=calDEA(shortlength,longlength); /计算DEAp=MinMove*PriceScale;If(DIFF>0 AND DEA>0 AND CrossOver(DIFF,DEA) /判断做多条件是否满足buycondition=True;sellcondition=false;If(DIFF<0 AND DEA<0 AND CrossUnder(DIFF,DEA) /判断做空条件是否满足sellcondition=True;buycondition=false;If(Open < OpenD(1)*(1-Stoploss/100) And Date!= Date1 )/止损SellShort(lots,Open);return;If(buycondition)/做多条件满足,做多Buy(lots,Open);If(sellcondition)/做空条件满足,做空SellShort(lots,Open);End/-/ 编译版本GS2010.12.08/ 用户版本2013/04/12 13:09/ 版权所有msnwzgl/ 更改声明TradeBlazer Software保留对TradeBlazer平台/每一版本的TrabeBlazer公式修改和重写的权利/-测试结果:2.4路径型策略2.4.1DBox策略DBox 策略是起源于美国一个专业舞蹈演员同时也是在股票市场上获得很大成功的Nicolas Darvas上世纪50年代所使用的策略。这个策略本质上属于一个突破跟踪策略。它使用一种称之为“box”的概念,当价格突破box的上下边界时进行交易。一个box由“bottom”(底部)和“top”(顶部)组成,bottom和top的形成和改变如下:1,如果价格在最近3个bar中都未创新高,那么高于后3个bar的最近的新高价就成为box的顶部。2,如果价格在最近3个bar中都未创新低,那么低于后3个bar的最近的新低价就成为box的底部。3,如果当前bar的最高价高于box的顶部或者低于box的底部,那么box被打破,1、2过程重新开始。做多条件:当前bar最高价高于box顶部(注意此时做多后,box被打破)做空条件:当前bar最低价低于box底部止盈条件:持多仓时,如果最高价>=平均入场价*(1+止盈点) 卖出平仓持空仓时,如果最低价<=平均入场价*(1-止盈点) 买入平仓止损条件:持多仓时,如果最低价<=平均入场价*(1-止损点)卖出平仓持空仓时,如果最高价>=平均入场价*(1+止损点) 买入平仓实现代码:/-/ 简称: Dbox_sn/ 名称: Dbox_sn/ 类别: 公式应用/ 类型: 用户应用/ 输出:/-Params:Numericlots(1);NumericBoxlength(3);Numericoffset(1);Numerictakeprofit(2);Numeric stoploss(10);NumericbackLength(5);numeric periodHigh(10);/最高价平滑时回撤周期NumericperiodLow(10);/最低价平滑时回撤周期VarsNumericSeries DayHigh;NumericSeries Daylow;NumericSeries todayHigh;NumericSeriestodaylow;NumericSeriesboxTop;NumericSeries boxBottom;Numeric i_offset;BoolSeries Topestablished(False);BoolSeries Bottomestablished(False);BoolSeriesBoxestablished(False);NumericSeriesTopcount(0);NumericSeriesbottomCount(0);NumericSeriesnewHigh(0);NumericSeries newLow(0);Numeric MyEntryPrice ; /入市价格Numeric MyExitPrice;/出市价格Numeric MinPoint;/止损时最小变动单位Beginif(CurrentBar<=Max(periodHigh,periodLow)dayHigh=high;dayLow=Low;elsedayHigh=AverageFC(dayHigh,periodHigh); /对最高价格平滑处理dayLow=AverageFC(dayLow,periodLow);/对最低价平滑处理MyEntryPrice=AvgEntryPrice;i_offset = offset*MinMove*PriceScale; /交易时可接受的价格浮动范围If(CurrentBar<=backlength)todayHigh=high;todaylow=low;If(CurrentBar>backlength)todayHigh=high;todaylow=Low;newHigh=Highest(todayHigh,backLength); /计算近来新高newLow=Lowest(todaylow,backlength);/计算近来新低PlotNumeric("newHigh",newHigh);PlotNumeric("newLow",newLow);If(high<newHigh1 An