QuantLib 金融计算——案例之普通欧式期权分析

2023-11-03 23:59

本文主要是介绍QuantLib 金融计算——案例之普通欧式期权分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • QuantLib 金融计算——案例之普通欧式期权分析
    • 概述
    • 普通欧式期权公式法定价
      • 1. 配置期权合约条款
      • 2. 构建期权对象
      • 3. 配置定价引擎
      • 4. 计算
      • 题外话:天数计算规则
    • Quote 带来的便利
    • 总结

如果未做特别说明,文中的程序都是 python3 代码。

QuantLib 金融计算——案例之普通欧式期权分析

载入 QuantLib 和其他包:

import QuantLib as ql
import numpy as np
import pandas as pdprint(ql.__version__)
1.15

概述

从金融工程中最简单的案例——“普通欧式期权公式法定价”入手,介绍 QuantLib 中期权分析的基本组件,以及如何将这些组件拼接成为一个完整的计算流程。

普通欧式期权公式法定价

采用《期权、期货及其他衍生产品(第 7 版)》第 17 章中的例子:

  • 类型:普通欧式看涨期权
  • 当前价格:49$
  • 敲定价格:50$
  • 无风险利率:5%
  • 年化波动率:20%
  • 期限:20 周

使用 BS 公式为上述期权定价,并计算希腊值。

1. 配置期权合约条款

# 配置日期计算条款
calendar = ql.UnitedStates(ql.UnitedStates.NYSE)
dayCounter = ql.Actual365Fixed(ql.Actual365Fixed.Standard)todayDate = ql.Date(11, ql.July, 2019)
maturity = todayDate + ql.Period(20, ql.Weeks)
settlementDate = todayDate# 配置期权参数
stock = 49
strike = 50
riskFreeRate = 0.05
volatility = 0.2# 配置全局估值日期
ql.Settings.instance().evaluationDate = todayDate

2. 构建期权对象

# 配置行权条款
europeanExercise = ql.EuropeanExercise(maturity)
optionType = ql.Option.Call
payoff = ql.PlainVanillaPayoff(type=optionType, strike=strike)# 构建期权对象
europeanOption = ql.VanillaOption(payoff=payoff,exercise=europeanExercise)

3. 配置定价引擎

underlying = ql.SimpleQuote(stock)
underlyingH = ql.QuoteHandle(underlying)# 无风险利率的期限结构
flatRiskFreeTS = ql.YieldTermStructureHandle(ql.FlatForward(settlementDate, riskFreeRate, dayCounter))# 波动率的期限结构
flatVolTS = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(settlementDate, calendar,volatility, dayCounter))# 构建 BS 过程
bsProcess = ql.BlackScholesProcess(s0=underlyingH,riskFreeTS=flatRiskFreeTS,volTS=flatVolTS)# 基于 BS 过程的公式定价引擎
pricingEngine = ql.AnalyticEuropeanEngine(bsProcess)europeanOption.setPricingEngine(pricingEngine)

4. 计算

# RESULTSprint("Option value =", europeanOption.NPV())
print("Delta value  =", europeanOption.delta())
print("Theta value  =", europeanOption.theta())
print("Theta perday =", europeanOption.thetaPerDay())
print("Gamma value  =", europeanOption.gamma())
print("Vega value   =", europeanOption.vega())
print("Rho value    =", europeanOption.rho())
Option value = 2.395988448539984
Delta value  = 0.5213970624832108
Theta value  = -4.309457134907618
Theta perday = -0.011806731876459226
Gamma value  = 0.06563585494066533
Vega value   = 12.089225358769994
Rho value    = 8.88039853654583

题外话:天数计算规则

上述例子中的计算结果和书中给出的结果略有出入,依经验判断,最有可能造成计算不一致的原因是“天数计算规则的不一致”。

详细来说,书中期权的期限是 20 周,作者认为 20 周等于 0.3846 年,可能的依据有:

  • \(20 \times 7 / 364(\text{not } 365) \approx 0.3846\) (即 Actual/364)或
  • \(20 \times 5(\text{weekday}) / [52(\approx 365/7)\times 5(\text{weekday})] \approx 0.3846\)

目前,QuantLib 中并不支持这两种天数计算规则。例子中出现的规则 Actual365Fixed(Actual365Fixed.Standard) 认为 20 周等于 0.38356 年:

print(dayCounter.yearFraction(settlementDate, maturity))
# 0.3835616438356164

对于期权来说,天数计算规则的影响可能微不足道,但是对于固定收益类金融工具及其衍生品来说,天数计算规则的选择至关重要,“失之毫厘,谬以千里”。

Quote 带来的便利

QuantLib 中有相当多的组件接受 Handle 类型的参数,而这些参数通常持有一个 Quote 类型的变量。借助“观察者模式”,用户修改 Quote 类型变量的值将会自动通知相关组件,并使其重新进行性计算,而无需再次构建一遍计算流程。对于某些用途来讲,这带来了相当大的便利。

# USE QUOTEstock_array = np.arange(start=30, stop=70, step=0.01)NPV = np.array([np.nan] * len(stock_array))
delta = np.array([np.nan] * len(stock_array))
theta = np.array([np.nan] * len(stock_array))
# thetaPerDay = np.array([np.nan] * len(stock_array))
gamma = np.array([np.nan] * len(stock_array))
vega = np.array([np.nan] * len(stock_array))
rho = np.array([np.nan] * len(stock_array))for i, v in enumerate(stock_array):# 重置 Quote 对象的值underlying.setValue(v)# 无须再次配置计算流程,直接计算NPV[i] = europeanOption.NPV()delta[i] = europeanOption.delta()theta[i] = europeanOption.theta()# thetaPerDay[i] = europeanOption.thetaPerDay()gamma[i] = europeanOption.gamma()vega[i] = europeanOption.vega()rho[i] = europeanOption.rho()result = pd.DataFrame(data=dict(NPV=NPV,delta=delta,theta=theta,# thetaPerDay=thetaPerDay,gamma=gamma,vega=vega, rho=rho),index=stock_array)result.plot(subplots=True)

232518-20190714170058131-252664972.png

总结

下面用一副图显示上述例子中的若干变量如何汇聚成一个计算流程:

232518-20190714170105966-109512616.png

转载于:https://www.cnblogs.com/xuruilong100/p/11184791.html

这篇关于QuantLib 金融计算——案例之普通欧式期权分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/341781

相关文章

Springboot中分析SQL性能的两种方式详解

《Springboot中分析SQL性能的两种方式详解》文章介绍了SQL性能分析的两种方式:MyBatis-Plus性能分析插件和p6spy框架,MyBatis-Plus插件配置简单,适用于开发和测试环... 目录SQL性能分析的两种方式:功能介绍实现方式:实现步骤:SQL性能分析的两种方式:功能介绍记录

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

使用Navicat工具比对两个数据库所有表结构的差异案例详解

《使用Navicat工具比对两个数据库所有表结构的差异案例详解》:本文主要介绍如何使用Navicat工具对比两个数据库test_old和test_new,并生成相应的DDLSQL语句,以便将te... 目录概要案例一、如图两个数据库test_old和test_new进行比较:二、开始比较总结概要公司存在多

C#使用DeepSeek API实现自然语言处理,文本分类和情感分析

《C#使用DeepSeekAPI实现自然语言处理,文本分类和情感分析》在C#中使用DeepSeekAPI可以实现多种功能,例如自然语言处理、文本分类、情感分析等,本文主要为大家介绍了具体实现步骤,... 目录准备工作文本生成文本分类问答系统代码生成翻译功能文本摘要文本校对图像描述生成总结在C#中使用Deep

SpringBoot实现动态插拔的AOP的完整案例

《SpringBoot实现动态插拔的AOP的完整案例》在现代软件开发中,面向切面编程(AOP)是一种非常重要的技术,能够有效实现日志记录、安全控制、性能监控等横切关注点的分离,在传统的AOP实现中,切... 目录引言一、AOP 概述1.1 什么是 AOP1.2 AOP 的典型应用场景1.3 为什么需要动态插

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

使用C#代码计算数学表达式实例

《使用C#代码计算数学表达式实例》这段文字主要讲述了如何使用C#语言来计算数学表达式,该程序通过使用Dictionary保存变量,定义了运算符优先级,并实现了EvaluateExpression方法来... 目录C#代码计算数学表达式该方法很长,因此我将分段描述下面的代码片段显示了下一步以下代码显示该方法如

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维