Using the BS model to calculate the price of European call options——based on China CSI 300 ETF call options_20200524_

Using the BS model to calculate the price of European call options-based on the China CSI 300 ETF call option verification, the results found that when the degree of virtual value of the option is deep, the theoretical price and the actual price are very different. For example, in recent years, the Shanghai and Shenzhen 300 rarely to more than 4600 points, so the theoretical price is almost zero, but in reality there are speculators in the market enough to buy
Author: Yuan Jianglei

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









Guess you like

Origin blog.csdn.net/weixin_45590329/article/details/106319886