利用BS模型计算欧式看涨期权价格——基于中国沪深300ETF看涨期权_20200524_

利用BS模型计算欧式看涨期权价格——基于中国沪深300ETF看涨期权验证,结果发现当期权虚值程度较深时,理论价格与现实价格差异极大。比如,在近年来沪深300很少能到4600点以上,因此理论价格几乎为零,但是现实市场中仍有投机者在够买
作者:袁江磊

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime
import math
from scipy.stats import norm
plt.rcParams['font.sans-serif']=['simhei']#用于正常显示中文标签
plt.rcParams['axes.unicode_minus']=False#用于正常显示负号
import tushare as ts
pro=ts.pro_api()
pd.set_option('display.max_columns', None)# 显示所有列
pd.set_option('display.max_rows', None)# 显示所有行

class BlackScholes():
    """通过BS模型计算欧式看涨期权价格"""
    def __init__(self,ts_code):
        self.data_ = pro.index_daily(ts_code=ts_code)  # 获得指定标的资产的日行情数据

    def init_info(self,S_0,X,r):
        """S_0为股票初始价格,X为行权价格,r为无风险利率"""
        self.S_0=S_0
        self.X=X
        self.r=r

    def time_through(self):
        """计算期权到期所剩时间,以年为单位"""
        time1 = datetime.datetime.strptime(self.start_date, '%Y%m%d')
        time2 = datetime.datetime.strptime(self.end_date, '%Y%m%d')
        time_ = time2 - time1  # 作差
        days=time_.days
        return days/365

    def cost(self):
        """计算期权费用"""
        d_1 = (math.log(self.S_0 /self.X) + (self.sigma ** 2 / 2 * self.time_)) / (self.sigma * (math.sqrt(self.time_)))
        d_2 = d_1 - self.sigma * math.sqrt(self.time_)
        C = math.exp(-1 * self.r * self.time_) * (self.S_0 * norm.cdf(d_1) - self.X * norm.cdf(d_2))
        return C/1000

    def stock_miu_sigma(self,start_date,end_date):
        """计算股票价格漂移率miu和波动率sigma,,start_date为现在日期(格式'20200305'),end_date为到期日期,sigma为股票价格波动率(标准差)"""
        #ts_code = '000300.SH'
        self.start_date = start_date
        self.end_date = end_date
        self.time_ = self.time_through()

        data_ = self.data_
        data_ = pd.DataFrame(data_[['close','trade_date']])  # 获得其中的收盘价
        data_.sort_values(['trade_date'], ascending=True,inplace=True)
        data_['ratio'] = [0.0000000000000000000] * len(data_)
        data_.index = range(data_.shape[0])

        # 计算股价比率
        for i in range(data_.shape[0] - 1):
            data_['ratio'][i + 1] = np.log(data_['close'][i + 1] / data_['close'][i])

        # 计算基础参数
        T = self.time_*365  # 使用过去T天的数据计算漂移率和波动率,本处使用期权到期所剩时间
        data_train = data_.ix[(len(data_['ratio'])-T):len(data_['ratio']), :]  # 选取过去一月的时间作为训练集

        mean = data_train['ratio'].sum() / T  # 计算样本均值
        S_2 = ((data_train['ratio'] - mean) ** 2).sum() / (T - 1)  # 计算样本方差
        miu = (mean + S_2 / 2) / self.time_  # 股价漂移率
        sigma = np.sqrt(S_2)/np.sqrt(self.time_)  # 股价波动率
        self.miu=miu
        self.sigma = sigma

#300ETF看涨期权日线行情
if __name__=='__main__':
    data_300opt=pd.read_excel('300ETF购.xlsx')
    data_300opt=data_300opt[['最新','行权','到期日']]
    data_300opt['行权']=data_300opt['行权']*1000
    data_300opt.columns=['最新价格','行权','到期日']
    cols=data_300opt.columns
    # 300指数日线行情
    ts_code = '000300.SH'
    close_300=pro.index_daily(ts_code=ts_code)[['trade_date','close']]#沪深300最新收盘价
    #df = pro.index_daily(ts_code=ts_code)

    BS=BlackScholes()
    S_0=close_300['close'][0]#初始股价,不变值
    X=data_300opt['行权'][0]#行权价格
    start_date=close_300['trade_date'][0]#今日日期
    end_date=str(data_300opt['到期日'][0])#行权日期
    BS.stock_miu_sigma(ts_code,start_date,end_date)#波动率
    r = 0.05#无风险收益率
    #print(BS.sigma)
    BS.init_info(S_0,X,r)
    BS.cost()

if __name__=='__main__':
    data_300opt=pd.read_excel('300ETF购.xlsx')#从东方财富下载沪深300指数所有看涨期权的日行情数据
    data_300opt=data_300opt[['最新','行权','到期日']]
    data_300opt['行权']=data_300opt['行权']*1000
    data_300opt.columns=['最新价格','行权','到期日']
    data_300opt['BS价格']=0.0000000
    cols=data_300opt.columns
    # 300指数日线行情
    ts_code = '000300.SH'
    close_300=pro.index_daily(ts_code=ts_code)[['trade_date','close']]#获得标的资产指数沪深300日行情数据
    #df = pro.index_daily(ts_code=ts_code)

    BS=BlackScholes(ts_code)
    for i in range(len(data_300opt['行权'])):
        S_0=close_300['close'][0]#初始股价,不变值
        X=data_300opt['行权'][i]#行权价格
        start_date=close_300['trade_date'][0]#今日日期
        end_date=str(data_300opt['到期日'][i])#行权日期
        BS.stock_miu_sigma(start_date,end_date)#波动率
        r = 0.05#无风险收益率
        #print(BS.sigma)
        BS.init_info(S_0,X,r)
        data_300opt['BS价格'][i]=BS.cost()#将通过BS模型计算的期权理论价格并入
        print('已经完成'+str(round(i/len(data_300opt['行权']),2)*100)+'%')
    data_300opt









你可能感兴趣的:(python日常实例)