QuantLib 金融计算——数学工具之求解器
如果未做特别说明,文中的程序都是 Python3 代码。
QuantLib 金融计算——数学工具之求解器
载入模块
import QuantLib as ql
import scipy
from scipy.stats import norm
print(ql.__version__)
1.12
概述
QuantLib 提供了多种类型的一维求解器,用以求解单参数函数的根,
\]
其中 \(f : R \to R\) 是实数域上的函数。
QuantLib 提供的求解器类型有:
BrentBisectionSecantRidderNewton(要求提供成员函数derivative,计算导数)FalsePosition
这些求解器的构造函数均为默认构造函数,不接受参数。例如,Brent 求解器实例的构造语句为 mySolv = Brent()。
调用方式
求解器的成员函数 solve 有两种调用方式:
solve(f,
accuracy,
guess,
step)
solve(f,
accuracy,
guess,
xMin,
xMax)
f:单参数函数或函数对象,返回值为一个浮点数。accuracy:浮点数,表示求解精度 \(\epsilon\),用于停止计算。假设 \(x_i\) 是根的准确解,- 当 \(|f(x)| < \epsilon\);
- 或 \(|x - x_i| < \epsilon\) 时停止计算。
guess:浮点数,对根的初始猜测值。step:浮点数,在第一种调用方式中,没有限定根的区间范围,算法需要自己搜索,确定一个范围。step规定了搜索算法的步长。xMin、xMax:浮点数,左右区间范围
根求解器在量化金融中最经典的应用是求解隐含波动率。给定期权价格 \(p\) 以及其他参数 \(S_0\)、\(K\)、\(r_d\)、\(r_f\)、\(\tau\),我们要计算波动率 \(\sigma\),满足
\]
其中 Black-Scholes 函数中 \(\phi = 1\) 代表看涨期权;\(\phi = −1\) 代表看跌期权。
非 Newton 算法(不需要导数)
下面的例子显示了如何加一个多参数函数包装为一个单参数函数,并使用 QuantLib 求解器计算隐含波动率。
例子 1
# Black-Scholes 函数
def blackScholesPrice(spot,
strike,
rd,
rf,
vol,
tau,
phi):
domDf = scipy.exp(-rd * tau)
forDf = scipy.exp(-rf * tau)
fwd = spot * forDf / domDf
stdDev = vol * scipy.sqrt(tau)
dp = (scipy.log(fwd / strike) + 0.5 * stdDev * stdDev) / stdDev
dm = (scipy.log(fwd / strike) - 0.5 * stdDev * stdDev) / stdDev
res = phi * domDf * (fwd * norm.cdf(phi * dp) - strike * norm.cdf(phi * dm))
return res
# 包装函数
def impliedVolProblem(spot,
strike,
rd,
rf,
tau,
phi,
price):
def inner_func(v):
return blackScholesPrice(spot, strike, rd, rf, v, tau, phi) - price
return inner_func
def testSolver1():
# setup of market parameters
spot = 100.0
strike = 110.0
rd = 0.002
rf = 0.01
tau = 0.5
phi = 1
vol = 0.1423
# calculate corresponding Black Scholes price
price = blackScholesPrice(spot, strike, rd, rf, vol, tau, phi)
# setup a solver
mySolv1 = ql.Bisection()
mySolv2 = ql.Brent()
mySolv3 = ql.Ridder()
accuracy = 0.00001
guess = 0.25
min = 0.0
max = 1.0
myVolFunc = impliedVolProblem(spot, strike, rd, rf, tau, phi, price)
res1 = mySolv1.solve(myVolFunc, accuracy, guess, min, max)
res2 = mySolv2.solve(myVolFunc, accuracy, guess, min, max)
res3 = mySolv3.solve(myVolFunc, accuracy, guess, min, max)
print('{0:<35}{1}'.format('Input Volatility:', vol))
print('{0:<35}{1}'.format('Implied Volatility Bisection:', res1))
print('{0:<35}{1}'.format('Implied Volatility Brent:', res2))
print('{0:<35}{1}'.format('Implied Volatility Ridder:', res3))
testSolver1()
# Input Volatility: 0.1423
# Implied Volatility Bisection: 0.14229583740234375
# Implied Volatility Brent: 0.14230199334812577
# Implied Volatility Ridder: 0.1422999996313447
Newton 算法(需要导数)
Newton 算法要求为根求解器提供 \(f(\sigma)\) 的导数 \(\frac{\partial f}{\partial \sigma}\)(即 vega)。下面的例子显示了如何将导数添加进求解隐含波动率的过程。为此我们需要一个类,一方面提供作为一个函数对象,另一方面要提供成员函数 derivative。
例子 2
class BlackScholesClass:
def __init__(self,
spot,
strike,
rd,
rf,
tau,
phi,
price):
self.spot_ = spot
self.strike_ = strike
self.rd_ = rd
self.rf_ = rf
self.phi_ = phi
self.tau_ = tau
self.price_ = price
self.sqrtTau_ = scipy.sqrt(tau)
self.d_ = norm
self.domDf_ = scipy.exp(-self.rd_ * self.tau_)
self.forDf_ = scipy.exp(-self.rf_ * self.tau_)
self.fwd_ = self.spot_ * self.forDf_ / self.domDf_
self.logFwd_ = scipy.log(self.fwd_ / self.strike_)
def blackScholesPrice(self,
spot,
strike,
rd,
rf,
vol,
tau,
phi):
domDf = scipy.exp(-rd * tau)
forDf = scipy.exp(-rf * tau)
fwd = spot * forDf / domDf
stdDev = vol * scipy.sqrt(tau)
dp = (scipy.log(fwd / strike) + 0.5 * stdDev * stdDev) / stdDev
dm = (scipy.log(fwd / strike) - 0.5 * stdDev * stdDev) / stdDev
res = phi * domDf * (fwd * norm.cdf(phi * dp) - strike * norm.cdf(phi * dm))
return res
def impliedVolProblem(self,
spot,
strike,
rd,
rf,
vol,
tau,
phi,
price):
return self.blackScholesPrice(
spot, strike, rd, rf, vol, tau, phi) - price
def __call__(self,
x):
return self.impliedVolProblem(
self.spot_, self.strike_, self.rd_, self.rf_,
x,
self.tau_, self.phi_, self.price_)
def derivative(self,
x):
# vega
stdDev = x * self.sqrtTau_
dp = (self.logFwd_ + 0.5 * stdDev * stdDev) / stdDev
return self.spot_ * self.forDf_ * self.d_.pdf(dp) * self.sqrtTau_
def testSolver2():
# setup of market parameters
spot = 100.0
strike = 110.0
rd = 0.002
rf = 0.01
tau = 0.5
phi = 1
vol = 0.1423
# calculate corresponding Black Scholes price
price = blackScholesPrice(
spot, strike, rd, rf, vol, tau, phi)
solvProblem = BlackScholesClass(
spot, strike, rd, rf, tau, phi, price)
mySolv = ql.Newton()
accuracy = 0.00001
guess = 0.10
step = 0.001
res = mySolv.solve(
solvProblem, accuracy, guess, step)
print('{0:<20}{1}'.format('Input Volatility:', vol))
print('{0:<20}{1}'.format('Implied Volatility:', res))
testSolver2()
# Input Volatility: 0.1423
# Implied Volatility: 0.14230000000000048
导数的使用明显提高了精度。
QuantLib 金融计算——数学工具之求解器的更多相关文章
- QuantLib 金融计算——数学工具之优化器
目录 QuantLib 金融计算--数学工具之优化器 概述 Optimizer Constraint OptimizationMethod EndCriteria 示例 Rosenbrock 问题 校 ...
- QuantLib 金融计算——数学工具之数值积分
目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...
- QuantLib 金融计算——数学工具之插值
目录 QuantLib 金融计算--数学工具之插值 概述 一维插值方法 二维插值方法 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之插值 载入模块 ...
- QuantLib 金融计算——数学工具之随机数发生器
目录 QuantLib 金融计算--数学工具之随机数发生器 概述 伪随机数 正态分布(伪)随机数 拟随机数 HaltonRsg SobolRsg 两类随机数的收敛性比较 如果未做特别说明,文中的程序都 ...
- QuantLib 金融计算
我的微信:xuruilong100 <Implementing QuantLib>译后记 QuantLib 金融计算 QuantLib 入门 基本组件之 Date 类 基本组件之 Cale ...
- QuantLib 金融计算——高级话题之模拟跳扩散过程
目录 QuantLib 金融计算--高级话题之模拟跳扩散过程 跳扩散过程 模拟算法 面临的问题 "脏"的方法 "干净"的方法 实现 示例 参考文献 如果未做特别 ...
- QuantLib 金融计算——基本组件之 Currency 类
目录 QuantLib 金融计算--基本组件之 Currency 类 概述 构造函数 成员函数 如果未做特别说明,文中的程序都是 python3 代码. QuantLib 金融计算--基本组件之 Cu ...
- QuantLib 金融计算——随机过程之概述
目录 QuantLib 金融计算--随机过程之概述 框架 用法与接口 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--随机过程之概述 载入模块 import Q ...
- QuantLib 金融计算——随机过程之一般 Black Scholes 过程
目录 QuantLib 金融计算--随机过程之一般 Black Scholes 过程 一般 Black Scholes 过程 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib ...
随机推荐
- 修复PlatformToolsets丢失问题(为VS2013以上版本安装VC90,VC100编译器)
前段时间测试VS2017的IDE时不小心弄丢了 MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets 下的VC90以及VC100的编译 ...
- XP+Android手机DIY家庭视频点播系统-历时3周全力打造吊丝的幸福生活
需求场景(纯熟虚构): 1. 哥电脑里有200G电影copy到手机上看没那么大空间,copy一部看一部删除一部,很是不方便也费时间. 2. 小林同学需求比较旺盛但是媳妇总有不方便的时候,家里有 ...
- calico网络
内容请参考:http://www.cnblogs.com/CloudMan6/p/7509975.html
- Shell 常用命令总结
Shell常用命令总结 1 ls命令:列出文件 ls -la 列出当前目录下的所有文件和文件夹 ls a* 列出当前目录下所有以a字母开头的文件 ls -l *.txt 列出当前目录下所有后缀名 ...
- Linux 基础教程 29-tcpdump命令-1
什么是tcpdump 在Linux中输入命令man tcpdump给出的定义如下所示: tcpdump - 转储网络上的数据流 是不是感觉很懵?我们用通俗.形象.学术的表达方式来全方位描述tc ...
- Solr相似度算法一:Lucene TF-IDF 相关性算分公式
Lucene在进行关键词查询的时候,默认用TF-IDF算法来计算关键词和文档的相关性,用这个数据排序 TF:词频,IDF:逆向文档频率,TF-IDF是一种统计方法,或者被称为向量空间模型,名字听起来很 ...
- Solr 从文件创建索引
http://blog.csdn.net/clj198606061111/article/details/21492457 http://wiki.apache.org/solr/Extracting ...
- .Net WebApi部署问题
在IIS上部署web api 完成后,浏览时出现了“The compiler failed with error code -2146232576.”的错误(有时会出现这个情况).主要是 我们在.Ne ...
- leetcode 回文数
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向 ...
- java.lang.IllegalArgumentException: No converter found for return value of type: class com.smart.result.Page
今天学习了一下spring boot 中的mybatis,用mybatis来增删改查用户,获取用户,添加用户,修改用户,删除用户,修改用户,都是可以的,但是获取带分页的用户列表,一直抛出这个java. ...