• Posts tagged "期货"

Blog Archives

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/

打赏作者

金融期货备考知识点

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

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

关于作者:

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

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

futures-quiz

前言

开通金融期货业务,据说要参加一个考试。像我这种非金融出身,又有IT思维的人,就充分借助互联网资源,自备大纲,自学研究,争取明天一次性通过考试。

从网上搜索到的金融期货的基础知识来看,就是下面的几个点!一晚备战应该够了!

目录

  1. 什么是期货?
  2. 中金所和金融期货
  3. 交易指令

1. 什么是期货?

期货,一般指期货合约,就是指由期货交易所统一制定的、规定在将来某一特定的时间和地点交割一定数量标的物的标准化合约。这个标的物,又叫基础资产,对期货合约所对应的现货,可以是某种商品,如铜或原油,也可以是某个金融工具,如外汇、债券,还可以是某个金融指标,如三个月同业拆借利率或股票指数。期货合约的买方,如果将合约持有到期,那么他有义务买入期货合约对应的标的物;而期货合约的卖方,如果将合约持有到期,那么他有义务卖出期货合约对应的标的物(有些期货合约在到期时不是进行实物交割而是结算差价,例如股指期货到期就是按照现货指数的某个平均来对在手的期货合约进行最后结算)。当然期货合约的交易者还可以选择在合约到期前进行反向买卖来冲销这种义务。

期货可以大致分为两大类

  • 商品期货: 主要品种可以分为农产品期货、金属期货(包括基础金属与贵金属期货)、能源期货三大类。
  • 金融期货: 主要品种可以分为外汇期货、利率期货(包括中长期债券期货和短期利率期货)和股指期货。

futuresbond

金融期货

  • 股指期货,就是以股票指数为标的物的期货。双方交易的是一定期限后的股票指数价格水平,通过现金结算差价来进行交割。
  • 利率期货,是指以债券类证券为标的物的期货合约, 它可以回避银行利率波动所引起的证券价格变动的风险。利率期货的种类繁多,分类方法也有多种。通常,按照合约标的的期限, 利率期货可分为短期利率期货和长期利率期货两大类。
  • 外汇期货,是指以汇率为标的物的期货合约,用来回避汇率风险。它是金融期货中最早出现的品种。目前,外汇期货交易的主要品种有:美元、英镑、德国马克、日元、瑞士法郎、加拿大元、澳大利亚元、法国法郎、荷兰盾等。从世界范围看,外汇期货的主要市场在美国。

2. 中金所和金融期货

  • 中金所
  • 沪深300指数介绍
  • 沪深300指数期货合约表
  • 5年期国债期货介绍
  • 5年期国债期货合约表

1). 中金所

中国金融期货交易所简称中金所,于2006年9月8日在上海期货大厦内挂牌,成为继上海期货交易所、大连商品交易所、郑州商品交易所之后的中国内地的第四家期货交易所,也是中国内地第一家金融衍生品交易所。

中国金融期货交易所的组织形式采用公司制,这也使中国金融期货交易所成为中国内地首家采用这一组织形式的交易所。中国金融期货交易所由上海期货交易所、郑州商品交易所、大连商品交易所、上海证券交易所和深圳证券交易所共同发起设立。5家股东分别出资1亿元人民币,各占20%股份。

2010年4月16日,中国内地第一个股指期货合约沪深300指数期货合约上市交易。

2). 沪深300指数介绍

沪深300指数是由上海和深圳证券市场中选取300只A股作为样本编制而成的成份股指数。  

沪深300指数样本覆盖了沪深市场六成左右的市值,具有良好的市场代表性。沪深300指数是沪深证券交易所第一次联合发布的反映A股市场整体走势的指数。它的推出,丰富了市场现有的指数体系,增加了一项用于观察市场走势的指标,有利于投资者全面把握市场运行状况,也进一步为指数投资产品的创新和发展提供了基础条件。

沪深300指数行情(2014-01-27)


名称	昨日收盘	最新价	成交金额	开盘价	最高价	最低价	涨跌幅(%)
HS300	2245.6		2215.9	63503992484	2233.0	2233.0	2211.9	-1.33

关于股指的介绍,请参考文章股指是什么?, 文件下载:沪深300指数编制细则

3). 沪深300指数期货合约表

  • 合约标的: 沪深300指数
  • 合约乘数: 每点300元
  • 报价单位: 指数点
  • 最小变动价位: 0.2点
  • 合约月份: 当月、下月及随后两个季月
  • 交易时间: 上午:9:15-11:30,下午:13:00-15:15
  • 最后交易日交易时间: 上午:9:15-11:30,下午:13:00-15:00
  • 每日价格最大波动限制: 上一个交易日结算价的±10%
  • 最低交易保证金: 合约价值的12%
  • 最后交易日: 合约到期月份的第三个周五,遇国家法定假日顺延
  • 交割日期: 同最后交易日
  • 交割方式: 现金交割
  • 交易代码: IF
  • 上市交易所: 中国金融期货交易所

4). 5年期国债期货介绍

根据《中国金融期货交易所5年期国债期货合约交割细则》的相关规定,现就5年期国债期货可交割国债范围有关事项明确如下:

  • 合约上市后新发行的符合可交割国债条件的国债,交易所在该国债上市交易日(含)之前公布将其纳入可交割国债范围
  • 合约交割月新发行且上市交易日在合约最后交易日(含)之前的5年期国债,纳入合约可交割国债范围。合约交割月新发行的7年期国债,其到期日距交割月首日的期限超过7年,不纳入合约可交割国债范围
  • 根据财政部和托管机构关于国债转托管的相关规定,为保证国债期货交割的顺利进行,因付息导致合约交割期间暂停转托管的国债不纳入该合约可交割国债范围。

5年期国债期货转换因子和应计利息计算公式:

转换因子

futuesbond

  • r:5年期国债期货合约票面利率3%
  • x:交割月到下一付息月的月份数
  • n:剩余付息次数
  • c:可交割国债的票面利率
  • f:可交割国债每年的付息次数

计算结果四舍五入至小数点后4位。

应计利息

应计利息的日计数基准为“实际天数/实际天数”,每100元可交割国债的应计利息计算公式如下:

interest

计算结果四舍五入至小数点后7位。

5). 5年期国债期货合约表

  • 合约标的: 面值为100万元人民币、票面利率为3%的名义中期国债
  • 可交割国债: 合约到期月首日剩余期限为4-7年的记账式附息国债
  • 报价方式: 百元净价报价
  • 最小变动价位: 0.002元
  • 合约月份: 最近的三个季月(3月、6月、9月、12月中的最近三个月循环)
  • 交易时间: 09:15—11:30, 13:00—15:15
  • 最后交易日交易时间: 09:15—11:30
  • 每日价格最大波动限制: 上一交易日结算价的±2%
  • 最低交易保证金: 合约价值的2%
  • 最后交易日: 合约到期月份的第二个星期五
  • 最后交割日: 最后交易日后的第三个交易日
  • 交割方式: 实物交割
  • 交易代码: TF
  • 上市交易所: 中国金融期货交易所

3. 交易指令

交易指令又称交易订单,是指在金融产品交易过程中,投资者向交易经纪人和经济公司按何种价格采取何种方式交易一定数量标的物的订单。常见的交易指令包括:限价指令、市价指令、撤销指令、止损指令等。

  • 开仓指令: 是开仓的时候选择以多头还是空头开仓。
  • 价格指令: 是指示期货公司怎么样竞价开仓。
  • 时限指令: 是指你的指令维持的时限。
  • 平仓指令: 是结束所持的仓位的几种方式。
  • 止损指令: 是为了自动止损。
  • 高级指令: 通常只有较专业的股指期货投资软件才有。这种指令能设定各种各样的条件让投资更加自动化。

1). 开仓指令

在做股指期货交易时,都要选择该交易是开仓还是平仓。如果你是要开始一个新的仓位,不管多头还是空头,都得选择开仓指令。

买: 如果你要买沪深300指数升的话,就得用“买”这个股指期货指令配合“开仓”指令来做多头。这个股指期货交易指令告诉你的期货公司代表你入市买入一个新的仓位。

卖: 如果你要获利于沪深300下跌的话,就得用“卖”这个股指期货指令配合“开仓”指令来做空头。这个股指期货交易指令告诉你的期货公司代表你入市接受一个做多方合约作为其对立方来建立新仓位。

2). 价格指令

市价指令(Market Order): 就是不对期货公司下一定的价格要求而是让期货公司尽快以最好的市场价格完成股指期货交易。一般上如果一个股指期货合约的流动性强的话,价格竞争激烈,用市场指令能够避免最后因为价格不合适而流拍。如果一个股指期货合约的流动性低,价格竞争低的话,不建议用市场指令以免价格过高。最好用现价指令。基本上,市价指令使你在股指期货交易中成为了被动方,接受市场的任何价格。

限价指令(Limit Order): 就是交代期货公司以你所定的价格或者更好的价格来做成交。如果该股指期货合约价格一直没有到达你所定下的价格,该股指期货交易就会流拍。限价指令让你在股指期货交易中占据主动方,在股指期货市场上主动提出你的价格要求,也就是在股指期货市场里头主动竞价。

3). 时限指令

当日交易指令(Day Order): 是最常用的交易时限指令。这个指令吩咐期货公司在收盘前继续执行该指令。收盘后,该股指期货交易指令将自动消除。

直到取消指令(Good Till Cancelled): 吩咐期货公司不论何时继续执行该指令,直到成交为止。这个指令最大的用途是用于设定长期止损点。只要止损点没到,指令任然生效。

4). 平仓指令

平仓: 在结束一个股指期货仓位时,必须选择“平仓”指令,然后相关的买卖指令。

买: 如果你要结束一个空头仓位,你就需要选择“平仓”然后“买”,表示买回之前所卖出的股指期货合约来冲销该仓位。

卖: 如果你要结束一个多头仓位,你就必须选择“平仓”然后“卖”,表示卖掉之前买入的股指期货合约来冲销该仓位。

向后展期(Roll Forward): 是一个高级股指期货交易指令,一般期货公司交易平台没有。向前滚期就是把现有的仓位平掉,同时间开仓同样多的原月份合约。这个股指期货交易指令的好处是两个交易同时进行,避免了因为平常和开仓之间的时间差所造成的价格流失,Slippage. 学习什么是向后展期。

反向交易(Reverse): 是一个高级股指期货交易指令,一般期货公司交易平台没有。反向交易就是把现有的仓位平掉,同时间逆向开仓同样的股指期货合约。如果你之前是持多头仓位,利用反向交易就能瞬间把它变成空头合约。同样的,这个股指期货交易指令的好处是两个交易同时进行,避免了因为平常和开仓之间的时间差所造成的价格流失。

5). 止损指令

市场止损指令(Stop Market Order): 让你设定一个止损的价位,让止损交易自动化。如果你是多头,市场止损指令就会在该股指期货合约价格低于所设定的价位时,以市场指令自动平仓。如果你是空头,市场止损指令就会在该股指期货合约价格高于所定的价位时,以市场指令自动平仓。因为是以市场指令执行平仓,最后交易价格肯能以你所设定的价格有所不同。

限价止损指令(Stop Limit Order): 与市场止损指令一样但是它让你以现价指令模式设定最后交易价。但是如果该股指期货合约价格不能比所设定的限价优的话,该仓位将不能得到平仓,而是继续亏损。

SAR(Stop and Reverse): 就是当该股指期货合约到达你所预定的价格时,期货公司或者交易软件自动将所持仓位平仓同时以相反方向开仓。这种指令通常用于支持点或者阻力点上。

6). 高级指令

追踪止损指令(Trailing Stop): 就是让股指期货交易系统自动追踪你的仓位的最高点然后当该股指期货合约价格从那个最高点拉回一定百分比时卖出。追踪止损指令不只是一种止损指令,它也是一种在出现价格回落时有效的自动套利离场的方法。

条件式执行指令(Contingent Orders): 是以各种客观条件来自动化股指期货交易的某些环节。条件式执行指令使得股指期货投资更加自动化,更加客观,减少投资者的交易时间以及参与。比如说,你可以用条件式执行指令来规定当沪深300到某个点位就平仓,也可以规定当股指期货合约价格到了某个价位就增仓还是减仓。

一方启动另一方(One Trigger Other): 是以一个指令的执行后自动下单另外一个指令。比如说,你可以下单开仓然后OTO一个止损点。当开仓指令成交后,就会自动下单止损指令。

一方取消另一方(One Cancel Other): 是以一个指令的执行后自动取消另外一个指令。比如说,你可以下单设置一个止损点OCO一个盈利离场点。当任何一个指令执行后就自动取消另外一个已经没有的指令。

参考资料:

掌握了这些金融期货的基础知识,我想明天金融期货考试应该就不成问题了!争取一次性通过!

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

打赏作者