第一部分 新手入门
- 一 量化投资视频学习课程
- 二 Python 手把手教学
- 量化分析师的Python日记【第1天:谁来给我讲讲Python?】
- 量化分析师的Python日记【第2天:再接着介绍一下Python呗】
- 量化分析师的Python日记【第3天:一大波金融Library来袭之numpy篇】
- 量化分析师的Python日记【第4天:一大波金融Library来袭之scipy篇】
- 量化分析师的Python日记【第5天:数据处理的瑞士军刀pandas】
- 量化分析师的Python日记【第6天:数据处理的瑞士军刀pandas下篇
- 量化分析师的Python日记【第7天:Q Quant 之初出江湖】
- 量化分析师的Python日记【第8天 Q Quant兵器谱之函数插值】
- 量化分析师的Python日记【第9天 Q Quant兵器谱之二叉树】
- 量化分析师的Python日记【第10天 Q Quant兵器谱 -之偏微分方程1】
- 量化分析师的Python日记【第11天 Q Quant兵器谱之偏微分方程2】
- 量化分析师的Python日记【第12天:量化入门进阶之葵花宝典:因子如何产生和回测】
- 量化分析师的Python日记【第13天 Q Quant兵器谱之偏微分方程3】
- 量化分析师的Python日记【第14天:如何在优矿上做Alpha对冲模型】
- 量化分析师的Python日记【第15天:如何在优矿上搞一个wealthfront出来】
第二部分 股票量化相关
- 一 基本面分析
- 1.1 alpha 多因子模型
- 1.2 基本面因子选股
- 1.3 财报阅读 • [米缸量化读财报] 资产负债表-投资相关资产
- 1.4 股东分析
- 1.5 宏观研究
- 二 套利
- 三 事件驱动
- 四 技术分析
- 4.1 布林带
- 4.2 均线系统
- 4.3 MACD
- 4.4 阿隆指标 • 技术指标阿隆( Aroon )全解析
- 4.5 CCI • CCI 顺势指标探索
- 4.6 RSI
- 4.7 DMI • DMI 指标体系的构建及简单应用
- 4.8 EMV • EMV 技术指标的构建及应用
- 4.9 KDJ • KDJ 策略
- 4.10 CMO
- 4.11 FPC • FPC 指标选股
- 4.12 Chaikin Volatility
- 4.13 委比 • 实时计算委比
- 4.14 封单量
- 4.15 成交量 • 决战之地, IF1507 !
- 4.16 K 线分析 • 寻找夜空中最亮的星
- 五 量化模型
- 5.1 动量模型
- 5.2 Joseph Piotroski 9 F-Score Value Investing Model
- 5.3 SVR
- 5.4 决策树、随机树
- 5.5 钟摆理论
- 5.6 海龟模型
- 5.7 5217 策略
- 5.8 SMIA
- 5.9 神经网络
- 5.10 PAMR
- 5.11 Fisher Transform
- 5.12 分型假说, Hurst 指数
- 5.13 变点理论
- 5.14 Z-score Model
- 5.15 机器学习
- 5.16 DualTrust 策略和布林强盗策略
- 5.17 卡尔曼滤波
- 5.18 LPPL anti-bubble model
- 六 大数据模型
- 6.1 市场情绪分析
- 6.2 新闻热点
- 七 排名选股系统
- 八 轮动模型
- 九 组合投资
- 十 波动率
- 十一 算法交易
- 十二 中高频交易
- 十三 Alternative Strategy
第三部分 基金、利率互换、固定收益类
- 一 分级基金
- 二 基金分析
- 三 债券
- 四 利率互换
第四部分 衍生品相关
- 一 期权数据
- 二 期权系列
- 三 期权分析
- 四 期货分析
量化分析师的Python日记【第8天 Q Quant兵器谱之函数插值】
1. 如何使用scipy
做函数插值
函数插值,即在离散数据的基础上补插连续函数,估算出函数在其他点处的近似值的方法。在scipy
中,所有的与函数插值相关的功能都在scipy.interpolate
模块中
from scipy import interpolate
dir(interpolate)[:5]
['Akima1DInterpolator',
'BPoly',
'BarycentricInterpolator',
'BivariateSpline',
'CloughTocher2DInterpolator']
作为介绍性质的本篇,我们将只关注interpolate.spline
的使用,即样条插值方法:
xk
离散的自变量值,为序列yk
对应xk
的函数值,为与xk
长度相同的序列xnew
需要进行插值的自变量值序列order
样条插值使用的函数基德阶数,为1时使用线性函数
print interpolate.spline.__doc__
Interpolate a curve at new points using a spline fit
Parameters
----------
xk, yk : array_like
The x and y values that define the curve.
xnew : array_like
The x values where spline should estimate the y values.
order : int
Default is 3.
kind : string
One of {'smoothest'}
conds : Don't know
Don't know
Returns
-------
spline : ndarray
An array of y values; the spline evaluated at the positions `xnew`.
1.1 三角函数(np.sin
)插值
一例胜千言!让我们这里用实际的一个示例,来说明如何在scipy
中使用函数插值。这里的目标函数是三角函数:
假设我们已经观测到的f(x)
在离散点x=(1,3,5,7,9,11,13)
的值:
import numpy as np
from matplotlib import pylab
import seaborn as sns
font.set_size(20)
x = np.linspace(1.0, 13.0, 7)
y = np.sin(x)
pylab.figure(figsize = (12,6))
pylab.scatter(x,y, s = 85, marker='x', color = 'r')
pylab.title(u'$f(x)$离散点分布', fontproperties = font)
<matplotlib.text.Text at 0x142cafd0>
首先我们使用最简单的线性插值算法,这里面只要将spline
的参数order
设置为1即可:
xnew = np.linspace(1.0,13.0,500)
ynewLinear = interpolate.spline(x,y,xnew,order = 1)
ynewLinear[:5]
array([ 0.84147098, 0.83304993, 0.82462888, 0.81620782, 0.80778677])
复杂一些的,也是spline
函数默认的方法,即为样条插值,将order
设置为3即可:
最后我们获得真实的sin(x)
的值:
ynewReal = np.sin(xnew)
ynewReal[:5]
array([ 0.84147098, 0.85421967, 0.86647437, 0.87822801, 0.88947378])
让我们把所有的函数画到一起,看一下插值的效果。对于我们这个例子中的目标函数而言,由于本身目标函数是光滑函数,则越高阶的样条插值的方法,插值效果越好。
pylab.figure(figsize = (16,8))
pylab.plot(xnew,ynewReal)
pylab.plot(xnew,ynewLinear)
pylab.plot(xnew,ynewCubicSpline)
pylab.scatter(x,y, s = 160, marker='x', color = 'k')
pylab.legend([u'真实曲线', u'线性插值', u'样条插值', u'$f(x)$离散点'], prop = font)
pylab.title(u'$f(x)$不同插值方法拟合效果:线性插值 v.s 样条插值', fontproperties = font)
<matplotlib.text.Text at 0x1424cd50>
2. 函数插值应用 —— 期权波动率曲面构造
市场上期权价格一般以隐含波动率的形式报出,一般来讲在市场交易时间,交易员可以看到类似的波动率矩阵(Volatilitie Matrix):
import pandas as pd
pd.options.display.float_format = '{:,>.2f}'.format
dates = [Date(2015,3,25), Date(2015,4,25), Date(2015,6,25), Date(2015,9,25)]
strikes = [2.2, 2.3, 2.4, 2.5, 2.6]
blackVolMatrix = np.array([[ 0.32562851, 0.29746885, 0.29260648, 0.27679993],
[ 0.28841840, 0.29196629, 0.27385023, 0.26511898],
[ 0.27659511, 0.27350773, 0.25887604, 0.25283775],
[ 0.26969754, 0.25565971, 0.25803327, 0.25407669],
[ 0.27773032, 0.24823248, 0.27340796, 0.24814975]])
table = pd.DataFrame(blackVolMatrix * 100, index = strikes, columns = dates, )
table.index.name = u'行权价'
table.columns.name = u'到期时间'
print u'2015年3月3日10时波动率矩阵'
table
2015年3月3日10时波动率矩阵
到期时间 | March 25th, 2015 | April 25th, 2015 | June 25th, 2015 | September 25th, 2015 |
---|---|---|---|---|
行权价 | ||||
2.20 | 32.56 | 29.75 | 29.26 | 27.68 |
2.30 | 28.84 | 29.20 | 27.39 | 26.51 |
2.40 | 27.66 | 27.35 | 25.89 | 25.28 |
2.50 | 26.97 | 25.57 | 25.80 | 25.41 |
2.60 | 27.77 | 24.82 | 27.34 | 24.81 |
交易员可以看到市场上离散值的信息,但是如果可以获得一些隐含的信息更好:例如,在2015年6月25日以及2015年9月25日之间,波动率的形状会是怎么样的?
2.1 方差曲面插值
我们并不是直接在波动率上进行插值,而是在方差矩阵上面进行插值。方差和波动率的关系如下:
所以下面我们将通过处理,获取方差矩阵(Variance Matrix):
evaluationDate = Date(2015,3,3)
ttm = np.array([(d - evaluationDate) / 365.0 for d in dates])
varianceMatrix = (blackVolMatrix**2) * ttm
varianceMatrix
array([[ 0.00639109, 0.0128489 , 0.02674114, 0.04324205],
[ 0.0050139 , 0.01237794, 0.02342277, 0.03966943],
[ 0.00461125, 0.01086231, 0.02093128, 0.03607931],
[ 0.00438413, 0.0094909 , 0.02079521, 0.03643376],
[ 0.00464918, 0.00894747, 0.02334717, 0.03475378]])
这里的值varianceMatrix
就是变换而得的方差矩阵。
下面我们将在行权价方向以及时间方向同时进行线性插值,具体地,行权价方向:
时间方向:
这个过程在scipy
中可以直接通过interpolate
模块下interp2d
来实现:
ttm
时间方向离散点strikes
行权价方向离散点varianceMatrix
方差矩阵,列对应时间维度;行对应行权价维度kind = 'linear'
指示插值以线性方式进行
interp = interpolate.interp2d(ttm, strikes, varianceMatrix, kind = 'linear')
返回的interp
对象可以用于获取任意点上插值获取的方差值:
interp(ttm[0], strikes[0])
array([ 0.00639109])
最后我们获取整个平面上所有点的方差值,再转换为波动率曲面。
sMeshes = np.linspace(strikes[0], strikes[-1], 400)
tMeshes = np.linspace(ttm[0], ttm[-1], 200)
interpolatedVarianceSurface = np.zeros((len(sMeshes), len(tMeshes)))
for i, s in enumerate(sMeshes):
for j, t in enumerate(tMeshes):
interpolatedVarianceSurface[i][j] = interp(t,s)
interpolatedVolatilitySurface = np.sqrt((interpolatedVarianceSurface / tMeshes))
print u'行权价方向网格数:', np.size(interpolatedVolatilitySurface, 0)
print u'到期时间方向网格数:', np.size(interpolatedVolatilitySurface, 1)
行权价方向网格数: 400
到期时间方向网格数: 200
选取某一个到期时间上的波动率点,看一下插值的效果。这里我们选择到期时间最近的点:2015年3月25日:
pylab.figure(figsize = (16,8))
pylab.plot(sMeshes, interpolatedVolatilitySurface[:, 0])
pylab.scatter(x = strikes, y = blackVolMatrix[:,0], s = 160,marker = 'x', color = 'r')
pylab.legend([u'波动率(线性插值)', u'波动率(离散)'], prop = font)
pylab.title(u'到期时间为2015年3月25日期权波动率', fontproperties = font)
<matplotlib.text.Text at 0xea27f90>
最终,我们把整个曲面的图像画出来看看:
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
maturityMesher, strikeMesher = np.meshgrid(tMeshes, sMeshes)
pylab.figure(figsize = (16,9))
ax = pylab.gca(projection = '3d')
surface = ax.plot_surface(strikeMesher, maturityMesher, interpolatedVolatilitySurface*100, cmap = cm.jet)
pylab.colorbar(surface,shrink=0.75)
pylab.title(u'2015年3月3日10时波动率曲面', fontproperties = font)
pylab.xlabel("strike")
pylab.ylabel("maturity")
ax.set_zlabel(r"volatility(%)")
<matplotlib.text.Text at 0x14e03050>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论