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

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

载入 QuantLib 和其他包:

  1. import QuantLib as ql
  2. import numpy as np
  3. import pandas as pd
  4. print(ql.__version__)
  1. 1.15

概述

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

普通欧式期权公式法定价

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

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

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

1. 配置期权合约条款

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

2. 构建期权对象

  1. # 配置行权条款
  2. europeanExercise = ql.EuropeanExercise(maturity)
  3. optionType = ql.Option.Call
  4. payoff = ql.PlainVanillaPayoff(
  5. type=optionType, strike=strike)
  6. # 构建期权对象
  7. europeanOption = ql.VanillaOption(
  8. payoff=payoff,
  9. exercise=europeanExercise)

3. 配置定价引擎

  1. underlying = ql.SimpleQuote(stock)
  2. underlyingH = ql.QuoteHandle(underlying)
  3. # 无风险利率的期限结构
  4. flatRiskFreeTS = ql.YieldTermStructureHandle(
  5. ql.FlatForward(
  6. settlementDate, riskFreeRate, dayCounter))
  7. # 波动率的期限结构
  8. flatVolTS = ql.BlackVolTermStructureHandle(
  9. ql.BlackConstantVol(
  10. settlementDate, calendar,
  11. volatility, dayCounter))
  12. # 构建 BS 过程
  13. bsProcess = ql.BlackScholesProcess(
  14. s0=underlyingH,
  15. riskFreeTS=flatRiskFreeTS,
  16. volTS=flatVolTS)
  17. # 基于 BS 过程的公式定价引擎
  18. pricingEngine = ql.AnalyticEuropeanEngine(
  19. bsProcess)
  20. europeanOption.setPricingEngine(pricingEngine)

4. 计算

  1. # RESULTS
  2. print("Option value =", europeanOption.NPV())
  3. print("Delta value =", europeanOption.delta())
  4. print("Theta value =", europeanOption.theta())
  5. print("Theta perday =", europeanOption.thetaPerDay())
  6. print("Gamma value =", europeanOption.gamma())
  7. print("Vega value =", europeanOption.vega())
  8. print("Rho value =", europeanOption.rho())
  1. Option value = 2.395988448539984
  2. Delta value = 0.5213970624832108
  3. Theta value = -4.309457134907618
  4. Theta perday = -0.011806731876459226
  5. Gamma value = 0.06563585494066533
  6. Vega value = 12.089225358769994
  7. 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 年:

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

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

Quote 带来的便利

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

  1. # USE QUOTE
  2. stock_array = np.arange(
  3. start=30, stop=70, step=0.01)
  4. NPV = np.array([np.nan] * len(stock_array))
  5. delta = np.array([np.nan] * len(stock_array))
  6. theta = np.array([np.nan] * len(stock_array))
  7. # thetaPerDay = np.array([np.nan] * len(stock_array))
  8. gamma = np.array([np.nan] * len(stock_array))
  9. vega = np.array([np.nan] * len(stock_array))
  10. rho = np.array([np.nan] * len(stock_array))
  11. for i, v in enumerate(stock_array):
  12. # 重置 Quote 对象的值
  13. underlying.setValue(v)
  14. # 无须再次配置计算流程,直接计算
  15. NPV[i] = europeanOption.NPV()
  16. delta[i] = europeanOption.delta()
  17. theta[i] = europeanOption.theta()
  18. # thetaPerDay[i] = europeanOption.thetaPerDay()
  19. gamma[i] = europeanOption.gamma()
  20. vega[i] = europeanOption.vega()
  21. rho[i] = europeanOption.rho()
  22. result = pd.DataFrame(
  23. data=dict(
  24. NPV=NPV,
  25. delta=delta,
  26. theta=theta,
  27. # thetaPerDay=thetaPerDay,
  28. gamma=gamma,
  29. vega=vega, rho=rho),
  30. index=stock_array)
  31. result.plot(subplots=True)

总结

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

QuantLib 金融计算——案例之普通欧式期权分析的更多相关文章

  1. QuantLib 金融计算——QuantLib 入门

    目录 QuantLib 金融计算--QuantLib 入门 简介 主要功能 安装与使用 学习指南 The HARD Way The EASY Way QuantLib 金融计算--QuantLib 入 ...

  2. QuantLib 金融计算——数学工具之数值积分

    目录 QuantLib 金融计算--数学工具之数值积分 概述 常见积分方法 高斯积分 如果未做特别说明,文中的程序都是 Python3 代码. QuantLib 金融计算--数学工具之数值积分 载入模 ...

  3. QuantLib 金融计算

    我的微信:xuruilong100 <Implementing QuantLib>译后记 QuantLib 金融计算 QuantLib 入门 基本组件之 Date 类 基本组件之 Cale ...

  4. QuantLib 金融计算——基本组件之 Currency 类

    目录 QuantLib 金融计算--基本组件之 Currency 类 概述 构造函数 成员函数 如果未做特别说明,文中的程序都是 python3 代码. QuantLib 金融计算--基本组件之 Cu ...

  5. QuantLib 金融计算——高级话题之模拟跳扩散过程

    目录 QuantLib 金融计算--高级话题之模拟跳扩散过程 跳扩散过程 模拟算法 面临的问题 "脏"的方法 "干净"的方法 实现 示例 参考文献 如果未做特别 ...

  6. QuantLib 金融计算——修复 BatesProcess 中的两个 Bug

    QuantLib 金融计算--修复 BatesProcess 中的两个 Bug 我发现了 BatesProcess 中的两个 Bug: 基类 HestonProcess::factors 的返回值取决 ...

  7. QuantLib 金融计算——基本组件之 Date 类

    目录 QuantLib 金融计算--基本组件之 Date 类 Date 对象的构造 一些常用的成员函数 一些常用的静态函数 为估值计算配置日期 如果未做特别说明,文中的程序都是 Python3 代码. ...

  8. QuantLib 金融计算——基本组件之 Calendar 类

    目录 QuantLib 金融计算--基本组件之 Calendar 类 Calendar 对象的构造 一些常用的成员函数 自定义假期列表 工作日修正 如果未做特别说明,文中的程序都是 Python3 代 ...

  9. QuantLib 金融计算——基本组件之 DayCounter 类

    目录 QuantLib 金融计算--基本组件之 DayCounter 类 DayCounter 对象的构造 一些常用的成员函数 如果未做特别说明,文中的程序都是 Python3 代码. QuantLi ...

随机推荐

  1. 完美转发(perfect forwarding)、universal reference、引用折叠(collasping)

    首先要分清: C++里的值只有两种值:左值.右值.—— 其本质应该是内存中存储的值/instance分两种:一种是持久的,一种是“短暂的” 也只有两种引用: 左值引用.右值引用. ——引用,就是这个内 ...

  2. crawler_app_在Airtest无线模式控制手机

    无线模式开启: adb tcpip 48887 参考引用:  https://www.cnblogs.com/xieqiankun/p/wireless-mode-of-poco.html

  3. 【开发工具】- Xshell过期了怎么办?

    点击下边链接下载免费版 http://www.netsarang.com/download/free_license.html

  4. 如何设计提高服务API的安全性(二)API密钥方式详解

    在上文已经讲述了基础介绍,这篇文章详细讲解API密钥方式. 利用何种加密方式呢? 经过上面加密算法的理解,单向加密不仅性能高,而且有压缩性,即长度一致,有效减少网络传输过程中的字节大小.适合我们这种调 ...

  5. NIO的整体认识

    目录 1.Java NIO简介 2.java NIO和IO的主要区别 3.缓冲区buffer和通道channel 3.1.缓冲区buffer 3.2.channel 4.文件通道fileChannel ...

  6. loadrunner 基本操作

    1.录制(录制选项) 2.回放(运行时设置) 3.添加事物 4.参数化 5.内容检查 6.添加集合点 1.在脚本中添加集合点函数如下: lr_rendezvous("集合点") / ...

  7. 01篇ELK日志系统——升级版集群之elasticsearch集群的搭建

    [ 前言:以前搭了个简单的ELK日志系统,以我个人的感觉来说,ELK日志系统还是非常好用的.以前没有弄这个ELK日志系统的时候,线上的项目出了bug,报错了,要定位错误是什么,错误出现在哪个java代 ...

  8. Linux自有服务(1)-Linux从入门到精通第五天(非原创)

    文章大纲 一.运行模式二.用户与用户组管理(重点)三.网络设置四.ssh服务(重点)五.学习资料下载六.参考文章   自有服务,即不需要用户独立去安装的软件的服务,而是当系统安装好之后就可以直接使用的 ...

  9. notepad++ 设置运行python脚本

    按F5 在输入框中输入: cmd /k python “$(FULL_CURRENT_PATH)” &PAUSE & EXIT python路径必须在环境变量中. 否则需要输入完整的p ...

  10. Semaphore的简介及应用场景

    Semaphore是一个计数信号量,常用于限制可以访问某些资源(物理或逻辑的)线程数目. 常用函数: 信号量的构造函数 非公平: public Semaphore(int permits);//per ...