• Archive by category "金融"
  • (Page 3)

Blog Archives

2016天善智能交流会第22场: R语言为量化而生

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员Java,R,Nodejs
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-hellobi-20160701/

meeting-hellobi

前言

感谢天善智能社区的邀请,有幸参加每周一期的跟数据有关的行业、工具、技术的交流盛宴,活动的口号是“Friday BI Fly 周五BI飞起来”。

目录

  1. 我的分享主题:R语言为量化而生
  2. 会议体验
  3. 自由讨论

1. 我的分享主题:R语言为量化而生

本次分享的主题 R语言为量化而生,主要内容来自我的一篇博客文章:R语言为量化而生。希望能够解释清楚,在量化投资中为什么要用R语言。从程序员的角度看,C++,Java,Python, C#都是可行方案;从数据人员的角度看,Excel, SAS, Matlab更是不错的。那么为什么是R语言呢,R语言的优势在哪里体现?

这类的问题,总是会被问到。那么答案,就在于你对量化这件事情的了解,和对各种编程语言的理解。最近3年,互联网在量化领域的大发展,以Quantopian为代表的在线策略研发平台,用Python做为核心语言,国内同样支持Python的平台也有 优矿聚宽米筐。这些平台主是面向程序员群体的平台,希望通过挖掘草根明星,来推动量化的发展。传统的量化交易软件,像文华MC, TB, TS 都有自己一套的脚本化的编程语言。有实力的专业团队,通常会自成体系的独立开发一套自己的系统。如果面向更广泛的人群,最常用的方法就是Wind导数据,Excel中拉个表出来。

所以,其实用什么语言不重要,关键是怎么理解做量化这件事情。那么R语言的天生优势就是数学计算,数据处理,免费开源,大量支持库。试试吧,你一定会喜欢的。

2. 会议体验

本次分享受天善智能社区的邀请,我真的非常高兴。天善智能是新一代的商业智能和大数据的垂直社区,聚集了大量的数据分析从业人员。活动介绍,https://ask.hellobi.com/blog/tianshansoft/4229。 本次活动同时有30个微信群进行直播,参加的人员,至少有2000人以上。可以天善智能社区,在行业的影响力是非常大的。

发个截图,体会一下微信同步直播的震撼吧!

wx

本此的分享基于微信的直播,我也第一次体验,要用纯文字的方式来进行介绍。想把一个事情说清楚,又增加了不少的难度。由于不能分享屏幕,代码部分会通过图片截屏。

本次活动的总结,https://ask.hellobi.com/blog/tianshansoft/4271,感谢天善社区的工作人员进行整理。

远程分享,就是没能与大家合照,有点遗憾!!贴张自己的照片吧。

01

3. 自由讨论

分享后,很多朋友都对于R语言都是非常的好奇,提了很多的问题,用户的参与性非常强。下列直接贴出用户的问题和我的回复。

1、替新手问一个,请教一下,R语言的数据分析应该从哪方面入手练习啊?因为目前工作上不是用R的,看完书之后想具体去试一下。

张丹: R其实上手很快,找一本书,认真操作练习一遍就上手了。

2、玉琴:不建议用for loop的原因是考虑到性能问题吗

张丹:for loop是调用的R的循环库,apply是调用C的循环库,性能差距还是很大的

3、来自20群的提问:提个问题,微软对R的收购会对R语言的发展产生什么影响?

张丹:我觉得这是正向发展的,是好事情。大公司看到了R的潜力!

4、尚林栋:R语言金融建模的具体步骤能说一下吗

金融建模的具体步骤,你可以参考这篇文章,http://blog.fens.me/finance-stock-ma/

5、刘嘉丰Alan:丹哥,现在有很多量化平台,提供打包好的函数,在线回测,和自己造轮子拿R语言相比,您觉得各有什么优势呢?

张丹:R的优势就是在数学计算,数据处理上。行业标准还没有统一,所以不一定在线平台的轮子就一定好用。但另外,我们从开发或使用的角度,更多的用到的R包,都是RStudio公司的产品,我觉得是RStudio在推动R的整个的进化过程。

6、我也觉得r语言不错,但经常想不到商业场景,到现在,我只是用它统计考勤,各种绩效kpi,每月算一次奖金,已经这样过去2年了,r语言路在何方哪?

张丹: 你所说的统计,只能说简单计数。比如,你要预测下个月的考勤情况,从而设计预算方案。你可能就需要做个回归分析,这时R就能给你很大的帮助了。生活和工作中,随处都是数据分析的场景。

7、Allen:r在拟合上感觉比python用起来更爽一些,其返回的结果较多

张丹:那么R和python比,R更面向数据,特别是对于没有编程基础的人。PYTHON,还是程序语言,还要了解程序结构,程序架构,代码量不会少。

有IT背景程序员,可能更倾向于PYTHON;如果没有IT背景,R更容易上手。

8、越中女儿:请教一个问题:quantmod对美股的实时接口很好用,对A股不支持,且A股基本面数据才更新到2013.09,请问有好用的ETL包么,类似于python的tushare那样对A股友好的,各种etl啊清洗的脏活累活感觉python更好啊,R就是安安静静做做统计,玩玩图形。

张丹: quantmod使用的是yahoo等国外的数据源,这些数据源本身没有A股数据,如果需要A股数据,用tushare还是不错的。 R特有的data.frame,matrix 等类型和操作方法,在python也需要单独去实现。

9、柠檬味的香草:最近想研究一些互联网文本数据与指数或各股走势的关系,但是在使用R语言处理文本数据不是很方便,丹哥可有一些强大的library推荐,对于非结构,文本数据的处理。

张丹:“尽量使用向量计算或矩阵计算的计算方法”,可以这样理解,对于一个二维结构,for需要2次,0(N^2)的时间复杂度。如果我们把数据,直接就按矩阵存储, 你让矩阵里的每个点都加1, 只需要算一次。Hadley提供的包,源代码我都看过,写很棒,也很实用。

r在拟合上感觉比python用起来更爽一些,其返回的结果较多

其实R有很多的第三方的包,已经有了大量的算法包,而其他语言相对较少。只是我们平时接触的不多,所以觉得用不到。R有大量的统计包,你可以从官方网站找到,输出的结果,大部分也都是统计的结果。

R所支持的行业领域,非常广泛。而工程的语言,不会做细粒度的区分,只是通用的解决方法。

10、郑州—金融数据:python有pandas.DataFrame,pandas应该是第三方的数据库结构吧?R的data.frame是内置的。

张丹:pandas.DataFrame,在底层处理,还需要对原PYTHON的数据结构做映射。当然他可以解决的很好,但你看到的内存结构,可能并不是真正的内存结构。

R内置数据类型,就可以理解是内存结构。不需要再考虑转换了。找一个自己熟悉的语言,大多数的功能,每种语言都是能实现。只有很细的领域,才会进一步区分。

11、RHaoop采用分布式并行计算,那请问如何解决需要嵌套循环的算法。

张丹:对于基于hadoop大数据的MR计算,建议做数学变成,通过数学的角度处理。我写过2个例子,一个是pagerank, 一个是itemcf。

12、@柠檬味的香草:想听听丹哥对传统数据挖掘转量化投资的建议。比如前景?竞争力?

张丹:量化投资,其实是IT人都想转的行业。你写的代码,不是通过工资来赚钱,而直接通过交易赚钱,代码的效用是最大化的。但这个行业竞争很大,聪明人都在这里,要么你的技术牛,要么你了解市场,要么的算法是独特的,不然也很难。

JhT: 做量化交易和策略的都是高智商的

越中女儿:我觉得量化对金融市场的理解比对技术本身更重要,R的需求应该会很快凸显出来。因为数据基础都有了,后面就是差会分析的人了。通常懂数据分析的程序员,比纯程序员待遇高。

13、老师,有好的spark或者hadoop入门的书吗,计算机能力弱和java不懂啊

张丹:hadoop有很多书了,我当初看的是 权威指南。spark的书不了解,我的是网上文档。

14、@Mia.W 学RHadoop需要对Hadoop或Mapreduce了解到什么程度,需要从头学hadoop或java吗

张丹:hadoop的MR的原理要了解,找到懂JAVA的同事,帮你把环境搭好。

15、@JhT 我是刚进来的,R的优势是什么?

张丹:R是免费开源的,CRAN上有8000多个包,遍布各行各业。R语言的3个特性,数学计算,数据建模,可视化。

16、@郑州—金融数据个人感觉商业上matlab比R和python支持度都要好,不管是分析,统计,挖掘还是量化方便,收费的毕竟是收费的

张丹:有商业推动,当然要比免费的好了。不过,像SAS和Matlab也在打通和R的接口,毕竟由全球第三方贡献包,要比一家公司提供的包要多很多的。

17、@越中女儿 有用R做过实盘风控么

张丹:有做,其实不太复杂。你把需要的实时数据,都同步存到redis中,用R在秒级调reids取数据,计算完成再写回去。

18、@Jason.k计算机8g内存,数据虽然行数不多,但是很多列,所以数据csv格式大小会高达几个G,这个规模数据量,内存应该是不够的。

张丹:R的机制,会把数据一次性加载到内存中。就算能读到内存,每次计算时,也会有中间变量,所以你的基础内存是不够的。而且对于win性能会更差。

最后,再次感谢 天善社区的小伙伴们的努力,谢谢大家!

转载请注明出处:
http://blog.fens.me/meeting-hellobi-20160701/

打赏作者

R语言为量化而生

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹(Conan), 程序员Java,R,Nodejs
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-finance/

r-finance

前言

做数据分析的朋友,一定听说过R语言。R语言是一门统计语言,在数据分析领域优势是非常明显的。

本文以 “R语言,为量化而生”为题,说明R语言真的很适合做金融做量化策略。金融本身是玩数据行业,R的最大的优势就是数据分析,所以用R来做量化投资的策略,真是很配,不仅顺手而且方便,用了你就会知识。

本文将由3个方面来介绍,R语言做量化是多么的适合。

目录

  1. 为什么是R语言?
  2. R语言的数据处理和时间序列
  3. R语言和金融模型

1. 为什么是R语言?

那么为什么是R语言,而不是其他的语言? 先简单介绍一下,我们的个人经历。

我是一个程序员,从2004年开始接触Java写了10多年的Java程序,期间还尝试过多种编程语言,VB、PHP、Python、SAS、R、Nodejs,最后把自己锁定在R,Nodejs和Java。谈不上对每一种语言都有很深的理解,但是每种语言的特点还是有点心得。

之所以选择R,Nodejs和Java这3种语言,有一部分情怀,更多的是理性。从技术发展来看,编程开发变得越来越简单,10年前用JavaEE做一个简单的web项目至少要2人月,现在用Nodejs新人边学边搞只需10人天。而且随着业务的多样化,单一的技术已经不足以支撑业务的发展,业务在从传统的软件开发向互联网和数据产品的方向在进化。根据不同语言的特点,每种都将在开发中占据一席之地,而很难在出现一种语言统一天下的情况。

R语言将在数据分析领域发挥着重要的作用。R语言的3个特性,数学计算、数据建模和数据可视化。R语言封装了多种基础学科的计算函数,我们在R语言编程的过程中只需要调用这些计算函数,就可以构建出面向不同领域、不同业务的、复杂的数学模型。

另外,R的知识体系结构是复杂的,要想学好R,就必须把多学科的知识综合运用,而最大的难点不在于R语言本身,在于使用者的知识基础和综合运用的能力。

r-basic

图中我将R语言知识体系结构分为3个部分:IT技术 + 业务知识 + 基础学科。

  • IT技术:是数据大发展时代必备的技术之一,R语言就是我们应该要掌握的一门技术。
  • 业务知识:是市场经验和法则,不管你在什么公司,你都了解业务是什么,产品是什么,用户是谁,公司的价值在哪里!
  • 基础学科:是我们在学校里学到的理论知识,虽然当初学的时候并不理解,工作中如果你还能掌握并实际运用,那么这将是你最有价值的竞争力。

关于R的知识体系,可以参考文章,R语言知识体系概览

对于金融量化投资来说,刚好是一个交叉学科,你需要懂IT技术,熟悉金融市场的规则,有数学建模的能力。R语言,正好可以帮我们来解决这样的问题,所以“R语言,为量化而生”!

对于做过数据分析的人来说,大家都了解什么是最费时间的!!无疑就是数据处理的部分。

2. R语言的数据处理和时间序列

第二部分,我们来介绍一下R语言的数据类型和数据处理的一些方法。当然,本文并没有介绍如何入门R语言,新手入门请参考文章R的极客理想系列文章

2.1 基本数据类型

在R语言中,数据类型包括向量类型,字符串类型,数字类型,布尔类型,矩阵类型,数据框类型,list类型等,通常我们在使用R语言里做数据处理的时候,大部分都会以数据框(data.frame)类型为一个主要的数据内存类型来使用。

数据框(data.frame)类型是R语言内置的一种数据类型,我们可以简单地把它理解为,与关系型数据库中表的结构是类似的,是一种二维的数据结构。


# 新建一个数据框
> data.frame(A=1:6,B=LETTERS[1:6])
  A B
1 1 A
2 2 B
3 3 C
4 4 D
5 5 E
6 6 F

正是由于R语言内置了这样的数据类型,使我们从数据库读取数据或导入CSV格式的数据时,与R语言有了一个很好的映射关系,直接加载到R语言的内存中变成标准化数据格式。

然后,就可以基于标准化的数据格式,用R语言的功能函数来处理数据了。比如,对于做数据库开发的人员来说,他可以使用sqldf包,在R语言中通过SQL语句对数据进行数据变换。同时,也可以按着数据框(data.frame)的标准方法进行数据处理,通过约定的向量索引下标的方式来按行按列来读取数据,或使用功能函数处理数据。


# sqldf包的使用
> library(sqldf)
> sqldf('select * from iris limit 6')
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

# 向量索引
> iris[1:6,]
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

# head函数使用
> head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

我们经常还会对数据进行转型处理,把数据框(data.frame)类型和其他数据类型的进行转化。我们有时会使用矩阵计算,R语言中默认供了矩阵(matrix)数据类型,可以很方便地把数据框转类型成矩阵类型,有时也需要把数据框的某一行或某一列转型为一个向量类型数据,或者把数据框变成一个list类型。通过数据的格式变换,用标准化的数据结构来满足数据分析的要求。

虽然R语言是统计语言,从性能上来说比C++/Java等语言慢不少。但对于数据分析的业务场景,用R语言来做数据处理的时候,你不用考虑程序如何架构,指针怎么定义,内存是否会泄露,只要关注你的数据和算法就行了。唯一需要注意的一点,不要直接用for循环的方式处理数据,尽量使用向量计算或矩阵计算的计算方法。当必须用循环的时候,你就需要用apply家族函数,代替for循环来做数据处理。关于apply家族函数的用法,请参考文章掌握R语言中的apply函数族

如果你的数据量比较大,1GB,10GB,甚至有100GB,对于这种规模比较大的数据集,apply的计算方式就不太能满足计算性能的要求了。你依然可以用data.table包, bigmemory包, ff包等,或者并行计算的包加速R语言在单机上的计算的性能。data.table的使用方法,请参考文章超高性能数据处理包data.table

那么再大规模的数据,超过1TB这个量级,不只是R语言,每种语言都会遇到计算性能的瓶颈。这个时候,我们需要把数据放到分布式系统中,如Hadoop或其他大数据的引擎中进行存储和计算。R语言与各种的大数据平台的通信接口都是通的,比如RHadoop,rhive, rhbase, rmongodb, rCassandra, SparkR, sparklyr等。如果你想了解hadoop的知识,请参考文章Hadoop家族系列文章RHadoop实践系列文章, R利剑NoSQL系列文章 之 Hive

2.2 时间序列类型

除了R语言的内置基础数据类型,对于金融的数据处理,一般我会把它变成标准的时间序列类型的数据,R语言中基本的时间序列的类型为 zoo 和 xts类型,当然还有一些其他包提供的数据类型。关于zoo和xts的详细介绍,请参考文章 R语言时间序列基础库zoo可扩展的时间序列xts

通过类型变换可以很方便地把的data.frame或者matrix等基础类型数据,变成xts时间序列类型的数据。时间序列类型的好处是它默认会以时间作为索引,对于量化策略来说,每条数据记录他都会有数据产生的时间,那这个时间就正好可以作为索引列的时间。


# 数据框
> df<-data.frame(A=1:6,B=rnorm(6))

# xts时间序列类型
> xdf<-xts(df,order.by=as.Date('2016-01-01')+1:6);xdf
           A           B
2016-01-02 1 -1.24013232
2016-01-03 2 -0.21014651
2016-01-04 3 -1.63251615
2016-01-05 4 -0.67279885
2016-01-06 5  0.01487863
2016-01-07 6  0.92012628

# 类型检查
> class(xdf)
[1] "xts" "zoo"

那么以时间作为数据的索引列的好处是,可以很方便地把数据以时间维度进行对齐。比如,你设计了一个股票交易策略和一个期货交易策略,由于股票是T+1交易,今天买了明天才能卖;而期货是T+0交易,今天买了马上就可以卖出。针对不同的市场规则,在设计交易策略时,可能就会选择不同的交易周期,那么这时两个策略的交易周期就会不一样,那么时间维度可能也不是对齐的。如果这两个策略是对冲的,那么我们就需要把它们以时间维度进行对齐,才能进行实现对策略模型对冲的准确计算。

把不同时间的维度的数据转化成同一个时间维度,相当于做时间的标准化。通过标准化的操作,让数据变成同一时间维度,数据之间才能够进行计算。

举个简单的例子,我们做股票交易,在实盘交易过程中,你可能最关心的是每秒最新的价格数据,每一秒都会产生一条数据,这是属于日内交易策略。另外,我们再做一个周期稍微长一点的策略,以日线为基础的,那么这里一条记录就是一天收盘价。对比日内策略,1秒钟一条数据和1天一条数据,它们不同维度的数据,是不能直接进行计算。

我们要处理这种不同周期维度数据的时候,就需要把数据转成同一个维度的。比如,我们对日线和周线的数据进行合并的时候,可以是把周线数据拆成日线数据,就是把一周分成五天。反过来,也可以把日线数据合并为周线数据,把5天的数据合并成一周。

所以这个时候就需要一个统一的数据格式进行标准化的数据定义,zoo和xts就是我们作为时间序列基础数据类型。这两个包是由第三方开发的,提供了很丰富的时间序列处理函数,我们可以直接使用这些函数来操作金融数据。很多其他的第三方金融算法分析包,也都是以这两个包作为基础开发。

3. R语言和金融模型

当我们掌握了R语言处理数据的方法,了解了如何使用R语言的基础数据类型和时间序列数据类型,下面我们就可以构建金融的策略模型。

金融建模跟其他行业的数据建模是类似的,只是由于行业不一样,金融行业有很多背景知识和金融市场规则需要我们了解。金融本身就是一个玩数据的行业,你可以通过获得交易数据,财务数据,上市公司的各种事件数据,基本面数据,宏观数据,舆情数据,互联网数据等,来构建你自己的交易策略。

我们需要把这些数据进行组合整理,结合你自己对业务的理解,使用R语言从数据中发现规律,并构建交易模型。用程序对历史数据进行回测,来验证规律的可靠性,是否会长期有效,并控制风险,最后把验证过的规律变成算法模型,这个就是金融策略建模的过程。

从金融交易分析的角度,可以从3个维度进行分析 基本面分析,技术面分析和消息面分析。

  • 基本面:指对宏观经济、行业和公司基本情况的分析,包括公司经营理念策略、公司报表等的分析。长线投资一般用基本面分析,通过基本面可以判断是否值去交易。
  • 技术面:指通过技术指标变化,判断股票走势形态,进行K线组合等,通过技术面可以判断如何进行交易。
  • 消息面:指上市公司发布的利好和利空的消息,通过消息面可以判断市场的情绪。

对于量化模型,大部分都是基于技术指标的模型,通过技术指标建模,跟踪市场的表现。在不完全了解金融业务和金融市场的情况下,通过几个技术指标来监控市场的走势,发现市场的机会也是有可能的。

量化交易和主观交易并不是对立的,量化交易是对主观交易的补充,当我们以数据作为决策基础的时候,其实可以尽量减少拍脑袋过程,创建数据模型也可以给我们心里建立良好的信心。如果交易没有使用量化的方法,那就跟我们平时做事一样,你可能想到什么就是什么。没有数据基础,那完全就是感觉,这样子交易就是很容易赔钱。

对于中国很多的散户,听到一个消息就跟着风的买卖股票,或者凭自己感觉大盘该涨了就跟进去,这些操作其实都是很不理性的。如果你通过量化的方法,即使再简单,就靠几条均线来进行判断,这样也是能给自己一个数据的基础,建立信心,而不是完全拍脑袋的事儿。

量化交易模型主要是以技术指标为主,常用的技术指标有不少,虽然简单但还是很有用的。对于很多实盘上运行的量化策略,大都会基于这些基础的指标,但并不是把每个指标单独使用。而是把多个指标通过变换组合使用,比如说MACD是均线模型,大部分的趋势策略都以MACD做为基础指标,通过变换再生成新的衍生指标。

常用的技术指标还包括KDJ、Boll、RSI、CCI等,当你直接使用这些指标的时候,可能效果并不是太好。因为市场上普遍接受了这些技术指标,已经被大量使用。单纯地用一个指标,你掌握的信息并不比别人多,所以你可能抓不到市场上赚钱的机会。

我们需要把多种技术指标或者多个维度的指标进行结合,通过组合优化的方式来降低策略的不确定风险,同时提高收益率。如果你找到了一个只有你自己知道市场规律,你的策略产生的信号完全是跟别人有区别的,你抓住了别人看不到的机会,这个才是你的赚钱机会。你领先的越多,越少人知道这个规则,那你可能赚钱的机会就越多。

建立量化模型,其实和我们平时做数据分析的思考试是一样的。要把这件事做好,我们需要把IT技术,业务知识和基础学科知识做进一步的结合,当你发现这个结合是属于你自己特有一个知识体系,你才能更好的发挥你的才能。

我们为什么要用R来做这件事情?

首先,R语言本身提供了很多数学、统计的基础包,让数学计算变得非常容易。R语言提供了常用的数据结构,向量、数据框、矩阵等,把数据变成标准化的数据,你的关注点只在数据上就可以了。另外,R语言是免费开源的,很多的第三方开发者提供了丰富的数据挖掘包,让你可以方便的使用各种算法模型,短短几行代码,就可以搞定一个复杂的事情。

R语言,在金融领域提供了很多交易框架或者计算模型,如果你了解了金融的理论知识以后,同时有一定的金融市场经验,你可以很方便的利用这些别人提供的这些技术框架,来构建自己的交易模型。CRAN上发布的金融项目,你可以去 R的官方网站 (https://cran.r-project.org/),找到Task Views 菜单里的 Finance标签。

task

通过调用第三方的程序包,自己的代码量就变的非常少。我们做一个R语言的策略,如果是很复杂的,你可能要写100-200行,但是如果你要实现同样复杂的策略,放到C++/Java去实现,这个策略就是没有1000-2000行是不可能实现的。在CRAN上面,简单数一下Finance标签下面列出的金融包就有141个,我相信没有哪种语言会比R语言对金融行业支持的更多了。

task2

虽然说R语言在性能上有些问题,但是我们会有多少了交易策略是基于一种高频的模型,对性能要求极高的呢?其实很少。就算是高频交易策略,几秒钟交易一次,R语言都可能满足要求。

海量金融数据我们怎么处理呢?

我们可以把基于海量数据的计算变成离线模型,金融行业每天都会产生大量的数据,像每日产生的交易数据,中国市场每天可能都是以GB的量来增长,跟互联网比起来不是很快,但对于你程序加载10年的数据,他要GB或TB的一个量级。

R语言本身真的很难处理这种量级的数据,但是这种量级数据对于其他语言来说同样是很难处理的。我们并不需要把这种体量的数据,都加载到内存中,进行实时数据计算。变成离线的计算模型,仅用于建模回测。把海量数据能变成离线的方式,放到hadoop或spark计算,用海量数据进行模型的训练。

我们用到的实时数据,一般就是一天或几天的数据,会不很大,每天从开盘到收盘可能也就1-2GB,对于这个大小,我们完全有能力放到内存中,进行各种各样的计算。

做量化交易难点还是在于如何发现市场机会,R语言可以很好的满足数据计算,建模,分析等的所有技术的部分。利用你的擅长,找到市场的机会,然后去实盘交易赚到钱,我们就完成了整个的交易过程。

本文并没有介绍,如何用R语言真正的去实现一个交易策略,你可以通过下面的列表找到对应的文章。

2015年我在创业,希望能推动R语言在金融量化领域的发展,但是由于种种原因项目没有持续发展。接下来,我还会以个人的方式继续努力,继续推动R在金融领域的发展。R对我们的影响和改变是非常大的,我认识R是非常好的一门语言,我会把推动R的发展,当成一项事业来做。希望也能和各位业界朋友,一起努力,把这份事业做下去。

转载请注明出处:
http://blog.fens.me/r-finance/

打赏作者

R语言构建配对交易量化模型

用IT技术玩金融系列文章,将介绍如何使用IT技术,处理金融大数据。在互联网混迹多年,已经熟练掌握一些IT技术。单纯地在互联网做开发,总觉得使劲的方式不对。要想靠技术养活自己,就要把技术变现。通过“跨界”可以寻找新的机会,创造技术的壁垒。

金融是离钱最近的市场,也是变现的好渠道!今天就开始踏上“用IT技术玩金融”之旅!

关于作者:

  • 张丹(Conan), 程序员Java,R,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/finance-pairs-trading/

pair-trading

前言

散户每天都在经历中国股市的上蹿下跳,赚到钱是运气,赔钱是常态。那么是否有方法可以让赚钱变成常态呢?

我们可以通过“统计套利”的方法,发现市场的无效性。配对交易,就统计套利策略的一种,通过对冲掉绝大部分的市场风险,抓住套利机会,积累小盈利汇聚大收益。

目录

  1. 什么是配对交易?
  2. 配对交易的模型
  3. 用R语言实现配对交易

1. 什么是配对交易?

配对交易(Pairs Trading)的理念最早来源于上世纪20年代华尔街传奇交易员Jesse Livermore 的姐妹股票对交易策略。配对交易的基本原理是找到两个相关性较高具备均衡关系的股票或其他金融产品,做空近期相对强势的金融产品,同时做多相对弱势金融产品,等待两者价格重返均衡值时进行平仓,赚取两者的价差变动的收益。

假设两个金融产品在未来的时期会保持良好的均衡关系,一旦两者之间的价格走势出现背离,同时这种背离在未来会被进行修复,那么就可能产生套利的机会。对于配对交易来说,就是找到这样的机会,进行统计套利。

配对交易的特点

配对交易与传统股票交易最大的不同之处在于,它的投资标的是两只股票的价差,是一种相对价值而非绝对价值。由于它在股票多头和空头方同时建仓,对冲掉了绝大部分的市场风险,所以它是一种市场的中性策略。无论大盘上涨还是下跌,配对交易策略收益都是相对平稳的,与大盘走势的相关性很低。

在市场无趋势性机会时,可以通过配对交易避免股市系统风险,获取Alpha绝对收益。趋势性的交易策略,可以参考文章 两条均线打天下

配对交易操作方法

  1. 组合筛选:在市场上寻找用于配对的金融产品或者组合,检查历史价格的走势,判断是否可以用来进行配对。主要用下面几个指标来筛选配对组合:相关系数、模型计算的均值回复速度、协整检验、基本面因素等。通过这些因素来寻找出具有稳定相关关系的组合。
  2. 风险衡量和动态组合的构建:计算配对组合各自的预期收益、预期风险、交易成本;判断两个组合之间的价差服从何种分布;判断是具有长期均衡特性还是短期均衡特性;价差发生跳跃的频率等。
  3. 确定交易规则:根据价差的特性,确定交易的频率(高频交易还是低频交易),交易的触发条件和平仓规则等。
  4. 执行交易及风险控制:除了按照交易规则执行外,还必须动态跟踪价差走势,如果发现突变,应该及时调整套利模式和交易频率。

配对交易缺点

  • 统计套利的规则都是基于历史数据计算的,但历史不能代表未来,当市场发生变化模型也会失效
  • 市场对价格进行修复的时间难以准确判断,只能根据历史大致估计。如果回归的时间过长,对套利者的资金使用成本是个考验,也有可能导致套利失败。

2. 构建配对交易的模型

根据配对交易的原理,我们就可以自己设计配对交易的模型了。首先,需要把配对交易涉及的指标都进行量化,比如如何选择不同的两个具备均衡关系金融产品,什么时候做多,什么时候做空,什么时候平仓等。

根据概念,我们生成两个虚拟的金融产品X,Y,包括时间和价格字段。让X和Y的两个产品都价格符合正态分布,生成100个日期的数据。由于是测试程序,日期字段是包括了自然日,暂时理解为连续的日期。

R语言实现的代码如下:


> set.seed(1)                         #设置随机种子
> dates<-as.Date('2010-01-01')+1:100  #100个日期
> x<-round(rnorm(100,50,40),2)        #随机生成X产品,100个正态分析的收盘价 
> y<-round(rnorm(100,50,40),2)        #随机生成Y产品,100个正态分析的收盘价 
> df<-data.frame(dates,x,y)
> df
         dates      x      y
1   2010-01-02  24.94  25.19
2   2010-01-03  57.35  51.68
3   2010-01-04  16.57  13.56
4   2010-01-05 113.81  56.32
5   2010-01-06  63.18  23.82
6   2010-01-07  17.18 120.69
7   2010-01-08  69.50  78.67
8   2010-01-09  79.53  86.41
9   2010-01-10  73.03  65.37
10  2010-01-11  37.78 117.29
11  2010-01-12 110.47  24.57
12  2010-01-13  65.59  31.53
13  2010-01-14  25.15 107.29
14  2010-01-15 -38.59  23.97
15  2010-01-16  95.00  41.70
16  2010-01-17  48.20  34.29
17  2010-01-18  49.35  37.20
18  2010-01-19  87.75  38.84
19  2010-01-20  82.85  69.77
20  2010-01-21  73.76  42.91
21  2010-01-22  86.76  29.76
22  2010-01-23  81.29 103.72
23  2010-01-24  52.98  41.42
24  2010-01-25 -29.57  42.82
25  2010-01-26  74.79  45.99
26  2010-01-27  47.75  78.51
27  2010-01-28  43.77  47.06
28  2010-01-29  -8.83  48.49
29  2010-01-30  30.87  22.73
30  2010-01-31  66.72  37.03
31  2010-02-01 104.35  52.41
32  2010-02-02  45.89  26.44
33  2010-02-03  65.51  71.26
34  2010-02-04  47.85 -10.74
35  2010-02-05  -5.08  62.26
36  2010-02-06  33.40 -11.46
37  2010-02-07  34.23  37.96
38  2010-02-08  47.63  28.87
39  2010-02-09  94.00  23.92
40  2010-02-10  80.53  47.72
41  2010-02-11  43.42 -26.57
42  2010-02-12  39.87  97.06
43  2010-02-13  77.88 -16.60
44  2010-02-14  72.27  31.46
45  2010-02-15  22.45   5.36
46  2010-02-16  21.70  19.97
47  2010-02-17  64.58 133.49
48  2010-02-18  80.74  50.70
49  2010-02-19  45.51  -1.45
50  2010-02-20  85.24 -15.62
51  2010-02-21  65.92  68.01
52  2010-02-22  25.52  49.26
53  2010-02-23  63.64  37.28
54  2010-02-24   4.83  12.83
55  2010-02-25 107.32  -9.50
56  2010-02-26 129.22   6.99
57  2010-02-27  35.31  90.00
58  2010-02-28   8.23  25.15
59  2010-03-01  72.79  -5.38
60  2010-03-02  44.60 124.77
61  2010-03-03 146.06  67.00
62  2010-03-04  48.43  40.45
63  2010-03-05  77.59  92.34
64  2010-03-06  51.12  85.46
65  2010-03-07  20.27  25.23
66  2010-03-08  57.55 138.24
67  2010-03-09 -22.20  39.80
68  2010-03-10 108.62  -6.98
69  2010-03-11  56.13  44.22
70  2010-03-12 136.90  58.30
71  2010-03-13  69.02 142.32
72  2010-03-14  21.60  54.23
73  2010-03-15  74.43  68.28
74  2010-03-16  12.64  46.91
75  2010-03-17  -0.15  36.64
76  2010-03-18  61.66  48.61
77  2010-03-19  32.27  81.51
78  2010-03-20  50.04 133.01
79  2010-03-21  52.97  91.10
80  2010-03-22  26.42  98.32
81  2010-03-23  27.25   0.75
82  2010-03-24  44.59  89.36
83  2010-03-25  97.12  58.80
84  2010-03-26 -10.94  -8.69
85  2010-03-27  73.76  70.84
86  2010-03-28  63.32  43.65
87  2010-03-29  92.52 108.58
88  2010-03-30  37.83  19.36
89  2010-03-31  64.80  32.79
90  2010-04-01  60.68  12.96
91  2010-04-02  28.30  42.92
92  2010-04-03  98.31  66.08
93  2010-04-04  96.42  20.73
94  2010-04-05  78.01  83.21
95  2010-04-06 113.47   1.68
96  2010-04-07  72.34   8.08
97  2010-04-08  -1.06 107.65
98  2010-04-09  27.07   9.37
99  2010-04-10   1.02  66.48
100 2010-04-11  31.06  34.76

把数据进行可视化,可以更直观地理解数据本身。


# 加载R语言类库
> library(ggplot2)
> library(scales)
> library(reshape2)

# 数据转型 
> df2<-melt(df,c('dates'))

# 画图
> g<-ggplot(data=df2,aes(x=dates,y=value,colour=variable))
> g<-g+geom_line()
> g<-g+scale_x_date(date_breaks = "1 week",date_labels='%m-%d')
> g<-g+labs(x='date',y='Price')
> g

01

上图中,X轴为时间,Y轴是价格,红色线为X的产品的价格,蓝色线为Y产品的价格。我们可以直观的看出,X,Y两个产品无任何关系。

根据配对交易的假设条件,如果两个金融产品的价差是收敛的。我们用X的产品价格减去Y产品的价格,当差值为正的时候,我们认为X的价格过高,则做空X,同时Y的价格过低,则做多Y;当差值为负的时候,我们认为X的价格过低,则做多X,同时Y的价格过高,则做空Y;当差值为0时,则价格被市场所修复,则全部平仓。

为了让差异更明显,我们定义的计算公式如下。


价差Z = X价格-Y价格
Z >  10时,做空X,做多Y ;Z<0时,平仓
Z < -10时,做多X,做空Y ;Z>0时,平仓

计算差价,然后计算交易统计。


# 计算差价
> df$diff<-df$x-df$y

# 找到差价大于10时的点
> idx<-which(df$diff>10)
> idx<-idx[-which(diff(idx)==1)-1]

# 打印差价的索引值
> idx
 [1]  4 11 15 23 25 30 34 36 38 43 48 53 55 59 61 68 76 81 83 86 88 92 95 98

接下来,我们进行模拟交易,取第一个索引值的点,在2010-01-04时做空X,做多Y。当差价小于0在2010-01-06时,进行平仓。


# 打印前20个数据
> head(df,20)
        dates      x      y    diff
1  2010-01-02  24.94  25.19   -0.25
2  2010-01-03  57.35  51.68    5.67
3  2010-01-04  16.57  13.56    3.01
4  2010-01-05 113.81  56.32   57.49
5  2010-01-06  63.18  23.82   39.36
6  2010-01-07  17.18 120.69 -103.51
7  2010-01-08  69.50  78.67   -9.17
8  2010-01-09  79.53  86.41   -6.88
9  2010-01-10  73.03  65.37    7.66
10 2010-01-11  37.78 117.29  -79.51
11 2010-01-12 110.47  24.57   85.90
12 2010-01-13  65.59  31.53   34.06
13 2010-01-14  25.15 107.29  -82.14
14 2010-01-15 -38.59  23.97  -62.56
15 2010-01-16  95.00  41.70   53.30
16 2010-01-17  48.20  34.29   13.91
17 2010-01-18  49.35  37.20   12.15
18 2010-01-19  87.75  38.84   48.91
19 2010-01-20  82.85  69.77   13.08
20 2010-01-21  73.76  42.91   30.85

# 当差价大于10时,做空X,当差价小于0时,平仓。
# 第4行做空,第6行平仓
> xprofit<- df$x[4]-df$x[6];xprofit
[1] 96.63

# 当差价大于10时,做多Y;当差价小于0时,平仓。
# 第4行做空,第6行平仓
> yprofit<- df$y[6]-df$y[4];yprofit
[1] 64.37

从交易结果来看,我们第一笔配对交易就是赚钱的。

这是为什么呢?

根据配对交易的假设条件,如果两个金融产品的价差是收敛的,通过协整性检验的方法,我们可验证数据的收敛性。那么如果数据是收敛的,他还会具备均值回归的特性,请参考文章 均值回归,逆市中的投资机会

画出X,Y的价差图,我们可以明显的看出,价差一直围绕着0上下波动,这是明显收敛的,同时符合均值回归的特性。


> plot(df$diff,type='l')

02

这就是市场的规则,通过配对交易的方法,我们找到市场无效性,从而可以赚去套利的收益。

3. 用R语言实现配对交易

看到上面的赚钱方法,也许大家会很兴奋!但是大部分市场的数据,都不会像我们的假设条件一样,轻而易举就能实现赚钱的目标。我们可以用计算机程序进行全市场的扫描发现交易机会,当然你也可以通过肉眼的方式来观察。

市场上有一些天生就具备均衡关系的金融产品,可以作为我们套利的入手对象。

  • 股票类,同行业、市值和基本面相似的个股,比如,中国银行(601988)和农业银行(601288)。
  • 基金类,以相同指数作为标的的不同基金,比如,证券B(150172),券商B(150201)。
  • 期货类,同一期货品种的不同合约,比如,铜(cu1605, cu1606)。
  • 混合类,跨市场为标的的金融产品,比如,沪深300指数,IF的期货合约

接下来,以相同品种不同合约的期货为例,我们把配对交易用在cu1605和cu1606的两个合约上,试试效果如何。由于期货是支持的T+0日内的交易的,而对于套利的操作,通常都不会持仓过夜,所以我们在尽量的短周期上进行操作,而且日内平仓。下面我将以1分钟做为交易周期。

3.1 数据准备

R语言本身提供了丰富的金融函数工具包,时间序列包zoo和xts,指标计算包TTR,可视包ggplot2等,我们会一起使用这些工具包来完成建模、计算和可视化的工作。关于zoo包和xts包的详细使用可以参考文章,R语言时间序列基础库zoo可扩展的时间序列xts

本文用到的数据,是铜的1分钟线的数据,从2016年日2月1日到2016年日2月29日,日盘的交易数据,以CSV格式保存到本地文件cu1605.csv,cu1606.csv。商品期货的日盘交易时间分为3段:09:00:00-10:14:59,10:30:00-11:29:59,13:30:00-14:59:59。当前测试,不考虑夜盘的数据。

数据格式如下:


2016-02-01 09:00:00,35870,35900,35860,35880
2016-02-01 09:01:00,35890,35890,35860,35870
2016-02-01 09:02:00,35870,35870,35860,35870
2016-02-01 09:03:00,35870,35900,35870,35900
2016-02-01 09:04:00,35900,35900,35870,35870
2016-02-01 09:05:00,35870,35880,35860,35870
2016-02-01 09:06:00,35880,35880,35860,35870

一共5列:

  • 第1列,交易时间,date,2016-02-01 09:00:00
  • 第2列,开盘价,Open,35870
  • 第3列,最高价,High,35900
  • 第4列,最低价,Low,35860
  • 第5列,收盘价,Close,35880

通过R语言加载铜的1分钟线数据,因为我们进行日内交易,所以在加载时我就进行了转换,按日期进行分组,生成R语言的list对象,同时把每日的data.frame类型对象转成XTS时间序列类型对象,方便后续的数据处理。


#加载工具包
> library(xts)
> library(TTR)

# 读取CSV数据文件
> read<-function(file){ 
+     df<-read.table(file=file,header=FALSE,sep = ",", na.strings = "NULL")  # 读文件
+     names(df)<-c("date","Open","High","Low","Close")                       # 设置列名
+     dl<-split(df,format(as.POSIXct(df$date),'%Y-%m-%d'))                   # 按日期分组
+     
+     lapply(dl,function(item){                                              # 换成xts类型数据
+         xts(item[-1],order.by = as.POSIXct(item$date))
+     })
+ }

# 加载数据
> cu1605<-read(file='cu1605.csv')
> cu1606<-read(file='cu1606.csv')

# 查看数据类型
> class(cu1605)
[1] "list"

# 查看数据的日期索引值
> names(cu1605)
 [1] "2016-02-01" "2016-02-02" "2016-02-03" "2016-02-04" "2016-02-05"
 [6] "2016-02-15" "2016-02-16" "2016-02-17" "2016-02-18" "2016-02-19"
[11] "2016-02-22" "2016-02-23" "2016-02-24" "2016-02-25" "2016-02-26"
[16] "2016-02-29"

# 查看每日的数据量
> nrow(cu1605[[1]])
[1] 223

# 查看cu1605合约的数据
> head(cu1605[['2016-02-01']])
                     Open  High   Low Close
2016-02-01 09:00:00 35870 35900 35860 35880
2016-02-01 09:01:00 35890 35890 35860 35870
2016-02-01 09:02:00 35870 35870 35860 35870
2016-02-01 09:03:00 35870 35900 35870 35900
2016-02-01 09:04:00 35900 35900 35870 35870
2016-02-01 09:05:00 35870 35880 35860 35870

把数据准备好了,我们就可以来建立模型了。

3.2 配对交易模型

以2016年02月01日为例进行交易,以1分钟线的close价格来计算cu1605和cu1606的两个合约的价差。下面我们对数据进行操作,合并2个合约在2016年02月01日的数据,并对空值进行处理,最后计算出两个合约的价差。


# 合并数据
> xdf<-merge(cu1605[['2016-02-01']]$Close,cu1606[['2016-02-01']]$Close)
> names(xdf)<-c('x1','x2')

# 用前值替换空值
> xdf<-na.locf(xdf)

# 计算价差
> xdf$diff<-xdf$x1-xdf$x2

# 打印前20行数据
> head(xdf,20)
                     x1     x2     diff
2016-02-01 09:00:00  35880  35900  -20
2016-02-01 09:01:00  35870  35920  -50
2016-02-01 09:02:00  35870  35910  -40
2016-02-01 09:03:00  35900  35940  -40
2016-02-01 09:04:00  35870  35910  -40
2016-02-01 09:05:00  35870  35920  -50
2016-02-01 09:06:00  35870  35910  -40
2016-02-01 09:07:00  35860  35910  -50
2016-02-01 09:08:00  35840  35880  -40
2016-02-01 09:09:00  35790  35840  -50
2016-02-01 09:10:00  35800  35840  -40
2016-02-01 09:11:00  35790  35830  -40
2016-02-01 09:12:00  35820  35860  -40
2016-02-01 09:13:00  35810  35850  -40
2016-02-01 09:14:00  35790  35830  -40
2016-02-01 09:15:00  35780  35830  -50
2016-02-01 09:16:00  35770  35810  -40
2016-02-01 09:17:00  35760  35820  -60
2016-02-01 09:18:00  35750  35800  -50
2016-02-01 09:19:00  35760  35810  -50

数据解释:

  • x1列,为第一腿对应cu1605合约
  • x2列,为第二腿对应cu1606合约。
  • diff列,为cu1605-cu1606

从价差的结果看,每1分钟cu1605合约都小于cu1606合约,从-110到-20价差不等,并且以-63为均值上下反复震荡。


# 计算价差范围
> range(xdf$diff)
[1] -110  -20

# 计算价差均值
> mean(xdf$diff)
[1] -63.90135

# 画出价差分布柱状图
> hist(xdf$diff,10)

画出价差分布柱状图
03

我们假设以-63为均值回归点,当差值为大于-45的时候,认为X的价格过高做空X,同时Y的价格过低做多Y;当差值小于-75的时候,我们认为X的价格过低做多X,同时Y的价格过高做空Y;当差值为-63时,价格被市场所修复,则全部平仓。以cu1605和cu1606的两个合约按照1:1持仓进行配比,1手多单对1手空单。

定义模型指标,计算价值列为diff,均值回归列为mid,最大阈值列为top,最小阈值列为bottom。


target.pair<-function(xdf){
  xdf$diff<-xdf$x1-xdf$x2   #差值
  xdf$mid<- -63             #均值回归点
  xdf$top<- -45             #最大阈值
  xdf$bottom<- -75          #最小阈值
  return(xdf)
}

完成指标的定义后,我们创建配对交易模型,并对合同数据进行回测,产生交易信号后,模拟交易输出清单,并可视化交易结果。

回测过程代码省略,产生的交易信号如下所示。


                  date    x1    x2 diff mid top bottom op
21 2016-02-01 09:00:00 35880 35900  -20 -63 -45    -75 ks
1  2016-02-01 09:25:00 35740 35810  -70 -63 -45    -75 pb
22 2016-02-01 09:40:00 35690 35730  -40 -63 -45    -75 ks
2  2016-02-01 09:47:00 35700 35770  -70 -63 -45    -75 pb
13 2016-02-01 10:00:00 35690 35770  -80 -63 -45    -75 kb
5  2016-02-01 10:01:00 35710 35760  -50 -63 -45    -75 ps
23 2016-02-01 10:02:00 35710 35750  -40 -63 -45    -75 ks
3  2016-02-01 10:07:00 35680 35750  -70 -63 -45    -75 pb
14 2016-02-01 10:37:00 35720 35800  -80 -63 -45    -75 kb
6  2016-02-01 10:42:00 35740 35790  -50 -63 -45    -75 ps
15 2016-02-01 11:20:00 35700 35780  -80 -63 -45    -75 kb
7  2016-02-01 11:21:00 35710 35750  -40 -63 -45    -75 ps
24 2016-02-01 11:21:00 35710 35750  -40 -63 -45    -75 ks
4  2016-02-01 11:23:00 35690 35760  -70 -63 -45    -75 pb
16 2016-02-01 11:29:00 35690 35770  -80 -63 -45    -75 kb
8  2016-02-01 13:36:00 35660 35720  -60 -63 -45    -75 ps
17 2016-02-01 13:45:00 35660 35740  -80 -63 -45    -75 kb
9  2016-02-01 13:46:00 35670 35730  -60 -63 -45    -75 ps
18 2016-02-01 13:52:00 35650 35730  -80 -63 -45    -75 kb
10 2016-02-01 13:53:00 35650 35710  -60 -63 -45    -75 ps
19 2016-02-01 13:56:00 35640 35720  -80 -63 -45    -75 kb
11 2016-02-01 14:49:00 35600 35660  -60 -63 -45    -75 ps
20 2016-02-01 14:52:00 35610 35700  -90 -63 -45    -75 kb
12 2016-02-01 14:58:00 35610 35690  -80 -63 -45    -75 ps

数据解释:

  • date列,为交易时间
  • x1列,为第一腿对应cu1605合约
  • x2列,为第二腿对应cu1606合约。
  • diff列,为cu1605-cu1606
  • mid列,为均值回归点
  • top列,为最大阈值
  • bottom列,为最小阈值
  • op列,为交易信号

交易信号一共有4种。

  • ks, 开仓, 做空(卖),对应反向操作为pb。
  • kb, 开仓, 做多(买),对应反向操作为ps。
  • ps, 平仓, 做空(卖),对应反向操作为kb。
  • pb,平仓, 做多(买),对应反向操作为ks。

一共出现了24个交易信号,由于我们进行的是配对交易,所以当出现ks(开仓做空)信号时,实际上会进行2笔操作,开仓做空第一腿,开仓做多第二腿。

接下来,进行模拟交易,计算出交易清单。


$x1
                       code op price pos    fee  value  margin balance     cash
2016-02-01 09:00:00  cu1605 ks 35880   1 8.9700 179400 26910.0      NA 173081.0
2016-02-01 09:25:00  cu1605 pb 35740   0 8.9350      0     0.0     700 173748.1
2016-02-01 09:40:00  cu1605 ks 35690   1 8.9225 178450 26767.5      NA 173437.7
2016-02-01 09:47:00  cu1605 pb 35700   0 8.9250      0     0.0     -50 173339.9
2016-02-01 10:00:00  cu1605 kb 35690   1 8.9225 178450 26767.5      NA 173552.0
2016-02-01 10:01:00  cu1605 ps 35710   0 8.9275      0     0.0     100 173574.2
2016-02-01 10:02:00  cu1605 ks 35710   1 8.9275 178550 26782.5      NA 173651.3
2016-02-01 10:07:00  cu1605 pb 35680   0 8.9200      0     0.0     150 173753.4
2016-02-01 10:37:00  cu1605 kb 35720   1 8.9300 178600 26790.0      NA 173758.1
2016-02-01 10:42:00  cu1605 ps 35740   0 8.9350      0     0.0     100 173780.2
2016-02-01 11:20:00  cu1605 kb 35700   1 8.9250 178500 26775.0      NA 173887.3
2016-02-01 11:21:00  cu1605 ps 35710   0 8.9275      0     0.0      50 173859.4
2016-02-01 11:21:001 cu1605 ks 35710   1 8.9275 178550 26782.5      NA 174044.1
2016-02-01 11:23:00  cu1605 pb 35690   0 8.9225      0     0.0     100 174096.2
2016-02-01 11:29:00  cu1605 kb 35690   1 8.9225 178450 26767.5      NA 174173.3
2016-02-01 13:36:00  cu1605 ps 35660   0 8.9150      0     0.0    -150 173945.5
2016-02-01 13:45:00  cu1605 kb 35660   1 8.9150 178300 26745.0      NA 174260.1
2016-02-01 13:46:00  cu1605 ps 35670   0 8.9175      0     0.0      50 174232.3
2016-02-01 13:52:00  cu1605 kb 35650   1 8.9125 178250 26737.5      NA 174331.9
2016-02-01 13:53:00  cu1605 ps 35650   0 8.9125      0     0.0       0 174254.1
2016-02-01 13:56:00  cu1605 kb 35640   1 8.9100 178200 26730.0      NA 174403.8
2016-02-01 14:49:00  cu1605 ps 35600   0 8.9000      0     0.0    -200 174125.9
2016-02-01 14:52:00  cu1605 kb 35610   1 8.9025 178050 26707.5      NA 174490.6
2016-02-01 14:58:00  cu1605 ps 35610   0 8.9025      0     0.0       0 174405.3

$x2
                       code op price pos    fee  value  margin balance     cash
2016-02-01 09:00:00  cu1606 kb 35900   1 8.9750 179500 26925.0      NA 146147.1
2016-02-01 09:25:00  cu1606 ps 35810   0 8.9525      0     0.0    -450 200214.2
2016-02-01 09:40:00  cu1606 kb 35730   1 8.9325 178650 26797.5      NA 146631.3
2016-02-01 09:47:00  cu1606 ps 35770   0 8.9425      0     0.0     200 200328.4
2016-02-01 10:00:00  cu1606 ks 35770   1 8.9425 178850 26827.5      NA 146715.6
2016-02-01 10:01:00  cu1606 pb 35760   0 8.9400      0     0.0      50 200442.7
2016-02-01 10:02:00  cu1606 kb 35750   1 8.9375 178750 26812.5      NA 146829.8
2016-02-01 10:07:00  cu1606 ps 35750   0 8.9375      0     0.0       0 200557.0
2016-02-01 10:37:00  cu1606 ks 35800   1 8.9500 179000 26850.0      NA 146899.1
2016-02-01 10:42:00  cu1606 pb 35790   0 8.9475      0     0.0      50 200671.2
2016-02-01 11:20:00  cu1606 ks 35780   1 8.9450 178900 26835.0      NA 147043.4
2016-02-01 11:21:00  cu1606 pb 35750   0 8.9375      0     0.0     150 200835.5
2016-02-01 11:21:001 cu1606 kb 35750   1 8.9375 178750 26812.5      NA 147222.6
2016-02-01 11:23:00  cu1606 ps 35760   0 8.9400      0     0.0      50 200949.8
2016-02-01 11:29:00  cu1606 ks 35770   1 8.9425 178850 26827.5      NA 147336.9
2016-02-01 13:36:00  cu1606 pb 35720   0 8.9300      0     0.0     250 201014.1
2016-02-01 13:45:00  cu1606 ks 35740   1 8.9350 178700 26805.0      NA 147446.2
2016-02-01 13:46:00  cu1606 pb 35730   0 8.9325      0     0.0      50 201078.4
2016-02-01 13:52:00  cu1606 ks 35730   1 8.9325 178650 26797.5      NA 147525.5
2016-02-01 13:53:00  cu1606 pb 35710   0 8.9275      0     0.0     100 201142.7
2016-02-01 13:56:00  cu1606 ks 35720   1 8.9300 178600 26790.0      NA 147604.8
2016-02-01 14:49:00  cu1606 pb 35660   0 8.9150      0     0.0     300 201207.0
2016-02-01 14:52:00  cu1606 ks 35700   1 8.9250 178500 26775.0      NA 147706.7
2016-02-01 14:58:00  cu1606 pb 35690   0 8.9225      0     0.0      50 201221.4

数据解释:

  • $x1部分,为第一腿的交易清单。
  • $x2部分,为第二腿的交易清单。
  • code,合约代码
  • op,交易信号
  • price,成交价格
  • pos,成交数量
  • fee,手续费
  • value,对应价值
  • margin,保证金
  • balance,平仓盈亏
  • cash,账号资金

我通过交易清单,统计交易结果。


> page  
$day     # 交易日期
[1] "2016-02-01"

$capital   # 初始资金
[1] 2e+05

$cash      # 账户余额
[1] 201221.4

$num       # 交易信号数
[1] 24

$record    # 配对交易平仓盈亏
                      x1   x2 balance
2016-02-01 09:25:00  700 -450     250
2016-02-01 09:47:00  -50  200     150
2016-02-01 10:01:00  100   50     150
2016-02-01 10:07:00  150    0     150
2016-02-01 10:42:00  100   50     150
2016-02-01 11:21:00   50  150     200
2016-02-01 11:23:00  100   50     150
2016-02-01 13:36:00 -150  250     100
2016-02-01 13:46:00   50   50     100
2016-02-01 13:53:00    0  100     100
2016-02-01 14:49:00 -200  300     100
2016-02-01 14:58:00    0   50      50

$balance   # 汇总平仓盈亏,第一腿盈亏,第二腿盈亏
[1] 1650  850  800

$fee       # 汇总手费费,第一腿手续费,第二腿手续费
[1] 429 214 215

$profit    # 账户净收益,收益率(占保证金)
[1] 1221.000    0.023

$wins      # 胜率,胜数,败数
[1]  1 12  0

最后,通过可视化输出交易信号。

04

图例解释

  • 棕色线,为价差diff
  • 紫色线,为最大阈值top
  • 红色线,为最小阈值bottom
  • 蓝色线,为均值线mid,平行于top和bottom
  • 浅蓝线,为ks开仓做空的交易
  • 绿色线,为kb开仓做多的交易

从图中看就更直观了,我们进行了12次交易,每次4笔,胜率100%。

最后,我们对2月份整个的数据进行回测。回测结果如下。


         date profit    ret balance fee winRate win fail maxProfit maxLoss avgProfit avgLoss
1  2016-02-01   1221  0.023    1650 429    1.00  12    0       250      50       138     NaN
2  2016-02-02   1077  0.020    1650 573    1.00  15    0       150       0       110     NaN
3  2016-02-03     64  0.001     100  36    1.00   1    0       100     100       100     NaN
4  2016-02-04    113  0.002     150  37    1.00   1    0       150     150       150     NaN
5  2016-02-05    926  0.017    1400 474    1.00  13    0       150     100       108     NaN 
6  2016-02-15   1191  0.022    1550 359    1.00  10    0       250     100       155     NaN 
7  2016-02-16     78  0.001     150  72    1.00   1    0       150       0       150     NaN  
8  2016-02-17    179  0.003     250  71    1.00   2    0       200      50       125     NaN 
9  2016-02-18     14  0.000      50  36    1.00   1    0        50      50        50     NaN  
10 2016-02-19    -36 -0.001       0  36     NaN   0    0         0       0       NaN     NaN   
11 2016-02-22     64  0.001     100  36    1.00   1    0       100     100       100     NaN 
12 2016-02-23    632  0.012     850 218    1.00   6    0       200     100       142     NaN 
13 2016-02-24    470  0.009     650 180    1.00   4    0       200       0       162     NaN 
14 2016-02-25    114  0.002     150  36    1.00   1    0       150     150       150     NaN 
15 2016-02-26    178  0.003     250  72    1.00   2    0       150     100       125     NaN 
16 2016-02-29    511  0.009     800 289    0.88   7    1       150     -50       121     -50 

数据解释:

  • date,交易日期
  • profit,净收益
  • ret,每日收益率
  • balance,平仓盈亏
  • fee,手续费
  • winRate,胜率
  • win,胜数
  • fail,败数
  • maxProfit,单笔最大盈利
  • maxLoss,单笔最大亏损
  • avgProfit,平均盈利
  • avgLoss,平均亏损

从结果来看,多么开心啊,几乎每天都是赚钱的!!

cu1605和cu1606两个合同是完美地具备均衡关系的两个金融产品,大家常常所说的跨期套利就是基于这个思路实现的。本文介绍的配对交易模型,是统计套利的一个基本模型,原理很简单,当大家都掌握后拼的就是交易速度了。

利用市场的无效性来获取利润,是每个套利策略都在寻找的目标。通过统计方法,我们可以发现市场的无效性,再以对冲的操作方式,规避绝大部分的市场风险,等待市场的自我修复后来赚钱利润。说起来很简单,但市场的无效性,可能会在极短时间内就被修复。

“天下武功为快不破”,通过量化的手段,让计算机来发现机会,进行交易,实现收益。一切就和谐了!!

转载请注明出处:
http://blog.fens.me/finance-pairs-trading/

打赏作者

尚书视频群活动:投资分析师笔试题

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员Java,R,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-onbook-20151028

uibe

前言

投资分析师一直是大家眼中光鲜耀眼的职业,通常受雇于银行,保险公司,投资公司,制造公司,信托公司,基金管理公司等。他们不仅需要了解国内国际的宏观经济形势,还要为公司和客户提供财政和投资融资建议,是一向非常有挑战性工作。

这次非常高兴,况客能与对外经济贸易大学深度合作,开发“投资分析师”的课程,帮助学生了解职场,提高动手和实战的能力。本次合作项目一经推出,就吸引了外经贸的230位从本科到博士的同学报名,其中170位同学参加了笔试,60位同学入围了面试,最后30位精英同学入选参加第一期的况客训练营。

尚书视频网站也使用了本次题目,拿这次笔试的试卷搞个竞答的活动!尚书视频网站以知识积累,聚集各路跨学科的大侠,经常一边讨论R,一边讨论Node,一会儿聊聊金融量化模型,一会儿又说到了Hadoop大数据的开发,一个跨学科的交流平台。本次的题目也是多种学科知识综合的问题,正巧可以看看大侠们思路,到底有多不一样。

目录

  1. 活动介绍
  2. 笔试题目
  3. 现场照片

1. 活动介绍

作为一名优秀的投资分析师,不仅要具备金融的基础知识,还要理解市场,冷静的思考,逻辑思维,并有一定的数据处理能力。那么,本次况客训练营,为了选拔出优秀的同学,我们在笔试题上面,确实下了一番功夫,包括了3道金融题,1道IT基础题,1道算法题,1道综合建模题。题目都是况客公司各种精英鬼才想出的,其实都是非常有意思题目。

想知道自己的技术到底在一个什么段位? 快来答题吧~~~\(^o^)/~

01

下面引用活动规则:活动规则下载


张丹老师所在的况客科技(北京)有限公司与对外经济贸易大学联合推出的“UIBE-况客投资分析师发展计划”已于2015年10月26日正式启动了。并于10月26日进行了第一轮的笔试考试。管理员我有幸看到了考试试卷,觉着有点儿意思,所以一拍大腿,决定拿这次笔试的试卷搞个竞答的活动!

这次使用的题目,都是张丹老师公司第一轮笔试的考试题啦。当天笔试规定的时间是2个小时,开卷笔试,可以上网。我琢磨着,咱们群里时间给宽松点儿吧,一周吧!依旧是开卷,可以上网,随便查,群内的兄弟姐妹老少爷们儿们都可以参加,没门槛限制!答完了就发送到我邮箱里,其中一定要包括“姓名”、“QQ号”、“群名片”呦!张丹老师统一阅卷,得分最高的前三名送张丹老师写的《R的极客理想-高级开发篇》一本!!

  • 活动时间:2015.10.30—2015.11.6
  • 活动范围:尚书视频 QQ群 内所有成员
  • 活动方式:开卷笔试,可以上网,随便查!!!
  • 答案提交方式:邮件提交
  • 答案提交截止日期:2015.11.6
  • 邮箱地址:onbook001@163.com
  • 活动奖品:《R的极客理想-高级开发篇》
  • 活动咨询:尚书视频 QQ群内 助理-管理员
  • QQ群:383275651

r2-200

还没有加群的朋友,快来申请吧,QQ群:383275651

非常感谢 华章公司-机械工业出版社 为本次活动提供图书奖品!!

2. 笔试题目

“UIBE-况客投资分析师发展计划”:旨在通过对外经济贸易大学重点金融实验室的优秀资源和况客公司的金融技术优势,在金融建模、量化编程、投研报告撰写等方面对学员进行系统的培训,使得学员的投资实战能力大大提高。作为投资分析师的摇篮计划,该项目不仅培养学生的投资研究实战能力,并将优秀学员推荐至国内外著名金融机构进行实习和工作。

接下来,就是本次的题目的,全都是简答题。祝大家好运!

02

1. 阐述个人选择股票的逻辑,并介绍在实际操作中如何实现。

2. 假设作为FOF的基金经理,你管理着1000万人民币的投资组合,可投资范围包括A和B两个指数增强型基金,此外可以投资于IC、IF和IH等股指期货合约。A基金的参考基准为沪深300指数,预计基金超额业绩为年化2%;B基金的参考投资基准为中证500指数, 预计基金超额业绩为年化5%。在要求组合业绩相对于沪深300指数的beta不能显著偏离1的情况下,尽可能地提高投资组合的业绩。请阐述你如何构建投资组合。

3. 资产管理是个竞争非常激烈的行业,对于大部分的基金管理人来说都会面临与同行进行排名的压力。国内一般采用年度考核的方式来评估一个基金经理的能力,现在假设你管理的同类型基金有N个同行业竞争者,目前距离年度结束只有T天,而你所管理的基金的最新排名在m,而你的目标是尽量在年度结束的时候获得尽量靠前的排名。假设市场是完全有效的市场,金融资产的收益率服从均值为0的正态分布,但是基金经理可以选择所配置金融资产的波动率d(也就是正态分布的标准差)。根据基金经理的从业经验,如果排名越落后的情况下,在剩下的时间T里,一般会选择提高所配置资产的风险水平d。请设计一套量化分析的方法验证该经验是否合理(本题目为开放型题目,没有标准答案; 可以从数学角度或者计算机程序设计的角度出发回答这个问题)。

4. 列出你所熟悉的编程或建模工具,并描述工具的特点,以及你的使用场景。

5. 实现一个回字形矩阵,内圈比外圈每一圈小1,最内圈为数字1。要求给定初始值,画出整个矩阵,请提供思路和伪代码。比如,初始值为3的回字形矩阵,如下所示:


3  3  3  3  3
3  2  2  2  3
3  2  1  2  3
3  2  2  2  3
3  3  3  3  3

6. “月上柳梢头,人约黄昏后”,出自北宋文学家欧阳修的《生查子》,全词富于诗情画意,此句更是唯美,被广为传唱。 请查阅天文学资料,建立模型,实现如下要求:

  • 定义画面中的时间;
  • 定义模型的各个因子,选用文字、图表、算法等形式描述模型;
  • 运用模型,推算北京今年有几次这样的时间;
  • 3年后,去国外哪个城市,什么时间去才能满足上述画面?

嘿嘿,一共6道题,记得发邮件!

3. 现场照片

笔试的考场

03

火爆的笔试现场

5

6

7

8

3个严肃的面试官

10

9

面试过程中的小组讨论环节

11

转载请注明出处:
http://blog.fens.me/meeting-onbook-20151028

打赏作者

2015lopdev生态联盟开发者大会:股市中的R语言量化算法模型

跨界知识聚会系列文章,“知识是用来分享和传承的”,各种会议、论坛、沙龙都是分享知识的绝佳场所。我也有幸作为演讲嘉宾参加了一些国内的大型会议,向大家展示我所做的一些成果。从听众到演讲感觉是不一样的,把知识分享出来,你才能收获更多。

关于作者

  • 张丹(Conan), 程序员Java,R,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/meeting-lopdev-20150922/

lopdev

前言

记得10年前还在上学的时候,总是参加IBM的大会,看着各种新技术从实验室创造,特别地神奇。今天我也有机会站在了IBM大会的讲台上,给大家分享我所研究的R语言技术,对我来说也是一件非常有纪念意义的事情。

感谢IBM主办方的邀请,也真心希望有机会与IBM建立合作机会。

目录

  1. 我的演讲主题:股市中的R语言量化算法模型
  2. 会议体验和照片分享

1. 我的演讲主题:股市中的R语言量化算法模型

股市中的R语言量化算法模型,PPT下载,主要内容来自我的一篇博文:R语言构建追涨杀跌量化交易模型

由于本次会议邀请准备时间太短,所以沿用了在数据分析师大会上的演讲内容,但也有不样的地方,增加了况客金融云的部分,通过在线的云环境,开发,部署,可视化自己的个性化的策略模型。

本次会议,我被安排在了新技术专场,虽然R并不被程序员所了解,但是R语言其实已经24年(1993年)的历史。由于听众大多是程序员,那么演讲内容就要简单直接,要有代码有真相,代码部分可以多多演示。

其他的几位嘉宾都是纯IT的底层技术,听起来确实有点吃力。那么我正好讲一个金融应用,正好调节一下大家睡眠的神经。追涨杀跌策略就成为最好的一个金融初门策略的切入点。我一直延续了一贯的演讲风格,有内容,有图片,有代码,有互动。从 追涨杀跌 的思路开始,到市场特征检验,再到数学公式,R语言建模,再到历史数据回测。通过R语言,很简单地就实现了一个我们脑子中的投资想法。类似的投资想法其实谁都有,利用IT人的技术优势,可以真正地与实际操作结合起来,实现从IT技术到价值的转变。

2. 会议体验和照片分享

本次大会不仅结识了很多同行的高手,同时听到不同领域对于数据的声音。群贤汇聚 思想碰撞,这也是对我最大收获。会议主页:http://lopdev.csdn.net/

12

2.1 我的分享是在9月22日的新技术分论坛,第四位分享嘉宾。

贾海鹏,中科超算,副总经理,主要介绍OpenBlas的项目情况。

01

杨瑞瑞,红帽,Linux开发主管,介绍了RedHat Linux 7.1内核的新特性。

03

陈飞,IBM,中国研究院资深研究员,介绍了OpenPower引擎,软硬件结合开发的新的框架标准。

04

张丹况客创始人CTO,《R的极客理想》系列图书作者,介绍了用R语言实现追涨杀跌的交易模型。

06

03

吴文昊,北京旷视科技有限公司,云平台副总裁,介绍OpenBlas在移动平台尝试学习产品上的应用。

07

2.2 用户互动

虽然是技术的专场,我的演讲还是吸引了一些感兴趣的小伙伴。把技术变成价值,是所有学技术的人都理想。

08

有一位来自印度的友人,中国文说的很不错,也在做互联网方向的创业。

13

况客的单页展板,顿时感觉自己代表了企业形象!下一次演讲我们会准备的更好,感谢况客市场总监Ruby为本次活动的精心安排。

11

2.3 个人采访

会议虽短,在最后还有个人采访环节。采访主题就围绕着“开源重构世界,开发改变未来”展来。看得出来IBM注重技术的态度,同时也在大力推动开源项目的发展。况客,用到的所有技术都是开源的产品,我们也会在合适的时候,把况客的技术开放,反馈于开源社区。

IT人,加油!开源重构世界,开发改变未来!

09

最后,感谢IBM工作人员的辛苦劳动,希望保持高水平会议越办越好!

转载请注明出处:
http://blog.fens.me/meeting-lopdev-20150922/

打赏作者