请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  量化平台 帖子:3365791 新帖:0

场内50ETF期权隐含波动率热力图Vs市场情绪

舞蹈家2发表于:5 月 9 日 20:09回复(1)

(零)什么是隐含波动率

期权价格取决于期初价格(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是【合约代码】。
举例:
contractdict.png
第二个字典中,
“键”是在T日存在的多个合约的到期日日期。
“值”是一个dataframe,columns是[call,put],index是执行价格,value是价【价格】。
第三个字典中,
“键”是在T日存在的多个合约的到期日日期。
“值”是一个dataframe,columns是[call,put],index是执行价格,value是价【隐含波动率】。
这里添加了一点,为了反映手续费和佣金,我们计算了加入手续费佣金后的实际隐含波动率。这里我们按1.3元一张计算。(券商内部价)。

(二)隐含波动率
开头有一个对象option,用于计算隐含波动率,有兴趣的同学可以整理到聚宽的方程库中。
使用方法:
impvolfun.png

(三)隐含波动率热力图
在时间上,我选取了年初一波牛市的起点,中点和终点的日期。以及中美贸易战的几个重要时期。中美贸易战时间轴
看一看贸易战事件和隐含波动率的关系。

1-2
年初
1-2.png

1-10
年初上升阶段
1-10.png

1-24
年初上升顶点
1-24.png

3-23
特朗普宣布对600亿美元中国进口商品增税
3-23.png

4-16
美国对中兴通讯下重手
美拟发起新301调查
4-16.png

4-18
央行降准释放4000亿资金
4-18.png

4-22
美国财长考虑来华磋商
4-22.png

5-4
中美贸易磋商
5-4.png

5-18
特朗普会见刘鹤
5-18.png

7-11
特朗普又打出两千亿关税牌
7-11.png

7-28
美参议院同意降低进口商品关税
7-28.png

8-8
美国确认加征关税的160亿美元
8-8.png

9-12
中国向世贸组织申请授权对美实施贸易报复
9-12.png

欢迎大家讨论。

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']

全部回复

0/140

量化课程

    移动端课程