- R的极客理想:量化投资篇
- 张丹
- 6315字
- 2023-02-22 21:09:32
1.1 R语言为量化而生
问题
为什么用R语言进行量化投资?
引言
做数据分析的朋友,一定知道R语言。R语言是一门统计语言,在数据分析领域具有非常明显的优势。金融本身是重视数据的行业,而R的最大优势就是数据分析,所以将R语言与金融相结合,用R来做量化投资的策略,真的很配,不仅顺手而且方便,用了你就会知道。
本章以“R语言为量化而生”作为本书的开篇,主要强调了R语言在量化投资领域有着广阔的应用场景,而且是重要的量化投资工具。
1.1.1 为什么是R语言
R语言是一门面向数据的编程语言,早期只是在统计领域被统计学家所使用。近年来随着大数据技术的发展,以及R语言自身生态的快速壮大,不仅在统计领域,在各大行业领域中都能看到R语言的身影,包括互联网、数据科学、人工智能、机器学习、生物医疗、游戏、电子商务、全球地理科学、数据可视化等。
R语言不仅能把数据分析做好,而且能通过数据连接到我们每个人的日常生活,让我们能够有更多的思考。比如,去超市购物,你购买的东西会记录在你的购物小票中,如果把这些购物小票都收集起来,通过Apriori关联规则的频繁项集算法,就可以分析出你的购物习惯。
再比如,我们经常会收到各种推销的骚扰电话,有时候是卖房,有时候是银行贷款,有时候是股票推荐,有时候是代开发票,还有时候是“猜猜我是谁”,此时我们可以收集自己的通话记录,通过电话号码、号码注册位置、通话时长来分析一下,哪些是有用通话,哪些是浪费时间的通话,从而计算出我们每一天会浪费多少时间,通过Bayes算法把有效通话和无效通话进行二元分类,从而阻止骚扰电话的入侵。
如果我们不仅能够收集自己的通话记录,还能把亲戚朋友或更多人的通话记录都收集起来,组建成一个数据库,再把统计出来的骚扰电话统一标记,做成黑名单,然后把黑名单公开出来,就可以让更多的人免受骚扰电话的影响。
人们的衣食住行都会产生数据,产生数据的地方,就需要做数据分析。通过数据分析,可以提高生活的效率,为我们节约宝贵的个人时间。
在人类社会中,人们除了衣食住行的基本需求外,更多是对钱的需求。我们每天都会跟钱打交道,会有消费的需求,月底会有工资收入,当收入大于消费,资金积累到一定阶段的时候,我们就会有投资的需求。中国人的投资一般就几种,买房、买黄金、买股票、买保险、买理财。投资时,很多人是不理性的,心血来潮就买了,也不仔细观察行情,买完很容易被套住,像“中国大妈抢购黄金”“中国大妈是救市的主力军”等事件都一度被新闻媒体热炒。
在金融市场中最不缺的就是机会,不管投资什么,如果能在交易的时候多思考一下,结果说不定就会不一样。运用我们数据分析的知识和对金融市场规则的理解,通过R语言进行数据分析,抓住机会,就会让我们辛辛苦苦赚到的钱得到保值和增值。
1.1.2 跨界结合
R语言与其他编程语言的最大不同在于,R语言是面向数据的,这一点很重要,甚至影响了我们的思维模式。我写了10多年的Java程序,程序员的思维模式在我的脑子里根深蒂固。我习惯用面向对象的思想来建模,把现实世界中的物体、行为、连接都用面向对象的方法来表达。我也习惯了IT项目的开发模式,从架构设计到开发的自上而下的设计思路,再到完全由需求驱动的敏捷开发,以及为业务随需而变的开发路径。作为程序员,我有理想,我自认为技术能改变世界,而这一切都是程序化思维在影响着我。如果你还不熟悉什么是面向对象,请参考《R的极客理想——高级开发篇》第4章。
后来,当我接触了R语言,通过另一扇门理解世界的时候,我发现世界是不一样的。在没有程序的世界里,你可以通过文字来表达你做事的方法,你可以感性地认识世界,也可以让数据来说出这个世界的意义。你可以天天看新闻联播,了解国家大事;也可以看微博、朋友圈的爆料,及时了解身边的消息。这并不是程序员的思维,而是大众化社会的想法。在这个社会里,程序员只是小众群体。
改变世界的方法,除了技术还有别的,比如,政策、资本、市场、法律、人事等,从公司运作的层面看,似乎哪个都比技术更重要。也许程序员并不关心这些,但面对市场时,再牛的技术也会被其他因素所制约。
我经历过创业,一个很深刻的教训就是,要让自己跳出原有的思维定式,通过多维的视角看世界、看自己。R语言帮我打开了通过数据看世界的窗口。我的能力提升不再局限于如何把程序写得多么漂亮,或是在时间复杂度上用O(log(N))解决O(N^2)的问题,而是开始关注怎么收集数据,怎么提高数据质量,来解决实际的业务问题。当然,由于程序员与生俱来的职业强迫性,我也会要求自己熬夜一晚上把50行代码优化成40行。
由上可见,问题被转化了,虽说术业要有专攻,但作为一个有理想的极客,全面掌握跨领域的知识才是我们的目标。我创业时经常被投资人问到,做量化投资的项目有多难?招几个金融背景的人才,再招几个IT背景的人才,捣鼓个项目,不是很快就做出来了吗?其实不然,不同行业背景的人是很难交流和沟通的,尤其是金融和IT行业:一种是封闭不愿意分享,一种是开放毫无保留;一种是先把话说出来,一种是先把事情做起来;一种是所有人都要为我服务,一种是只专注于自己的兴趣。所以,如果不是能够跨界通吃的人,是做不好量化项目的。
我们要立志做个跨学科的人,这才是最核心的点,是不可被替代的。从IT技术出发,你需要扎实的编程功底及架构思想、科学的项目管理方法、严谨的产品设计逻辑;你还需要具备统计、数学等基础学科的知识,以及数据挖掘与机器学习的数据处理经验;最重要的,不管是量化投资或其他的领域,你要能结合业务,理解市场的规则(如图1-1所示)。
图1-1 跨界结合
这听起来很难,实际上也确实很难!虽然很难,但不光是对你,对所有人都是这么难。只要你能坚持下来,一定能通过知识改变命运。
1.1.3 R语言量化工具包
做量化投资,R语言的优势在哪?R语言可以帮助我们从多种维度去理解量化投资。R语言本身就是我们需要掌握的IT技术,是一个需要编程的技术活,但却极大地降低了对编程的要求,短短20~30行R语言代码,已经能干很多事情了。R语言是面向数据的,可以让我们方便地对数据进行处理,同时对数学、统计等基础学科有丰富的函数支持,还提供多种数据挖掘和机器学习的算法库,让我们可以直接使用。
量化领域更是R语言的强项,有针对投资研究的包,有做回测分析的包,有做金融产品定价的包,有做投资组合优化的包,还有风险管理的包,涵盖了量化投资的方方面面,只是有些包的使用要针对中国市场的特点进行改进和优化。
R语言为量化投资提供了丰富的工具包,具体分类如下。与R语言相比,再也没有哪种语言会拥有这种支持了。
❑数据管理:包括数据集抓取、存储、读取、时间序列、数据处理等,涉及的R包有zoo(时间序列对象)、xts(时间序列处理)、timeSeries(Rmetrics系时间序列对象)、timeDate(Rmetrics系时间序列处理)、data.table(数据处理)、quantmod(数据下载和图形可视化)、RQuantLib(QuantLib数据接口)、WindR(Wind数据接口)、RJDBC(数据库访问接口)、rhadoop(Hadoop访问接口)、rhive(Hive访问接口)、rredis(Redis访问接口)、rmongodb(MongoDB访问接口)、SparkR(Spark访问接口)、fImport(Rmetrics系数据访问接口)等。
❑指标计算:包括金融市场的技术指标的各种计算方法,涉及的R包有TTR(技术指标)、TSA(时间序列计算)、urca(单位根检验)、fArma(Rmetrics系ARMA计算)、fAsianOptions(Rmetrics系亚洲期权定价)、fBasics(Rmetrics系计算工具)、fCopulae(Rmetrics系财务分析)、fExoticOptions(Rmetrics系期权计算)、fGarch(Rmetrics系Garch模型)、fNonlinear(Rmetrics系非线模型)、fOptions(Rmetrics系期权定价)、fRegression(Rmetrics系回归分析)、fUnitRoots(Rmetrics系单位根检验)等。
❑回测交易:包括金融数据建模,并验证历史数据验证模型的可靠性,涉及的R包有FinancialInstrument(金融产品)、quantstrat(策略模型和回测)、blotter(账户管理)、fTrading(Rmetrics系交易分析)等。
❑投资组合:对多策略或多模型进行管理和优化,涉及的R包有PortfolioAnalytics(组合分析和优化)、stockPortfolio(股票组合管理)、fAssets(Rmetrics系组合管理)等。
❑风险管理:对持仓进行风险指标的计算和风险提示,涉及的R包有Performance-Analytics(风险分析)、fPortfolio(Rmetrics系组合优化)、fExtremes(Rmetrics系数据处理)等。
在《R的极客理想》系列图书中,分别对这些包做了介绍。请大家对照包名进行参考。
1.1.4 实战应用
利用R语言的便利性,我们可以很容易地通过上面介绍的这些工具包做一个交易模型。构建一个简单的投资策略,甚至都不需要有太多的代码。
接下来,我就举例说明一下怎样把R语言提供的程序包结合在一起使用。按照下面的步骤做一个简单的交易策略,即基于移动平均线MACD做一个针对全球指数的投资方案。如果你还是金融新手,不了解MACD策略,那么请参考《R的极客理想——高级开发篇》的2.3节。
本文所使用的系统环境:
❑Win10 64bit
❑R:3.2.3 x86_64-w64-mingw32/x64 b4bit
下面是一个简化的量化策略的研究过程,分为如下6步进行。
1)用quantmod包下载数据;
2)用zoo包和xts包进行数据格式标准化;
3)用TTR包进行模型计算;
4)用PerformanceAnalytics包进行指标风险;
5)用ggplot2包进行可视化输出;
6)最后,进行结果分析。
首先,我们要获取数据:个人用户可以通过互联网免费下载数据,专业机构通常都是买专业数据库。这里我们通过quantmod包从Yahoo财经下载数据。我选择了全球5个市场的指数进行比较,代码和名称对应关系如表1-1所示。
表1-1 指数名称和代码
下面我们通过R语言代码,来完成这个交易策略模型的构建。当然,这里只是为了说明整个过程,给大家一个直观的感觉,会省略对于策略的细节处理。
# 加载程序库 > library(quantmod) > library(TTR) > library(PerformanceAnalytics) > library(ggplot2) > library(scales) # 从Yahoo财经下载各全球指数数据 > options(stringsAsFactors = FALSE) > symbols<-c("^GSPC", "^N225", "^HSI", "^STI", "000001.SS") > suppressWarnings(getSymbols(symbols, src = "yahoo", from="2012-01-01")) [1] "GSPC" "N225" "HSI" "STI" "000001.SS" # 取指数价格调整后的数据,合并数据集 > df<-merge(GSPC$GSPC.Adjusted, HSI$HSI.Adjusted, N225$N225.Adjusted, STI$STI. Adjusted, '000001.SS'$'000001.SS.Adjusted') # 对列重命名 > names(df)<-c("GSPC", "HSI", "N225", "STI", "SSE")
接下来,让我们看看数据是什么样子的,并画出全球指数,如图1-2所示。
图1-2 全球指数
# 查看数据前6行 > head(df) GSPC HSI N225 STI SSE 2012-01-031277.0618877.41 NA 2688.36 NA 2012-01-041277.3018727.318560.112711.022169.39 2012-01-051281.0618813.418488.712713.022148.45 2012-01-061277.8118593.068390.352715.592163.40 2012-01-091280.7018865.72 NA 2691.282225.89 2012-01-101292.0819004.288422.262719.832285.74 # 查看数据最后6行 > tail(df) GSPC HSI N225 STI SSE 2017-02-242367.3423965.7019283.543117.033253.43 2017-02-272369.7323925.0519107.473108.623228.66 2017-02-282363.6423740.7319118.993096.613241.73 2017-03-012395.9623776.4919393.543122.773246.93 2017-03-022381.9223728.0719564.803136.483230.03 2017-03-032383.1223552.7219469.173122.343218.31 # 查看数据类型,为xts > class(df) [1] "xts" "zoo"
整个数据集采用从2012年01月03日到2017年03月03日之间数据,数据为xts类型(xts类型是R语言中专用的时间序列类型)。关于xts的详细介绍,可以参考《R的极客理想——工具篇》的2.2节。
# 画出全球指数 > g<-ggplot(aes(x=Index, y=Value, colour=Series), data=fortify(df, melt=TRUE)) > g<-g+geom_line(size=1) > g<-g+scale_y_continuous(breaks = seq(1000,30000,4000)) > g<-g+ggtitle("Gloabel Index") > g
由于各国指数成立时间不同,成份股也不同,导致指数值有的很大,有的相对比较小,所以我们不能用指数大小来判断好坏。通常情况下,我们会转换成收益率进行比较,通过收益率进行度量后,所有标的便都是在同一个维度了。
# 全球指数的每日累计收益率 > ret_df<-Return.calculate(df, method="discrete") > chart.CumReturns(ret_df, legend.loc="topleft", main="Cumulative Daily Returns for Gloabel Index")
收益率越高,说明指数在这期间是表现越多的,我们越应该去投资。图1-3中,日经225(N225)指数大幅超越了其他指数,中国的上证综指(SSE)一起一落波动非常大,标普500(GSPC)走势稳健。
图1-3 全球指数累计收益率
接下来计算指数的平均年化收益率,如果我们把钱一直投资在这些指数上面,那么每年的平均回报是多少呢?
> Return.annualized(ret_df) GSPC HSI N225 STI SSE Annualized Return 0.1133813 0.0619811 0.1927681 0.03696703 0.04817027
这里日经指数(N225)年化回报率是最高的,每年平均有19.28%的年化收益率,与图1-3的累计收益率走势相符。而中国的上证综指(SSE)仅有4.82%的年化收益率,回报不算高,且波动太大。综合来看,标普500(GSPC)其实是投资的首选,11.34%年化收益率,平均波动率也不是太高,所以风险和收益都是相对不错的。
接下来,我们构建一个简单的MACD模型,通过MACD策略再对上面5个指数构建交易策略。
> # MACD策略模型 > MACD<-function(dt, n=30){ + names(dt)<-c('close') + + # MACD移动平均均线 + dat<-na.locf(dt) + dat$ma<-SMA(dat$close, n) + + # 交易信号 + sig_buy<-which(dat$ma-dat$close>0) + sig_Sell<-which(dat$ma-dat$close<0) + sig_buy<-sig_buy[which(diff(sig_buy)>1)] + sig_Sell<-sig_Sell[which(diff(sig_Sell)>1)] + if(first(sig_Sell)<first(sig_buy)) sig_Sell<-sig_Sell[-1] + if(last(sig_Sell)<last(sig_buy)) sig_buy<-sig_buy[-length(sig_buy)] + + # 交易清单 + trade_dat<-do.call(rbind.data.frame, apply(cbind(sig_buy, sig_Sell),1, function(row){ + dt[row[1]:row[2], ] + })) + + # 计算收益率 + ret_trade<-Return.calculate(trade_dat, method="discrete") + return(ret_trade) + } # MACD策略每日收益率 > macd_ret<-lapply(df, function(col) MACD(col,30)) # MACD策略,年化收益率 > t(do.call(rbind.data.frame, lapply(macd_ret, Return.annualized))) GSPC HSI N225 STI SSE close 0.2137435 0.2406476 0.2261996 0.01869112 0.2817241
我们写了一个MACD的策略函数,相当于建模的过程,函数的输出即策略的收益率。然后,我们把指数数据传给MACD()函数,经过计算输出策略收益率。最后,把策略收益率与纯指数收益率放到一起来进行对比,如表1-2所示。
表1-2 收益率对比
从表1-2中我们可以很明显地看出,用一根均线的MACD策略,平均年收益率会大幅优于纯指数的收益率,也就是说,如果我们这样交易,就可以赚到更多的钱。其实,这就是量化投资的思想,从数据中发现规律。可能上面的过程和代码会让你觉得很迷惑,怎么就能赚到钱了?别着急,本节只是本书的开篇,等你仔细阅读了全书,就能领悟到这里的玄机了。
上面的实例用40行左右的代码就完成了很多事情。如果要把整个操作都细分列举出来,包括数据采集、数据清洗、数据标准化、指标计算、数据建模、历史回测、投资组合构建、组合优化、计算结果评价、数据可视化等组成部分,其操作步骤如图1-4所示。
图1-4 量化程序操作步骤
要搭建一套量化交易的系统,主要就是完成图1-4所示的这些步骤。对于个人玩家来说,按照上面R语言代码的思路,就已经可以实现了。如果你想做得更好,不仅是个人玩,而是通过成立公司把系统做大做强,为更多的用户提供量化服务,那么你还需要有一整套的平台架构方案,同时配合你要做的金融业务。
1.1.5 量化交易平台系统架构
R语言很强大,但R语言不是万能的。如果要搭建完整的量化投资平台,我们不仅需要R的建模部分,更多的还需要依赖IT部分来搭建起整套系统架构。下面我们先来了解一个量化投资平台需要哪些平台化的模块,如图1-5所示。
图1-5 量化交易平台系统架构
图1-5中各业务模块定义如下:
❑数据采集系统:主要用于采集证券、期货等金融产品的交易数据,证券产品的财务数据,以及宏观指标数据和互联网数据等。
❑数据平台系统:用于数据存储和数据访问,实现统一的数据访问的接口。
❑在线研发系统:让开发者通过API进行在线策略开发,开发者可以直接使用平台的数据,策略提交后自动化完成策略回测。
❑回测系统:对用户已提交的策略进行历史数据的回测,并进行打分和评估。
❑策略系统:把回测验证后的策略,进行信号的可视化展示,在交易时间实现实时数据刷新,帮助开发者更直观地理解策略信号。
❑优选系统:从回测已验证的策略中,选出符合一定条件的策略进行模拟交易。
❑模拟交易系统:运行策略产生策略信号,进行模拟买卖。
❑模拟会计系统:对模拟交易进行每日的会计核算。
❑策略超市:从模拟会计系统选出符合一定条件的策略,放入策略超市,开放给投资人。
❑投资组合:投资人从策略超市中选出多个策略,组建投资组合。
❑实盘交易系统:根据投资组合中的策略信号,进行实盘的自动化交易。
❑实盘会计系统:对实盘交易进行每日的会计核算。
❑风控系统:对实盘的策略进行风险监控,一旦实盘策略遇到黑天鹅事件,将马上切断交易,并通知投资人调整投资组合。
❑指标系统:以宏观数据为基础,让用户可以通过自定义的方式,创建自己理解的指标,并以个人的名义进行发布和分享。
❑策略周刊:每周选出平台中公开的、表现比较好的策略,以报告形式进行发布和推广。
❑BBS社区:在BBS社区进行沟通,解决用户在软件使用中的各种问题。
接下来我们换一个角度,从系统架构看,整套IT系统主要分为4大模块:数据部分、计算部分、展示部分、交易部分。我们把图1-5的内容转化为用技术架构来描述,如图1-6所示。
图1-6 技术架构
❑数据部分主要包括2类数据,历史数据和实时数据。历史数据的特点是种类繁多,数据量巨大,用于回测和建模。实时数据的特点是及时性要求高,用于交易。数据部分主要通过Java来构建,以保证系统的可靠性、稳定性和高性能。
❑计算部分主要是各种算法的应用,包括指标计算、历史回测、实时估值、数据挖掘等(这些是R语言擅长的,并且用Docker进行隔离,可以有效地分配计算资源)。计算部分主要通过R来完成。R让建模变得简单,几分钟就可以把想法落地变成模型。
❑展示部分主要是把计算的结果在PC或手机上进行可视化,以友好的方式将收益和风险水平反馈给用户。展示部分主要是用Javascript来完成,可以让可视化有更好的体验。
❑交易部分主要是对接交易所的交易通道,让我们可以用真钱去交易,让分析结果得到价值的体现,让技术得以变现。交易部分主要是用C++技术,以保证交易的及时性。
从整体的结构来看,R语言是大脑,是帮助我们决策的最核心的部分,而决策也是量化投资过程中最复杂的部分。量化投资本身是一个跨学科的领域,需要系统的、科学的方法才能把这些事情做好。
本书是一个起点,希望大家跟着我的思路,从R语言入手,体会R语言建模的乐趣,并真正地把技术变现。我认为R语言是非常好的一门语言,从量化投资的角度,我会一直推动R语言在中国的发展,并把它当成一项事业来做。同时,本书也会译成英文版在全球发行,让中国的技术走出去。加油!!