1.引言

量化投资主要是将现代数学理论和金融数据结合起来的一种全新的分析方法,在海外己有30年的发展历史,其投资业绩稳定,市场规模和份额不断扩大,得到越来越多的投资者的认可。量化投资在国外金融领域己经得到广泛应用,尤其在近十年来的国际投资界发展迅猛,并己经连同基本面分析、技术面分析并称为三大主流方法。现代数学理论和金融数据的结合,再加上计算机快速运算的配合,使得量化投资具有了系统、准确、高效等投资优势,并将投资决策发挥得淋漓尽致。
量化投资主要包括量化策略、量化投资交易策略、资产配置、交易执行及风险管理等几个方面的内容。量化策略主要是决定总体投资方向,需要确定投资选取的行业、风格、产品,也就是投资者考虑确定投资什么市场、选择什么产品,在不同市场上的投资如何分配变换。量化投资交易策略主要是决定如何进行投资,选取什么样的策略进行投资,是主动预测式策略还是被动事件驱动反应式策略。回归分析(regression analysis)和动量模型(momentum  modeling)仍然是量化投资者使用最广泛的投资交易策略。资产配置主要是决定资产的投资如何分配,首先根据行业选择进行配置,然后在行业内通过策略组合进行资产优化及构建。交易执行主要是通过计算机程序来实现完成投资交易过程,交易执行可以通过证券/期货公司交易站点或交易所专线直连方式实现。对于个人投资者,一般采用证券/期货公司交易站点的方式,而大型机构投资者,由于对实时性及效率要求较高,一般采用交易所专线直连方式。如果交易量较大,在交易执行过程中,可以采用算法交易,通过 VWAP 或 TWAP 模型将交易分拆以降低交易成本。风险管理主要是针对投资产品的市场及组合进行风险控制,可以通过风险价值模型进行测算及度量,实时判断当前投资的风险程度,当投资组合出现亏损时给出预警,甚至自动执行止损平仓。从风险分析模型来看,使用最多的就是方差模型(Variance),其次依次为:在险值模型(VaR)、下方风险模型(Downside  Risk)、条件在险值模型(CVaR)、极值模型(EVT)。 
总之,量化策略决定投资的大方向,投资交易策略决定投资的收益性,资产配置决定投资的平衡性,交易执行决定投资的实时性,风险管理决定投资的安全性。几个环节缺一不可,相互循环促进。

2.理论模型

2.1移动平均线

移动平均线(MA,Moving average)是以道·琼斯的”平均成本概念”为理论基础,采用统计学中”移动平均”的原理,将一段时期内的股票价格平均值连成曲线,用来显示股价的历史波动情况,进而反映股价指数未来发展趋势的技术分析方法。它是道氏理论的形象化表述。 移动平均线的计算方法就是求连续若干天的收盘价的算术平均。天数就是MA的参数。在技术分析领域中,移动平均线是必不可少的指标工具。移动平均线利用统计学上的“移动平均”原理,将每天的市场价格进行移动平均计算,求出一个趋势值,用来作为价格走势的研判工具。 计算公式: MA = (C1+C2+C3+C4+C5+….+Cn)/n ,C为收盘价,n为移动平均周期数。 例如,5日移动平均价格计算方法为:MA5 = (前四天收盘价+前三天收盘价+前天收盘价+昨天收盘价+今天收盘价)/5 移动平均线依时间长短可分为三种:短期移动平均线,中期移动平均线,长期移动平均线。短期移动平均线一般以5日或10日为计算期间,中期移动平均线大多以30日、60日为计算期间;长期移动平均线大多以100天和200天为计算期间。

2.2两条均线模型

一条均线模型,在大的趋势下是可以稳定赚钱的,但由于一条均线对于波动 ,非常敏感性,如果小波动过于频繁,不仅会增加交易次数,而且会让模型失效。然后,就有二条均线的策略模型,可以减低对波动的敏感性。 二条均线策略模型,与一条均线模型思路类似,以5日均线价格替换股价,是通过5日均线和20日均线交叉来进行信号交易的。 以下用上证指数进行两条均线模型的模拟分析。 首先取出上证指数的调整股价收盘价作为我们的收盘价,并利用rollapply函数进行计算30日移动平均股价,她的计算方式就是开头金融背景分析提到的方式,比如今天的30日平均股价就是前29天的加今天的收盘价的平均值。 首先画出从2014年1月1日到2015年12月1日的上证指数每日的收盘价,并在此基础上加上30日移动平均走势图,画上绿色。 很多人的交易策略如下:当股价上穿30日均线则买入,下穿30日均线则卖出。那他的原理是什么呢?我们说30日均线是沪、深股市大盘的中期生命线,每当一轮中期下跌结束指数向上突破30日均线,往往会有一轮中期上升。对于个股来说,30日均线是判断有庄无庄、庄家出没出货以及其走势强弱的标准。30日均线有着非常的趋势性,无论其上升趋势还是下跌趋势一旦形成均很难改变。 当然有些交易系统交易策略更加繁杂,比如有人的卖出策略还会加入止损率,如果你的止损率是5%,就是说如果今天的收盘价比昨天的收盘价低5%,你就会卖出你的股票,即使你的股价和30日均线还没有达到卖出的交点。这样可以及时减小损失。 但是使用股价和30日均线的交易策略有一点问题,就是日股价的波动太大,会导致交点过多,这样的频繁交易会产生大量的手续费和印花税,同时也会使我们的模型失效,于是回归到我们的题目,叫做两条均线打天下,我们选择波动相对较小两条均线的交点作为我们的交易判断点。他们分别是5日均线和20日均线。

3.数据来源及预处理

3.1数据来源

quantmod为R语言中分析股票走势的包,本文将利用其中的getsymbols()函数获取2015/1/1至2017/8/25的上证综指,上海证券综合指数简称“上证指数”或“上证综指”,其样本股是在上海证券交易所全部上市股票,包括A股和B股,反映了上海证券交易所上市股票价格的变动情况,上证综合指数是最早发布的指数,是以上证所挂牌上市的全部股票为计算范围,以发行量为权数的加权综合股价指数。这一指数自1991年7月15日起开始实时发布,基日定为1990年12月19日,基日指数定为100点。得到的数据如下

getSymbols('^SSEC',scr="yahoo",from="2015-01-01",to="2017-08-25")
## 'getSymbols' currently uses auto.assign=TRUE by default, but will
## use auto.assign=FALSE in 0.5-0. You will still be able to use
## 'loadSymbols' to automatically load data. getOption("getSymbols.env")
## and getOption("getSymbols.auto.assign") will still be checked for
## alternate defaults.
## 
## This message is shown once per session and may be disabled by setting 
## options("getSymbols.warning4.0"=FALSE). See ?getSymbols for details.
## 
## WARNING: There have been significant changes to Yahoo Finance data.
## Please see the Warning section of '?getSymbols.yahoo' for details.
## 
## This message is shown once per session and may be disabled by setting
## options("getSymbols.yahoo.warning"=FALSE).
## [1] "SSEC"
data=data.frame(SSEC)
data[1:5,]

数据包含日期、开盘价、收盘价、最高价、最低价、成交量、调整后的收盘价。

3.2数据预处理

从数据中可以看到,数据的日期变量为行名称,因此需要将行名称提取出来转换为时间变量,并赋值给日期变量time列,增加到原数据中.

time=row.names(data)
time=ymd(time)
data%<>%
  mutate(time=time)
data[1:5,]

4.探索性分析

4.1缺失值分析

为了避免原始数据在时间上不连续,所以新建一个连续的时间序列,利用left_join通过关键字“time”匹配出原始数据中隐藏的缺失值,然后对数据缺失的原因进行分析。

c=ymd('2015.1.1')+days(0:967)
Time=data.frame(time=c)
data=left_join(Time,data)
## Joining, by = "time"

为了分析缺失值与具体时间的关系,将年份、月份、号数分别提取出来,并新增星期数变量,便于分析。

data=data %>%
  mutate(year=year(time)) %>%
  mutate(month=month(time)) %>%
  mutate(day=day(time)) %>%
  mutate(week=wday(data$time,label=TRUE,abbr=FALSE))

首先,由于周六、周日和上证所公告的休市日不交易,所以直接删掉周末的缺失数据。

data=data %>%
  filter(week %in% c('星期一','星期二','星期三','星期四','星期五'))

然后,将数据中剩余的缺失行提取出来进行进一步分析,发现股市停盘时间除了国家法定节假日外,还有2015年9月3号和4号,而这两天是抗战胜利70周年纪念日,所以停盘。经过分析可知,该数据集中不包含异常停盘时间。

data_na=data %>% filter(is.na(SSEC.Open))

4.2 股票成交量

成交量是一种供需的表现,说明市场的活跃度和资金规模,是判断市场运行趋势与方向的重要参考依据之一。所以首先画出成交量的时间趋势图。发现2015年股票交易规模巨大,成交量远远高于2016及其之后的年份。数据显示,2015年中国内地的股票成交量增长186%,至101亿笔,股票交易额上涨218%,至43万亿美元。对于中国股市成交额与成交量的双双飙升,申万宏源投资顾问石磊认为,2015年中国股市成交量的攀升与内地股市的热度息息相关。巨额成交量背后是中国股市的“散户热”。截止到2016年1月21日,中国股市的市场投资者数量突破1亿;其中非自然人仅占28.73万,大约每14个人中就有1人是股民。然而在美国,三大证券交易所个体散户日均成交量仅占总体成交量的11%。基于2015年的股票巨大成交量,将2015年的数据提取出来进行重点分析。

data=data[!is.na(data$SSEC.Open),]
data %>%
  ggplot(aes(x=time,y=SSEC.Volume)) +
  geom_line()

data_2015=data %>%
  filter(year==2015)
data_2015 %>%
  ggplot(aes(x=time,y=SSEC.Volume)) +
  geom_smooth(se=FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

可以看到2015年的成交量从一月份开始上升,在六月达到顶点,开始暴跌,这也符合”暴涨之后必有暴跌“的股市规律,此前宽松的流动性在监管松弛的环境下催生了资产泡沫,是泡沫就难免会破裂,特别是当泡沫越吹越大的时候,流动性泛滥与实体经济投资机会缺乏,导致了“资产荒”的出现。由于坏账率飙升、房地产投资下滑,大量银行资金不愿投向信贷,而是通过场外配资、融资融券等方式入市,成为股市加杠杆的主要资金来源,是导致股市泡沫的重要原因。

4.3 股票振幅

振幅是股价能量的晴雨表。一般来说,在低位震幅大好,在高位震幅大不好。股票市场的震荡幅度收缩,一方面意味着游资的转移,另一方面也意味着这一市场投机性相对减弱。股票 价格波动趋于稳定,有利于市场更好地实现价值发现的功能。这不能说是市场投资价值的回归,但是可以说是股市股资属性的回归。这种变化是好是坏很难说,至少那些习惯于在股价波动做投机的投资者会感到不太适应。 在股票分析中,股票振幅在一定程度上表现股票的活跃程度,这与股票成交量的作用类似,所以两者应该有较强的相关关系,我们也将在接下来的分析中验证这一点。 首先,增加股票振幅、股票最大涨幅和股票最大跌幅这三个变量,然后再进行画图分析。

data=data %>%
  mutate(zf=(SSEC.High/SSEC.Low)-1) %>%
  mutate(up=(SSEC.High/SSEC.Open)-1) %>%
  mutate(down=(SSEC.Low/SSEC.Open)-1)
data$zf=round(data$zf,5)
data$up=round(data$up,5)
data$down=round(data$down,5)
ggplot(data=data)+
  geom_smooth(aes(x=time,y=zf),se=FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

ggplot(data=data)+
  geom_point(mapping=aes(x=zf,y=SSEC.Volume))+
  geom_smooth(mapping=aes(x=zf,y=SSEC.Volume),se=FALSE)
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

可以看出,股价振幅的时间趋势图与股票成交量的时间趋势图相似度很高,这也证明了这两者都是反映股票活跃程度的指标。为了进一步验证这两个指标之间的相关性,又画出了用这两个指标拟合的散点图和曲线图,从图中可以看出,一方面,股票交易量随着振幅的增大而增大,另一方面交易量的方差也在增大,说明股价振幅越大,市场越活跃,包含的不确定性因素越多。

4.4股票市场的季节效应

对数据按月份分组,计算每月的平均收盘价,然后对数据拟合曲线,可以看出股票市场中存在明显的季节效应,主要包括:“春季行情”:年初以后到两会之前,股票市场往往会出现春季行情,主要表现为股指的上涨;“五穷六绝七翻身”:5月下跌压力大,6月更加弱势,7月常常出现反弹;“红十月”:10月上涨概率高,整个四季度股票表现都偏强势。对于投资者而言,研究市场和行业的季节效应对于获取超额收益或是回避潜在的风险无疑是有益的,但正如古诗所说“年年岁岁花相似,岁岁年年人不同”,市场中的季节效应并非每年都能够精确的到来。因此,了解季节效应产生的原因,并从当年的实际情况出发进行研判比对着日历“刻舟求剑”更为重要。

mymean=function(data){
  mean(data$SSEC.Close)
}

data%>%
  group_by(month)%>%
  nest()%>%
  mutate(mean=map_dbl(data,mymean))%>%
  ggplot(mapping=aes(x=month,y=mean))+
    geom_smooth()
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

4.5成交量与振幅的模型拟合

本部分对股票成交量与股价振幅建模,想进一步证明振幅与成交量是存在正相关的。

sim1=tibble(x=data$zf,y=data$SSEC.Volume)
sim1_mod<-lm(y~x,data=sim1)
summary(sim1_mod)
## 
## Call:
## lm(formula = y ~ x, data = sim1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -437834  -66866  -30257   38331  525489 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   163725       7407   22.11   <2e-16 ***
## x            5542843     291058   19.04   <2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 123800 on 645 degrees of freedom
## Multiple R-squared:  0.3599, Adjusted R-squared:  0.3589 
## F-statistic: 362.7 on 1 and 645 DF,  p-value: < 2.2e-16
grid<-sim1 %>%
  data_grid(x)
grid<-grid %>%
  add_predictions(sim1_mod)
ggplot(sim1,aes(x))+
  geom_point(aes(y=y))+
  geom_line(
    aes(y=pred),
    data=grid,
    colour='red',
    size=1
  )

sim1 <- sim1 %>%
  add_residuals(sim1_mod)
ggplot(sim1,aes(x,resid))+
  geom_ref_line(h=0)+
  geom_point()

虽然两者存在正相关,但从模型拟合结果来看,模型残差仍然包含关于自变量的信息,并且随着自变量的增大,因变量的方差有增大的趋势。

4.6利用Bootstrap模拟邹至庄检验

Bootstrap是非参数统计中一种重要的估计统计量变异性,并可进行统计量区间估计的统计方法,也称为自助法。其核心思想和基本步骤如下: (1) 采用重复抽样技术从原始样本中抽取一定数量(可自己给定,一般与原始样本相同)的样本,此过程允许重复抽样。 (2) 根据抽出的样本计算待估计的统计量T。 (3) 重复上述N次(一般大于1000),得到N个统计量T。 (4) 计算上述N个统计量T的样本方差,以此估计统计量T的方差。 应该说Bootstrap是现代统计学较为流行的一种统计方法,在小样本时效果很好。通过方差的估计可以构造置信区间等,其应用范围得到进一步延伸。 邹检验是指一种统计和计量经济学的检验。它可以测试两组不同数据的线性回归系数是否相等。在时间序列中,邹检验被普遍地用来检验结构性变化是否存在。其本质是比较两个回归,检验模型的结构稳定性???所谓模型的结构稳定的指模型在样本期的不同时期(子样本),其参数不发生改变。而任何参数样本期的不同时期发生改变,则称模型不具有结构稳定性。一般而言,导致模型发生结构变化的因素是重要的外生事件,或外生冲击,故常设定某一时点或年份,以此将样本分为二个子样本,分别估计这二个子样本和样本全体,构成F统计量,据此推断模型是否发生结构变化。理论认为邹氏统计量服从F分布,本文将利用bootstrap方法模拟统计量的分布,进而计算检验的p值

getSymbols('^SSEC',scr='yahoo',from='2017-04-01')
## [1] "SSEC"
data=data.frame(SSEC)
data%<>%
  mutate(time=ymd(rownames(.)))%>%
  mutate(days=.$time-ymd('20170401'))
ggplot(data,aes(x=days,y=SSEC.Adjusted))+
  geom_point()+
  geom_line()+
  geom_smooth()
## Don't know how to automatically pick scale for object of type difftime. Defaulting to continuous.
## `geom_smooth()` using method = 'loess' and formula 'y ~ x'

从股票走势图明显看出,2017年中上证综指股价跌到最低点,然后逐渐回升,因此本文将利用bootstrap对两个阶段的数据进行邹至庄检验,证明两个阶段的数据发生了结构性变化。 首先建立整个数据的线性模型,提取整体模型的残差平方和s_c.

mod_c=lm(SSEC.Adjusted~days,data)
s_c=deviance(mod_c)

接着,查询股价最低点即结构变化点

data[data$SSEC.Adjusted==min(data$SSEC.Adjusted),]

然后,分别建立两部分时间序列的模型,提取各自的残差平方和

mod_before=lm(SSEC.Adjusted~days,data[1:25,])
s_before=deviance(mod_before)
mod_after=lm(SSEC.Adjusted~days,data[26:99,])
s_after=deviance(mod_after)

计算样本统计量z_sample

z_sample=(95/2)*(s_c-s_before-s_after)/(s_before+s_after)

通过bootstrap随机采样,获得统计量的分布

N=1000
z=NULL
for (i in 1:N) {
  sample=sample(1:99,25,replace = T)
  mod_be_boot=lm(SSEC.Adjusted~days,data[sample,])
  s_be_boot=deviance(mod_be_boot)
  mod_af_boot=lm(SSEC.Adjusted~days,data[-sample,])
  s_af_boot=deviance(mod_be_boot)
  z_boot=(95/2)*(s_c-s_be_boot-s_af_boot)/(s_be_boot+s_af_boot)
  z=c(z,z_boot)
}
z=data.frame(count=z)
ggplot(z,aes(x=count))+
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

计算检验P值

(sum(z>z_sample)+1)/(1000+1)
## [1] 0.01798202

在p值为0.05的显著性水平下即能拒绝两个时期的时间序列结构未改变的原假设,即认为,上证综指的股价在2017年5月10日发生了结构性改变。其现实原因为,2018年上半年,上证180指数在诸多内外部因素叠加共振下,震荡下行。从内部因素来看,宏观经济增长动力减弱,“强监管”、“去杠杆”、“防风险”持续推进,债券信用风险暴露速度加快,融资成本持续上升,流动性紧张担忧加剧;外部因素来看,美联储加息和中美贸易摩擦不断发酵,市场不确定因素增加。最终,上证180指数于上半年末收于7571.95点,上半年下跌12.43%。验证了本文的数据变化。

5.实证分析

本文选用IBM的股票,时间从2010年1月1日到2019年1月4日。首先取出IBM的调整股价收盘价作为我们的收盘价,并利用rollapply函数进行5日和20日移动平均股价的计算。首先画出从2010年1月1日到2019年1月4日的IBM的5日和20日移动平均股价。如图所示:

getSymbols('IBM',src='yahoo',from='2010-01-01')
## [1] "IBM"
#取调整股价
data<-IBM[,'IBM.Adjusted']
names(data) <- 'close'


#计算5日移动平均
rollmean5 <- rollapply(data$close, width = 5, FUN = mean)
rollmean5 <- rollmean5[!is.na(rollmean5)]
data.df5 <- as.data.frame(rollmean5)
time=row.names(data.df5)
time=ymd(time)
data.df5%<>%
  mutate(time=time)


#计算20日移动平均值
rollmean20 <- rollapply(data$close, width = 20, FUN = mean)
rollmean20 <- rollmean20[!is.na(rollmean20)]
data.df <- as.data.frame(rollmean20)
time=row.names(data.df)
time=ymd(time)
data.df%<>%
  mutate(time=time)
data=as.data.frame(data)
time=row.names(data)
time=ymd(time)
data%<>%
  mutate(time=time)
#画出IBM的5日和20日移动平均股价
ggplot(data.df,aes(x=time,y=close))+
  geom_line(color="yellow")+
  geom_line(data=data.df5,aes(x=time,y=close),color="red")+
  geom_line(data=data,aes(x=time,y=close))

names(data.df)[1]='close20'
names(data.df5)[1]='close5'
data_mix=data %>%
  left_join(data.df) %>%
  left_join(data.df5) %>%
  filter(!is.na(close20))
## Joining, by = "time"
## Joining, by = "time"
Juggpoint <- function(ldata){
    result <- as.data.frame(ldata)
    tmp <- as.data.frame(ldata)
    for(i in 1:nrow(ldata)){
        if (ldata[i,4] > ldata[i,3]){
            tmp$close[i] = "Up"
        }
        if (ldata[i,4] <= ldata[i,3]){
            tmp$close[i] = "Down"
        }
    }
    result <- cbind(ldata$time,as.data.frame(tmp$close),result$close20)
    colnames(result) <- c("Date","Series","Value")
    return(result)
}
pdata=Juggpoint(data_mix)
pdata[1:2,]

两条均线策略模型是通过5日均线和20日均线交叉来进行信号交易的,当5日移动平均股价大于20日移动平均股价则买入,反之则卖出,因此设计上述函数来判断交叉点,当20日均价小于5日均价时,将该点的变量值设置为”up“,反之设置为”down“。最终得到的数据如图。

drawLineWithColor <- function(ldata,pdata,titie="Stock_MA",sDate=min(ldata$time),eDate=max(ldata$time)){
    g<-ggplot(mapping = aes(x=Date))+
      geom_point(data=fortify(pdata,melt=T),mapping=aes(y=Value,color=Series))+
      geom_line(data=ldata,mapping=aes(x=time,y=close5,color='red'))+
      geom_line(data=ldata,mapping=aes(x=time,y=close20,color='green'))+
      labs(title = titie,subtitle = paste(sDate,'to',eDate))
    g
}
data_mix$time=ymd(data_mix$time)
pdata$Date=ymd(pdata$Date)
drawLineWithColor(data_mix,pdata)

当5日股价上穿20日均线则买入,并从这一点开始把20日均线画成紫色,下穿20日均线卖出,并从这一点开始化成红色。如图所示,我们以三点覆盖20日均线,紫色点为买入持有,红色点位卖出空仓。可以从图中看到,红色点和紫色点在20日均线上交替出现,我们可以在每次紫色出现的第一个点买入股票,然后在红色的第一个点卖出股票。 如图所示:从第一个紫色交易点进行买入,然后再接下来的两年不停的卖出和买进,直到最后一个红色交点处。这样一买一卖,肯定是有偶数个交点的,如果一共有2n个交点(第一个点买,第2n个点卖),那么每个奇数点都是买,每个偶数点都是卖。 设最开始的时候本金是m元,每个交点的调整股价是Xi,那么剩下的钱为: m*Xi(所有偶数点的乘积)/Xi(所有奇数点的乘积) 利用交易信号数据,进行模拟交易。我们设定交易参数,以$10W为本金,满仓买入或卖出,手续为0,传入交易信号。 通过模拟交易,可以精确地算出每笔交易的盈利情况,有26笔交易是亏损的,10笔交易是有盈利的。查看最后的资金情况,资金剩余96828.9元,亏了3171.1元.为什么最后会亏损呢?中间的大波段应该赚到了足够多的钱。通过资金曲线我们可以找到亏损的原因。 把股价和现金流量并排放置,从2010-09开始均线策略开始大幅赚钱,到2011-10到达最高点,并且超过了本金,然后开始下滑,截止到2012-01亏损3859.86元。这是由于我们把赚到的利润继续投资,增大了头寸,以至于2011年底的股市震荡让模型失效,从而赔了更多的钱。 那么这个结果是不是说明我们的均线策略是无效果的呢?. 其实从交易的角度来讲,上面的模型还不算完成,还有很多的赔钱交易,要进行更多的优化,减少最大回撤,在确定的的时间做多,反向做空等。

6.总结

本文主要是希望尽量用所学R知识处理实际问题,虽然还存在很多不足,但也从中学到了很多。首先,确定了比较有实际价值的研究主题,即量化投资交易策略。第二,数据收集。数据是利用quantmod包中的getsymbols()函数获取的。第三,数据处理。由于数据是时间序列数据,很容易发现数据是不连续的,含有大量缺失值,所以首先对数据缺失原因进行了分析,再通过R的dplyr和tidyr等包中的函数对数据进行细致的处理,最后得到易于分析的整洁数据。第四,数据可视化。对重要变量的分布情况、异常值、解释变量与被解释变量间的关系都做了细致的可视化。第五,建模。对关心的变量进行了回归建模。第六,使用R Markdown 完成所有的工作,虽然存在有些显示不太美观的问题。总之,通过此次编程及写作,对R的理解又进了一步。