(零)什么是隐含波动率
期权价格取决于期初价格(S0),执行价格(K),到期期限(T),无风险利率(r),已经波动率(volatility,有时候也写sigma)。(分红不讨论了,可以涵盖在r里)
期权价格V=f(S0,K,T,r,vol)
S0,K,T,r都是客观存在的,vol是期权交易双方的内心预期。
期权的价格V是可以被观察到的,所以我们通过V,S0,K,T,r求解出波动率vol。利用市场价格V倒推出来的vol被称为隐含波动率。
期权交易是一种升维交易,那么隐含波动率能够反映市场情绪么?
(一)数据整理
首先将聚源数据库中的场内期权数据整理为一个便于使用的字典格式:
在T日,得到3个字典。
第一个字典中,
“键”是在T日存在的多个合约的到期日日期。
“值”是一个dataframe,columns是[call,put],index是执行价格,value是【合约代码】。
举例:
第二个字典中,
“键”是在T日存在的多个合约的到期日日期。
“值”是一个dataframe,columns是[call,put],index是执行价格,value是价【价格】。
第三个字典中,
“键”是在T日存在的多个合约的到期日日期。
“值”是一个dataframe,columns是[call,put],index是执行价格,value是价【隐含波动率】。
这里添加了一点,为了反映手续费和佣金,我们计算了加入手续费佣金后的实际隐含波动率。这里我们按1.3元一张计算。(券商内部价)。
(二)隐含波动率
开头有一个对象option,用于计算隐含波动率,有兴趣的同学可以整理到聚宽的方程库中。
使用方法:
(三)隐含波动率热力图
在时间上,我选取了年初一波牛市的起点,中点和终点的日期。以及中美贸易战的几个重要时期。中美贸易战时间轴
看一看贸易战事件和隐含波动率的关系。
1-2
年初
1-10
年初上升阶段
1-24
年初上升顶点
3-23
特朗普宣布对600亿美元中国进口商品增税
4-16
美国对中兴通讯下重手
美拟发起新301调查
4-18
央行降准释放4000亿资金
4-22
美国财长考虑来华磋商
5-4
中美贸易磋商
5-18
特朗普会见刘鹤
7-11
特朗普又打出两千亿关税牌
7-28
美参议院同意降低进口商品关税
8-8
美国确认加征关税的160亿美元
9-12
中国向世贸组织申请授权对美实施贸易报复
欢迎大家讨论。
from jqdata import *
from jqdata import jy
import numpy as np
import pandas as pd
import datetime
from scipy import stats
import seaborn as sns
import matplotlib.pyplot as plt
class option(object):
def __init__(self,S0,K,T,r,sigma,otype):
self.S0=float(S0)
self.K=float(K)
self.T=float(T)
self.r=float(r)
self.sigma=float(sigma)
self.otype=otype
def d1(self):
d1=((log(self.S0/self.K)+(self.r+0.5*self.sigma**2)*self.T)/(self.sigma*sqrt(self.T)))
return d1
def d2(self):
d2=((log(self.S0/self.K)+(self.r-0.5*self.sigma**2)*self.T)/(self.sigma*sqrt(self.T)))
return d2
def value(self):
d1=self.d1()
d2=self.d2()
if self.otype=='Call':
value=self.S0*stats.norm.cdf(d1,0.0,1.0)-self.K*exp(-self.r*self.T)*stats.norm.cdf(d2,0.0,1.0)
elif self.otype=='Put':
value=self.K*exp(-self.r*self.T)*stats.norm.cdf(-d2,0.0,1.0)-self.S0*stats.norm.cdf(-d1,0.0,1.0)
else:
print('option type mistake')
return value
def impvol(self,Price):
a=0
b=1
while b-a>0.001:
self.sigma=(a+b)/2
if self.value()>=Price:
b=self.sigma
else:
a=self.sigma
iv=(a+b)/2
return iv
#def impvol(self,Price):
# def difference(sigma):
# self.sigma=sigma
# return self.value()-Price
# iv=fsolve(difference,0)[0]
# return iv
x=option(100,100,0.25,0.03,0.3,'Call')
print('期权价格 :',x.value())
print('期权隐含波动率:',x.impvol(6.337))
期权价格 : 6.33722015065 期权隐含波动率: 0.30029296875
date=datetime.date(2018,1,24)
S0=get_price('510050.XSHG',start_date=date,end_date=date,fields=['close']).values[0][0]
r=0.03
q=query(jy.Opt_DailyPreOpen).filter(jy.Opt_DailyPreOpen.TradingDate==date,jy.Opt_DailyPreOpen.ULAName=='50ETF')
df=jy.run_query(q).loc[:,['ContractCode','TradingCode','StrikePrice','ExerciseDate']]
exercise_date_list=sorted(df['ExerciseDate'].unique())
key_list=[]
Contract_dict={}
Price_dict={}
impVol_dict={}
for exercise_date in exercise_date_list:
#获得T型代码
df1=df[df['ExerciseDate']==exercise_date]
#去除调整合约
check=[]
for i in df1['TradingCode']:
x=True if i[11]=='M' and i[6]=='C' else False
check.append(x)
df_C=df1[check][['ContractCode','StrikePrice']]
df_C.index=df_C.StrikePrice.values
del df_C['StrikePrice']
df_C.columns=['Call']
df_C=df_C.sort_index()
#去除调整合约
check=[]
for i in df1['TradingCode']:
x=True if i[11]=='M' and i[6]=='P' else False
check.append(x)
df_P=df1[check][['ContractCode','StrikePrice']]
df_P.index=df_P.StrikePrice.values
del df_P['StrikePrice']
df_P.columns=['Put']
df_P=df_P.sort_index()
dfT=pd.concat([df_C,df_P],axis=1)
exercise_date=datetime.datetime.strptime(str(exercise_date)[:10],'%Y-%m-%d')
exercise_date=datetime.date(exercise_date.year,exercise_date.month,exercise_date.day)
Contract_dict[exercise_date]=dfT
#T型价格
q=query(jy.Opt_DailyQuote).filter(jy.Opt_DailyQuote.TradingDate==date)
df2=jy.run_query(q).loc[:,['ContractCode','ClosePrice']]
df2.index=df2['ContractCode'].values
del df2['ContractCode']
dfPrice=dfT.copy()
dfPrice['Call']=df2.loc[dfT.loc[:,'Call'].values,:].values
dfPrice['Put']=df2.loc[dfT.loc[:,'Put'].values,:].values
dfPrice=dfPrice
Price_dict[exercise_date]=dfPrice
dfimpVol=dfPrice.copy()
T=(exercise_date-date).days/365
for K in dfimpVol.index:
for otype in dfimpVol.columns:
optionprice=dfPrice.loc[K,otype]+1.3/10000
x=option(S0,K,T,r,0,otype)
dfimpVol.loc[K,otype]=x.impvol(optionprice)
impVol_dict[exercise_date]=dfimpVol
key_list.append(exercise_date)
key=key_list[0]
strike_index=set(list(impVol_dict[key].index))
for key in key_list[1:]:
strike_index=strike_index&set(impVol_dict[key].index)
weight=[0.25,0.25,0.25,0.25]
i=0
key=key_list[0]
impVol_avg=impVol_dict[key].loc[strike_index,:]*weight[i]
for key in key_list[1:]:
i=i+1
impVol_avg=impVol_avg+impVol_dict[key].loc[strike_index,:]*weight[i]
impVol_avg
ax = sns.heatmap(impVol_avg.values)
ax.set_yticklabels(list(strike_index))
ax.set_xticklabels(list(impVol_avg.columns))
ax.set_title(date)
plt.show()
print('date:',date)
print('S0:',S0)
print('Contract_Dict')
print('{')
key_list=sort(list(impVol_dict.keys()))
for key in key_list:
print(key,':')
print(Contract_dict[key])
print('}')
print('Price_Dict')
print('{')
for key in key_list:
print(key,':')
print(Price_dict[key])
print('}')
print('impliedVolatility_Dict')
print('{')
for key in key_list:
print(key,':')
print(impVol_dict[key])
print('}')
date: 2018-01-24 S0: 3.172 Contract_Dict { 2018-01-24 : Call Put 2.65 10001151 10001153 2.70 10001135 10001136 2.75 10001127 10001128 2.80 10001095 10001100 2.85 10001096 10001101 2.90 10001097 10001102 2.95 10001098 10001103 3.00 10001099 10001104 3.10 10001152 10001154 3.20 10001171 10001172 3.30 10001179 10001180 3.40 10001187 10001188 3.50 10001195 10001196 3.60 10001203 10001204 2018-02-28 : Call Put 2.65 10001155 10001159 2.70 10001156 10001160 2.75 10001141 10001146 2.80 10001142 10001147 2.85 10001143 10001148 2.90 10001144 10001149 2.95 10001145 10001150 3.00 10001157 10001161 3.10 10001158 10001162 3.20 10001173 10001174 3.30 10001181 10001182 3.40 10001189 10001190 3.50 10001197 10001198 3.60 10001205 10001206 2018-03-28 : Call Put 2.65 10001163 10001165 2.70 10001137 10001138 2.75 10001129 10001130 2.80 10001105 10001110 2.85 10001106 10001111 2.90 10001107 10001112 2.95 10001108 10001113 3.00 10001109 10001114 3.10 10001164 10001166 3.20 10001175 10001176 3.30 10001183 10001184 3.40 10001191 10001192 3.50 10001199 10001200 3.60 10001207 10001208 2018-06-27 : Call Put 2.65 10001167 10001169 2.70 10001139 10001140 2.75 10001131 10001132 2.80 10001115 10001120 2.85 10001116 10001121 2.90 10001117 10001122 2.95 10001118 10001123 3.00 10001119 10001124 3.10 10001168 10001170 3.20 10001177 10001178 3.30 10001185 10001186 3.40 10001193 10001194 3.50 10001201 10001202 3.60 10001209 10001210 } Price_Dict { 2018-01-24 : Call Put 2.65 0.5223 0.0001 2.70 0.4628 0.0001 2.75 0.4165 0.0001 2.80 0.3668 0.0001 2.85 0.3195 0.0001 2.90 0.2662 0.0001 2.95 0.2170 0.0001 3.00 0.1645 0.0001 3.10 0.0626 0.0001 3.20 0.0001 0.0180 3.30 0.0001 0.1290 3.40 0.0001 0.2320 3.50 0.0001 0.3320 3.60 0.0001 0.4245 2018-02-28 : Call Put 2.65 0.5301 0.0015 2.70 0.4799 0.0020 2.75 0.4330 0.0027 2.80 0.3843 0.0038 2.85 0.3371 0.0051 2.90 0.2921 0.0080 2.95 0.2435 0.0117 3.00 0.2033 0.0185 3.10 0.1247 0.0400 3.20 0.0693 0.0855 3.30 0.0351 0.1494 3.40 0.0170 0.2323 3.50 0.0092 0.3261 3.60 0.0048 0.4242 2018-03-28 : Call Put 2.65 0.5489 0.0032 2.70 0.5019 0.0040 2.75 0.4561 0.0050 2.80 0.4079 0.0073 2.85 0.3580 0.0104 2.90 0.3126 0.0151 2.95 0.2672 0.0216 3.00 0.2315 0.0298 3.10 0.1601 0.0573 3.20 0.1060 0.1030 3.30 0.0654 0.1634 3.40 0.0413 0.2379 3.50 0.0270 0.3204 3.60 0.0164 0.4146 2018-06-27 : Call Put 2.65 0.5950 0.0126 2.70 0.5515 0.0157 2.75 0.5073 0.0205 2.80 0.4617 0.0266 2.85 0.4214 0.0327 2.90 0.3797 0.0412 2.95 0.3409 0.0524 3.00 0.3045 0.0644 3.10 0.2402 0.0983 3.20 0.1835 0.1417 3.30 0.1402 0.1958 3.40 0.1046 0.2609 3.50 0.0783 0.3319 3.60 0.0589 0.4110 } impliedVolatility_Dict { 2018-01-24 : Call Put 2.65 0.999512 0.999512 2.70 0.000488 0.999512 2.75 0.000488 0.999512 2.80 0.000488 0.999512 2.85 0.000488 0.999512 2.90 0.000488 0.999512 2.95 0.000488 0.999512 3.00 0.000488 0.999512 3.10 0.000488 0.999512 3.20 0.999512 0.000488 3.30 0.999512 0.999512 3.40 0.999512 0.999512 3.50 0.999512 0.999512 3.60 0.999512 0.000488 2018-02-28 : Call Put 2.65 0.246582 0.280762 2.70 0.203613 0.267090 2.75 0.259277 0.252441 2.80 0.245605 0.240723 2.85 0.241699 0.226074 2.90 0.242676 0.219238 2.95 0.215332 0.208496 3.00 0.220215 0.204590 3.10 0.200684 0.189941 3.20 0.199707 0.192871 3.30 0.203613 0.190918 3.40 0.210449 0.197754 3.50 0.227051 0.220215 3.60 0.239746 0.254395 2018-03-28 : Call Put 2.65 0.313965 0.236816 2.70 0.303223 0.225098 2.75 0.295410 0.213379 2.80 0.274902 0.207520 2.85 0.247559 0.201660 2.90 0.233887 0.197754 2.95 0.218262 0.193848 3.00 0.224121 0.187988 3.10 0.213379 0.183105 3.20 0.212402 0.185059 3.30 0.210449 0.184082 3.40 0.217285 0.183105 3.50 0.228027 0.171387 3.60 0.233887 0.178223 2018-06-27 : Call Put 2.65 0.281738 0.205566 2.70 0.275879 0.199707 2.75 0.266113 0.197754 2.80 0.252441 0.195801 2.85 0.247559 0.190918 2.90 0.238770 0.187988 2.95 0.232910 0.187012 3.00 0.228027 0.184082 3.10 0.222168 0.182129 3.20 0.216309 0.180176 3.30 0.216309 0.178223 3.40 0.216309 0.178223 3.50 0.218262 0.173340 3.60 0.222168 0.168457 }
#用作别用
x=pd.DataFrame()
for key in key_list:
y=Price_dict[key]
y['EDate']=key
x=pd.concat([x,y])
x['C-P']=x['Call']-x['Put']
本社区仅针对特定人员开放
查看需注册登录并通过风险意识测评
5秒后跳转登录页面...
移动端课程