当前位置: 首页 > news >正文

【Python】期权--隐含波动率计算

文章目录

  • 一、期权的概念
    • 1.1 期权的基本要素
    • 1.2 看涨期权和看跌期权
    • 1.3 期权的操作策略
    • 1.4 期权的定价模型
    • 1.5 期权的风险和收益
  • 二、期权定价模型和隐含波动率计算
  • 三、代码示例

一、期权的概念

期权是一种金融衍生工具,赋予持有人在未来某一特定日期或之前以预定价格买入或卖出标的资产的权利,但不承担必须买卖的义务。期权主要分为看涨期权(Call Option)和看跌期权(Put Option)。

这个视频讲的不错:

【从零开始学期权】期权是什么?期权的基础概念和特性(第一集)

1.1 期权的基本要素

  1. 标的资产:期权合约所涉及的资产,可以是股票、指数、商品、货币等。
  2. 行权价格(Strike Price):期权持有人可以在期权到期日或之前买入或卖出标的资产的价格。
  3. 到期日(Expiration Date):期权合约的有效期限,超过此日期期权将失效。
  4. 期权费(Premium):购买期权时支付的费用,是期权的价格。

简单来说,(看涨期权)你可以拿钱去卖方买期权(相当于一张合约、一张合同),你买要花钱,这个就是期权的期权费。现在拥有了一个期权合约,这个合约的作用就是,约定了一个价格(成为行权价格、执行价格),在合约到期(到期日)之前,你有权利以这个价格向卖家买期权合约对应的标的物(标的物可以是股票、指数、商品等等东西),当然了你也可以不买;但是卖家(卖你期权的人)必须(有义务)满足你的权利(以约定的价格即执行价格购买标的物)。

你怎么赚钱呢?

  • 买期权的时候,期权合约不是约定了一个执行价格嘛,就是你可以以这个价格买标的物,但是你买了期权后过了几天,标的物的价格上涨(市场价格浮动嘛)了,那你就可以以低价买高价的东西了(卖家必须卖给你,他交了押金的);
  • 或者你不买标的物,你发现期权的价格上涨了,你就可以把期权卖给别人。
  • 总之就是赚差价,但要注意,期权合约是有时间限制的,超过了约定的到期日,这个合约就没用用了。

当然了,要是标的物价格下跌了、期权价格下跌了,你就亏啦,但最多也就亏个本金嘛,就是你买期权合约花的钱;理论上赚钱是无上限的。

1.2 看涨期权和看跌期权

  • 看涨期权(Call Option):赋予持有人在未来某一日期或之前以特定价格买入标的资产的权利。买入看涨期权的投资者预期标的资产价格将上涨。
  • 看跌期权(Put Option):赋予持有人在未来某一日期或之前以特定价格卖出标的资产的权利。买入看跌期权的投资者预期标的资产价格将下跌。

这两种期权又叫认购期权认沽期权

前面我详细讲解的是看涨期权。

认沽期权也是类似的,标的物价格下跌,你就可以以高价(执行价格)卖给期权卖家了;或者期权价格上涨,你也可以转差价。

欧式期权,只能在到期日行使权利(以执行价格买卖标的物),美式期权则不必。但大多数人,不选择行使权利,而是直接买卖期权(平仓),这样利润更大(不展开解释了)。

期权还有时间价值,简单来说就是离到期日越远,期权的价格、标的物的价格有更多的波动可能性,潜在的价值更高。

此外,你也可以做期权卖家,去卖这2种期权。但这时,你的亏损理论上无限大。

1.3 期权的操作策略

  1. 买入看涨期权(Long Call):预期标的资产价格会上涨,投资者买入看涨期权。
  2. 买入看跌期权(Long Put):预期标的资产价格会下跌,投资者买入看跌期权。
  3. 卖出看涨期权(Short Call):预期标的资产价格不会上涨,投资者卖出看涨期权。
  4. 卖出看跌期权(Short Put):预期标的资产价格不会下跌,投资者卖出看跌期权。

1.4 期权的定价模型

期权定价的主要模型有:

  1. Black-Scholes模型:这是最早也是最著名的期权定价模型,基于无套利理论和对数正态分布假设。
  2. 二叉树模型(Binomial Model):使用树状结构模拟标的资产价格变化,适用于美式期权。
  3. 蒙特卡罗模拟(Monte Carlo Simulation):通过大量随机模拟路径计算期权价格,适用于复杂期权。

1.5 期权的风险和收益

  • 风险:买入期权的最大损失是期权费,而卖出期权的潜在损失是无限的。
  • 收益:买入看涨期权的收益是标的资产价格减去行权价格和期权费;买入看跌期权的收益是行权价格减去标的资产价格和期权费。

二、期权定价模型和隐含波动率计算

常见的期权定价模型有 Black-Scholes 模型,其公式如下:

对于欧式看涨期权(Call Option)的定价公式是:

C = S 0 ⋅ N ( d 1 ) − K ⋅ e − r T ⋅ N ( d 2 ) C = S_0 \cdot N(d_1) - K \cdot e^{-rT} \cdot N(d_2) C=S0N(d1)KerTN(d2)

对于欧式看跌期权(Put Option)的定价公式是:

P = K ⋅ e − r T ⋅ N ( − d 2 ) − S 0 ⋅ N ( − d 1 ) P = K \cdot e^{-rT} \cdot N(-d_2) - S_0 \cdot N(-d_1) P=KerTN(d2)S0N(d1)

其中, d 1 d_1 d1 d 2 d_2 d2 的计算公式为:

d 1 = ln ⁡ ( S 0 K ) + ( r + σ 2 2 ) T σ T d_1 = \frac{\ln\left(\frac{S_0}{K}\right) + \left(r + \frac{\sigma^2}{2}\right)T}{\sigma\sqrt{T}} d1=σT ln(KS0)+(r+2σ2)T

d 2 = d 1 − σ T d_2 = d_1 - \sigma\sqrt{T} d2=d1σT

符号解释:

  • C C C: 看涨期权价格
  • P P P: 看跌期权价格
  • S 0 S_0 S0: 标的资产当前价格
  • K K K: 行权价格
  • r r r: 无风险利率
  • σ \sigma σ: 标的资产的波动率(隐含波动率)
  • T T T: 到期时间
  • N ( ⋅ ) N(\cdot) N(): 标准正态分布函数的累积分布函数

这些公式是基于以下假设的:

  1. 标的资产价格遵循几何布朗运动。
  2. 无风险利率和波动率在期权有效期内保持不变。
  3. 不考虑红利支付。
  4. 市场是无摩擦的(即没有交易成本、税收等)。

根据前面的公式就可以求解隐含波动率,常用的方法有牛顿法、二分法。

三、代码示例

以纳斯达克100指数期权为例,简写NDX。

假设今天是2024-6-15,标的物价格为:19659.8,无风险利率为5.53%,期权价格为 A s k + B i d 2 \frac{Ask+Bid}{2} 2Ask+Bid

到期日为2024-6-21的期权数据:(Skrike:执行价格,Ticker:合约代码,Bid:买方愿出最高价,Ask:买方可就是最低价,Last:最近成交价,Volm:交易量)

CallsPuts
StrikeTickerBidAskLastVolmStrikeTickerBidAskLastVolm
19530NDX 6/21/24 C19530214.1000061229.8000031165.3999939019530NDX 6/21/24 P195306365.4000015367.300003052
19540NDX 6/21/24 C19540206.6000061222160.6499939019540NDX 6/21/24 P1954059.7999992468.1999969570.099998473
19550NDX 6/21/24 C19550199.3000031214.3999939174.47999572919550NDX 6/21/24 P1955062.570.9000015372.699996952
19560NDX 6/21/24 C19560192.1999969207.6000061140219560NDX 6/21/24 P1956065.6999969573.8000030575.900001532
19570NDX 6/21/24 C19570184.8999939200.8999939132.3500061019570NDX 6/21/24 P1957068.5999984776.8000030579.199996958
19575NDX 6/21/24 C19575181.5197.51642519575NDX 6/21/24 P1957569.6999969578.4000015380.300003054
19580NDX 6/21/24 C19580178.1999969194.3000031159.6199951619580NDX 6/21/24 P1958071.300003058086.8499984710
19590NDX 6/21/24 C19590171.1999969187.5140.1999969119590NDX 6/21/24 P1959074.8000030583.4000015385.400001536
19600NDX 6/21/24 C19600164.6000061180.5158.72000121819600NDX 6/21/24 P1960077.8000030586.599998479554
19610NDX 6/21/24 C19610158173.8999939160619610NDX 6/21/24 P1961081.3000030590.1999969587.6299972520
19620NDX 6/21/24 C19620152161.5125.54119620NDX 6/21/24 P196208593.80000305103.110000643
19625NDX 6/21/24 C19625148.8999939158.30000311481819625NDX 6/21/24 P1962586.9000015395.80000305105.150001522
19630NDX 6/21/24 C19630145.6999969155.199996984.19999695019630NDX 6/21/24 P1963088.6999969597.5999984700
19640NDX 6/21/24 C19640139.6000061149135.27000431619640NDX 6/21/24 P1964092.59999847104.5106.510
19650NDX 6/21/24 C19650133.5142.8999939130.89999392119650NDX 6/21/24 P1965096.5105.800003110912
19660NDX 6/21/24 C19660128137.1000061126.5500031519660NDX 6/21/24 P19660100.6999969109.8000031130.51
19670NDX 6/21/24 C19670121.9000015131.1999969111.87999731819670NDX 6/21/24 P19670104.9000015114.0999985145.39999390
19675NDX 6/21/24 C19675119.5999985128.3000031109.1999969619675NDX 6/21/24 P19675107.1999969116.1999969157.39999390
19680NDX 6/21/24 C19680116.0999985125.590.41999817019680NDX 6/21/24 P19680109.6999969118.599998500
19690NDX 6/21/24 C19690110.699996912081.30000305019690NDX 6/21/24 P19690114.4000015123.099998500
19700NDX 6/21/24 C19700105.5114.599998595.470001221019700NDX 6/21/24 P19700119.0999985127.9000015160.55000316
19710NDX 6/21/24 C19710100.3000031109.400001591.80000305419710NDX 6/21/24 P19710123.9000015132.899993900
19720NDX 6/21/24 C1972096104.400001559.31999969019720NDX 6/21/24 P19720128.8999939137.8999939161.39999393
19725NDX 6/21/24 C1972593.19999695101.900001584.05000305119725NDX 6/21/24 P19725131.3999939140.300003100
19730NDX 6/21/24 C1973090.6999969599.580.09999847619730NDX 6/21/24 P19730134.1000061143.199996900
19740NDX 6/21/24 C1974086.3000030594.699996950019740NDX 6/21/24 P19740139.1999969148.500
19750NDX 6/21/24 C1975081.3000030590.0999984780.800003051219750NDX 6/21/24 P19750144.6999969154.1000061198.30000311
19760NDX 6/21/24 C1976076.9000015385.6999969564.5119760NDX 6/21/24 P19760150.1000061165.800003100
19770NDX 6/21/24 C1977073.1999969581.3000030563.40000153419770NDX 6/21/24 P19770155.8000031171.399993900
19775NDX 6/21/24 C1977571.0999984779.3000030568.40000153119775NDX 6/21/24 P19775158.6999969174.199996900
19780NDX 6/21/24 C197806977.1999969560119780NDX 6/21/24 P19780161.600006117700

import pandas as pd
import numpy as np
from scipy.stats import norm
from scipy.optimize import newton
from datetime import datetime
import matplotlib.pyplot as pltclass OptionAnalysis:def __init__(self, file_path):self.file_path = file_pathself.S = 19659.80self.r = 0.0553self.current_date = datetime(2024, 6, 15)self.data = pd.read_excel(file_path, sheet_name=0, header=[0, 1])def bs_price(self, S, K, T, r, sigma, option_type='call'):d1 = (np.log(S / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * np.sqrt(T))d2 = d1 - sigma * np.sqrt(T)if option_type == 'call':return S * norm.cdf(d1) - K * np.exp(-r * T) * norm.cdf(d2)return K * np.exp(-r * T) * norm.cdf(-d2) - S * norm.cdf(-d1)def implied_volatility(self, option_price, S, K, T, r, option_type='call'):def difference(sigma):return self.bs_price(S, K, T, r, sigma, option_type) - option_pricereturn newton(difference, 0.2, tol=1e-5)def process_data(self):strike_calls = self.data[('Calls', 'Strike')].dropna().valuesbid_calls = self.data[('Calls', 'Bid')].dropna().valuesask_calls = self.data[('Calls', 'Ask')].dropna().valuesprice_calls = (bid_calls + ask_calls) / 2strike_puts = self.data[('Puts', 'Strike')].dropna().valuesbid_puts = self.data[('Puts', 'Bid')].dropna().valuesask_puts = self.data[('Puts', 'Ask')].dropna().valuesprice_puts = (bid_puts + ask_puts) / 2expiry_date = datetime.strptime(self.data.index.name, '%m-%d-%y')T = (expiry_date - self.current_date).days / 365implied_vols_calls = [self.implied_volatility(price, self.S, K, T, self.r, 'call') for price, K in zip(price_calls, strike_calls)]implied_vols_puts = [self.implied_volatility(price, self.S, K, T, self.r, 'put') for price, K in zip(price_puts, strike_puts)]self.data[('Calls', 'Implied Volatility')] = pd.Series(implied_vols_calls, index=self.data.index[:len(implied_vols_calls)])self.data[('Puts', 'Implied Volatility')] = pd.Series(implied_vols_puts, index=self.data.index[:len(implied_vols_puts)])return strike_calls, implied_vols_calls, strike_puts, implied_vols_putsdef plot_data(self):strike_calls, implied_vols_calls, strike_puts, implied_vols_puts = self.process_data()plt.figure(figsize=(14, 6))# Callsplt.subplot(1, 2, 1)plt.plot(strike_calls, implied_vols_calls, 'go-', label='Call Implied Volatility')plt.xlabel('Strike Price')plt.ylabel('Implied Volatility')plt.title('Call Implied Volatility vs Strike Prices')plt.grid(True)plt.legend()# Putsplt.subplot(1, 2, 2)plt.plot(strike_puts, implied_vols_puts, 'mo-', label='Put Implied Volatility')plt.xlabel('Strike Price')plt.ylabel('Implied Volatility')plt.title('Put Implied Volatility vs Strike Prices')plt.grid(True)plt.legend()plt.suptitle(f'NDX: Options Implied Volatility', color='blue')plt.tight_layout()plt.savefig('ndx_img/Options_volatility.png')if __name__ == '__main__':file_path = 'NDX.xlsx'analysis = OptionAnalysis(file_path)analysis.plot_data()

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 手把手构建Netty
  • 【前端 · 面试 】TCP 总结(一)—— 概述
  • SpringCloud Alibaba 微服务(四):Sentinel
  • Web前端:HTML篇(一)
  • ubuntu修改anaconda权限
  • 配置文件application.properties
  • input().strip()什么意思
  • jdk1.8中HashMap为什么不直接用红黑树
  • 基于opencv的答题卡识别
  • AI的学习明确路径
  • 环境如何搭建部署Nacos
  • 神经网络的参数初始化【PyTorch】
  • arduino程序-MC猜数字1(基础知识)
  • python I 嵌套列表的多种展开方法
  • 32--蜂鸣器
  • Angular 响应式表单之下拉框
  • Angular2开发踩坑系列-生产环境编译
  • Bytom交易说明(账户管理模式)
  • HTML中设置input等文本框为不可操作
  • mockjs让前端开发独立于后端
  • PHP面试之三:MySQL数据库
  • Python 使用 Tornado 框架实现 WebHook 自动部署 Git 项目
  • Redash本地开发环境搭建
  • Redis在Web项目中的应用与实践
  • Vue.js 移动端适配之 vw 解决方案
  • vue从入门到进阶:计算属性computed与侦听器watch(三)
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 分享几个不错的工具
  • 服务器从安装到部署全过程(二)
  • 高度不固定时垂直居中
  • 搞机器学习要哪些技能
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 通过几道题目学习二叉搜索树
  • 06-01 点餐小程序前台界面搭建
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • 阿里云服务器如何修改远程端口?
  • # Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型
  • #define与typedef区别
  • (11)MSP430F5529 定时器B
  • (20050108)又读《平凡的世界》
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (笔试题)分解质因式
  • (五)Python 垃圾回收机制
  • (正则)提取页面里的img标签
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .NET 5.0正式发布,有什么功能特性(翻译)
  • .NET Framework 和 .NET Core 在默认情况下垃圾回收(GC)机制的不同(局部变量部分)
  • .NET gRPC 和RESTful简单对比
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • /var/log/cvslog 太大
  • @RequestMapping 的作用是什么?
  • @transaction 提交事务_【读源码】剖析TCCTransaction事务提交实现细节
  • @value 静态变量_Python彻底搞懂:变量、对象、赋值、引用、拷贝
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [ACL2022] Text Smoothing: 一种在文本分类任务上的数据增强方法