“工欲善其事,必先利其器”。
在 如何搭建量化投资研究系统?(数据篇)中,作者介绍了如何依靠网络爬虫收集整理交易数据,搭建一个金融数据库。在数据的问题基本解决之后,量化投资的研究工作就要正式启动了。根据人类思维的一般规律,一项复杂的研究工作,通常以“个别、感性、直观”的方式开始,在获得了基本的认识和灵感之后,再逐步上升到“整体、理性、抽象”的认知。所以,量化投资研究的第一步就是——“看盘”,下面介绍如何在R中利用quantmod包“优雅、高效”的看盘。
一、quantmod简介
quantmod的全称是Quantitative Financial Modelling & Trading Framework for R,quantmod的设计目标是在R中为量化交易者开发、测试和评估交易策略提供一个统一的计算框架。设想可以说是雄心勃勃,但是在仔细浏览quantmod的官方网站(quantmod: Quantitative Financial Modelling Framework)之后可以感觉到,目前quantmod还不能说是一个“完成品”,特别是和交易策略相关的部分,完成度不高。不过就已经完成的部分来看,quantmod在数据的获取、操作和可视化方面做得相当好。
二、数据获取
在quantmod中获取数据非常方便,quantmod提供了一系列“包装器函数”(“包装器”是一种常用的设计模式)从若干数据源获得金融数据,包括股票和指数数据、汇率数据和期权数据等等。
quantmod中获取股票和指数交易数据的函数是getSymbols,以平安银行和上证指数为例,运行
PAB <- getSymbols("000001.SZ",
from = "2014-01-01",
to = "2015-07-01",
src = "yahoo",
auto.assign = FALSE)
SSI <- getSymbols("000001.SS",
from = "2014-01-01",
to = "2015-07-01",
src = "yahoo",
auto.assign = FALSE)
就轻松获得了平安银行和上证指数的数据。还可以采用另外一种方式,先配置要参数
setDefaults(getSymbols,
auto.assign = FALSE)
setSymbolLookup(PAB = list(name = "000001.SZ",
from =
"2014-01-01",
to =
"2015-07-01"),
SSI = list(name = "000001.SS",
from = "2014-01-01",
to = "2015-07-01"))
PAB <- getSymbols("PAB")
SSI <- getSymbols("SSI")
需要解释一下,上交所和深交所的后缀分别是“.SS”和“.SZ”;from和to分别代表起始时间;src表示数据源(默认以雅虎财经为数据源);auto.assign表示是否自动声明变量(这里取消了自动声明);setDefaults为函数设置默认参数;setSymbolLookup为要取的数据设置参数。
如果不想用网络数据源,getSymbols也可以读取本地csv文件。假设PAB.csv保存有交易数据,文件内容分别是时间、开高低收、成交量和复权价,运行
setSymbolLookup(PAB = list(src="csv",
format = "%Y-%m-%d"))
PAB <- getSymbols("PAB")
就可以读取csv中的数据。
getSymbols函数返回的对象的类型是xts,事实上xts类型的对象只要包含“开高低收”和“成交量”的标签,就可以使用quantmod中的大部分函数。如果已经按照《数据篇》的方法建立了数据库,运行
col.names <- c("Open", "High", "Low", "Close", "Volume", "Adjusted")
P <- dbGetQuery(con,
"select
date, open, high, low, close, voturnover
from iQI.equity_trading
where
code = '000001'
order by date asc;")
P.xts <- xts(P[,-1],
order.by = as.Date(P[,1]))
names(P.xts) <- col.names[1:5]
P.xts和PAB一样可以使用quantmod中的函数。
quantmod中获取股票分红和配股数据的函数是getSymbols和getSplits,运行
setDefaults(getDividends,
src = "yahoo")
setDefaults(getSplits,
src = "yahoo")
PAB.div <- getDividends("000001.SZ")
PAB.spl <- getSplits("000001.SZ")
分别可以获得平安银行的分红数据和配股数据。
既然用quantmod获取数据如此简单,为什么还要用《数据篇》里的方法自己搭建数据库呢?(在不能翻墙的前提下)雅虎财经是最常用到的数据源,但是雅虎的业务重点并不包括中国,所以中国财经数据的质量难免要打一个折扣。举个例子,平安银行在2015-04-10的收盘价是19.80,而qantmod得到的数据却是16.50;上证指数只有收盘数据,成交量数据是0。
三、数据可视化
金融数据的可视化可以说是quantmod的一大亮点,有大量的作图函数可供选择,而且使用方式非常简便灵活。quantmod中作图的主函数是chartSeries,运行
chartSeries(PAB)
就能画出平安银行的K线图。
平安银行K线图
quantmod默认的绘图风格是美式的,如果想要调整风格或其他参数,需要调用reChart函数,运行
cn.theme <- chartTheme(up.col = "red",
dn.col = "green")
reChart(name = "平安银行",
subset = "2015",
theme = cn.theme,
type = "candlesticks")
平安银行K线图
chartTheme函数用来产生一个控制绘图风格的对象;name用来修改图片标题;subset用来对数据对象做“切片”操作(quantmod通常处理xts类型的对象,xts的切片操作非常灵活和人性化,具体用法请查阅xts包的文档);theme用来设置风格;type用来设置绘图类型(这里设置成“蜡烛图”)。
四、技术指标
quantmod在K线图中添加技术指标的操作非常灵活方便,有两种方式,分别是调用内置函数和自定义指标。常用的技术指标大多都可以在quantmod的内置函数中找到,比如在上图中添加MACD和布林带,可以运行
addMACD()
addBBands()
MACD&布林带
每个指标函数都可以调整具体的参数设置(具体的用法请阅读文档)。
添加自定义指标分为两种方式,一种是调用addTA函数直接添加;另一种是调用newTA函数生成技术指标对象。
如果把收盘价对数值及其指数移动平均作为一种技术指标,运行
addTA(cbind(EMA(log(Cl(PAB))), log(Cl(PAB))),
col = c("red", "green"),
type = c("o", "o"),
pch = c(20, 20),
legend = "LogClEMA")
自定义指标(方法一)
另一种方式
LogClEMA <- function(x)
{
return (cbind(log(Cl(x)),EMA(log(Cl(x)))))
}
addLogClEMA <- newTA(FUN = LogClEMA,
col = c("red", "green"),
type = c("o", "o"),
pch = c(20, 20),
legend.name = "LogClEMA")
addLogClEMA()
自定义指标(方法二)
如果要去掉某个指标,需要调用dropTA函数,函数的参数是要去掉指标对应的函数名,比如去掉成交量
dropTA("addVo")
去掉“成交量”
有些金融数据并不包含“开高低收”和成交量信息,只是单纯的一列或几列数据,这时如果用chartSeries绘图应该设置图形的类型为“线图”,以基金“华夏成长”的累计净值为例
par(pch = 20)
chartSeries(HXCZ$anv,
col="green",
subset = "2015",
type = "line",
line.type = "o",
name = "华夏成长")
“华夏成长”累计净值
如果要添加技术分析指标,方法和前面讲的一样。
五、数据计算函数
quantmod提供了一系列函数对数据对象做基本的操作和计算,这些函数和前面讲的数据可视化功能结合起来,对研究工作带来的帮助可谓如虎添翼,也许束缚人的只剩下想象力。
1.提取型函数
函数Op、Hi、Lo、Cl、Vo和Ad分别用来提取交易数据中的开盘价、最高价、最低价、收盘价、成交量和复权价;HLC、OHLC和OHLCV分别提取高低收、开高低收和开高低收成交量;seriesHi和seriesLo分别提取每一列数据中的最高值和最低值。
2.标记型函数
seriesAccel、seriesDecel、seriesIncr和seriesDecr分别标记序列中的节点是否处在加速、减速、增长和下降的状态;findPeaks和findValleys分别标记出局部最高和局部最低点。以seriesIncr为例
par(pch = 20)
chartSeries(Cl(PAB),
col="green",
subset = "2015-05::",
type = "line",
line.type = "o",
name = "平安银行")
addTA(seriesIncr(Cl(PAB)),
col="red",
legend = "incr")
peak <- Cl(PAB)[findPeaks(Cl(PAB))-1]
addTA(peak,
col = "red",
type = "p",
on = 1,
legend = "peak")
valley <- Cl(PAB)[findValleys(Cl(PAB))-1]
addTA(valley,
col = "yellow",
type = "p",
on = 1,
legend = "valley")
平安银行收盘价
其中红色的时间段内收盘价在持续增长,红色和黄色的点分别对应局部最高和局部最低点。
3.平移函数
Lag和Next用来向后和向前平移数据
4.对比型函数
函数OpCl、ClCl、HiCl、LoCl、LoHi、OpHi、OpLo和OpOp 分别计算开高低收四种价格的相对变化程度;Delt计算前后不同时期数据的相对变化程度。
5.收益率计算函数
quantmod中计算收益率的主函数是periodReturn,在参数中设置周期就可以计算出不同周期对应的收益率;dailyReturn、weeklyReturn、monthlyReturn、quarterlyReturn、yearlyReturn和allReturns分别计算每日、每周、每月、每季度、每年和所有的收益率。
以华夏成长为例,计算累计净值的收益率,并画出收益率直方图和密度曲线
hist(dailyReturn(HXCZ$anv)*100,
breaks = 50,
probability = TRUE,
main = "华夏成长",
xlab = "returns")
lines(density(dailyReturn(HXCZ$anv)*100),
lwd = 2,
col = "red")
lines(density(weeklyReturn(HXCZ$anv)*100),
lwd = 2,
col = "green")
lines(density(monthlyReturn(HXCZ$anv)*100),
lwd = 2,
col = "blue")
legend(x = -4, y=0.8,
legend = c("daily","weekly","monthly"),
lty = c(1,1,1),
lwd = c(2,2,2),
col = c("red", "green", "blue"))
每日收益率的直方图及3条密度曲线
6.除权函数
adjustOHLC用来计算复权价,方法有两种,一是利用网络数据源(雅虎财经)的分红配股数据计算;二是输入复权因子作为参数来计算。
六、总结
以上简单介绍了quantmod的使用方法,权当是抛砖引玉,要真正做到灵活应用全面掌握,还是应该多加写代码多看文档,最后用一张思维导图总结一下quantmod中的常用函数。
quantmod常用函数