def estimiate_bs_constant_vol(evalDate, calendar, daycounter, option_type): estimate_vol = 0.0 try: vols, spot, mktData, mktFlds, optionData, optionFlds, optionids = wind_data.get_wind_data( evalDate) ql.Settings.instance().evaluationDate = evalDate curve = wind_data.get_curve_treasury_bond(evalDate, daycounter) yield_ts = ql.YieldTermStructureHandle(curve) dividend_ts = ql.YieldTermStructureHandle( ql.FlatForward(evalDate, 0.0, daycounter)) vol = 1.0 step = 0.005 min_sse = 10000 # estimate_vol = 0.0 while vol > step: flat_vol_ts = ql.BlackVolTermStructureHandle( ql.BlackConstantVol(evalDate, calendar, vol, daycounter)) sse = calulate_market_model_price_sse(spot, mktData, mktFlds, optionData, optionFlds, optionids, yield_ts, dividend_ts, flat_vol_ts, option_type) if sse < min_sse: min_sse = sse estimate_vol = vol vol -= step except: print('Error -- estimiate_bs_constant_vol failed') return estimate_vol, min_sse
def get_bsmprocess(self, daycounter, underlying, vol_surface): yield_ts = ql.YieldTermStructureHandle( get_curve_treasury_bond(self.evalDate, daycounter)) dividend_ts = ql.YieldTermStructureHandle( ql.FlatForward(self.evalDate, 0.0, daycounter)) vol_ts = ql.BlackVolTermStructureHandle(vol_surface) process = ql.BlackScholesMertonProcess(ql.QuoteHandle(underlying), dividend_ts, yield_ts, vol_ts) return process
def get_rf_tbcurve(evalDate,daycounter,maturitydate): curve = get_curve_treasury_bond(evalDate, daycounter) maxdate = curve.maxDate() #print(maxdate,maturitydate) if maturitydate > maxdate: rf = curve.zeroRate(maxdate, daycounter, ql.Continuous).rate() else: rf = curve.zeroRate(maturitydate, daycounter, ql.Continuous).rate() return rf
def get_call_put_impliedVols_tbcurve( evalDate, daycounter, calendar, maxVol=1.0, step=0.0001, precision=0.05, show=True): call_volatilities_0 = {} call_volatilities_1 = {} call_volatilities_2 = {} call_volatilities_3 = {} put_volatilites_0 = {} put_volatilites_1 = {} put_volatilites_2 = {} put_volatilites_3 = {} e_date0, e_date1, e_date2, e_date3 = 0, 0, 0, 0 try: curve = get_curve_treasury_bond(evalDate, daycounter) vols, spot, mktData, mktFlds, optionData, optionFlds, optionids = get_wind_data(evalDate) ql.Settings.instance().evaluationDate = evalDate yield_ts = ql.YieldTermStructureHandle(curve) dividend_ts = ql.YieldTermStructureHandle(ql.FlatForward(evalDate, 0.0, daycounter)) month_indexs = get_contract_months(evalDate) for idx, optionid in enumerate(optionids): optionDataIdx = optionData[optionFlds.index('wind_code')].index(optionid) mdate = pd.to_datetime(optionData[optionFlds.index('exercise_date')][optionDataIdx]) maturitydt = ql.Date(mdate.day, mdate.month, mdate.year) mktindex = mktData[mktFlds.index('option_code')].index(optionid) strike = optionData[optionFlds.index('exercise_price')][optionDataIdx] close = mktData[mktFlds.index('close')][mktindex] ttm = daycounter.yearFraction(evalDate, maturitydt) rf = curve.zeroRate(maturitydt, daycounter, ql.Continuous).rate() nbr_month = maturitydt.month() if nbr_month == month_indexs[0]: e_date0 = maturitydt Ft = spot * math.exp(rf * ttm) moneyness = math.log(strike / Ft, math.e) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': optiontype = ql.Option.Call implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) call_volatilities_0.update({moneyness: [implied_vol, strike, close]}) else: optiontype = ql.Option.Put implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) put_volatilites_0.update({moneyness: [implied_vol, strike, close]}) elif nbr_month == month_indexs[1]: e_date1 = maturitydt Ft = spot * math.exp(rf * ttm) moneyness = math.log(strike / Ft, math.e) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': optiontype = ql.Option.Call implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) call_volatilities_1.update({moneyness: [implied_vol, strike, close]}) else: optiontype = ql.Option.Put implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) put_volatilites_1.update({moneyness: [implied_vol, strike, close]}) elif nbr_month == month_indexs[2]: e_date2 = maturitydt Ft = spot * math.exp(rf * ttm) moneyness = math.log(strike / Ft, math.e) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': optiontype = ql.Option.Call implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) call_volatilities_2.update({moneyness: [implied_vol, strike, close]}) else: optiontype = ql.Option.Put implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) put_volatilites_2.update({moneyness: [implied_vol, strike, close]}) else: e_date3 = maturitydt Ft = spot * math.exp(rf * ttm) moneyness = math.log(strike / Ft, math.e) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': optiontype = ql.Option.Call implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) call_volatilities_3.update({moneyness: [implied_vol, strike, close]}) else: optiontype = ql.Option.Put implied_vol, error = calculate_vol_BS(maturitydt, optiontype, strike, spot, dividend_ts, yield_ts, close, evalDate, calendar, daycounter, precision, maxVol, step) put_volatilites_3.update({moneyness: [implied_vol, strike, close]}) expiration_dates = [e_date0, e_date1, e_date2, e_date3] cal_vols = [call_volatilities_0, call_volatilities_1, call_volatilities_2, call_volatilities_3] put_vols = [put_volatilites_0, put_volatilites_1, put_volatilites_2, put_volatilites_3] except Exception as e: print('Error -- get_call_put_impliedVols failed') print(e) return return cal_vols, put_vols, expiration_dates, spot, curve
def add_data(self, k, m, vol, close, open): self.strikes.append(k) self.moneynesses.append(m) self.volatilities.append(vol) self.closes.append(close) self.opens.append(open) w.start() evalDate = ql.Date(24, 3, 2017) calendar = ql.China() daycounter = ql.ActualActual() ql.Settings.instance().evaluationDate = evalDate curve = get_curve_treasury_bond(evalDate, daycounter) yield_ts = ql.YieldTermStructureHandle(curve) dividend_ts = ql.YieldTermStructureHandle(ql.FlatForward(evalDate, 0.0, daycounter)) vols, spot, mktData, mktFlds, optionData, optionFlds, optionids = get_wind_data(evalDate) mdates = [] data_mdates = [] for optionid in optionids: optionDataIdx = optionData[optionFlds.index('wind_code')].index(optionid) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': mktindex = mktData[mktFlds.index('option_code')].index(optionid) tmp = pd.to_datetime(optionData[optionFlds.index('exercise_date')][optionDataIdx]) mdate = datetime.date(tmp.year, tmp.month, tmp.day) maturitydt = ql.Date(mdate.day, mdate.month, mdate.year) strike = optionData[optionFlds.index('exercise_price')][optionDataIdx]
dataset = daily_svi_dataset.get(date) cal_vols, put_vols, maturity_dates, s, rfs = dataset index = 0 mdate = maturity_dates[index] maturitydt = util.to_ql_date(mdate) params_c = paramset_c[index] params_p = paramset_p[index] rf = util.get_rf_tbcurve(date_ql, daycounter, maturitydt) ttm = daycounter.yearFraction(date_ql, maturitydt) discount = math.exp(-rf * ttm) # Example strike = 2.4 dS = 0.001 iscall = True curve = get_curve_treasury_bond(date_ql, daycounter) yield_ts = util.get_yield_ts(date_ql, curve, maturitydt, daycounter) dividend_ts = util.get_dividend_ts(date_ql, daycounter) print('strike = ', strike, ', option type : call') print('=' * 100) print("%10s %25s %25s %25s %25s" % ("Spot", "delta_total", "delta_eff", "delta_constant_vol ", "diff")) print('-' * 100) svi_c = svimodel(ttm, params_c) call_delta_total = [] call_delta_cnst = [] call_delta_eff = [] call_diff = [] #index=['data_total','data_const']
# # if model_price == 0.0: continue # squared_error = (model_price - close) ** 2 # # print(" %15s %25s %25s " % (round(close,6),round(model_price,6), round(squared_error*10000,6))) # sse += squared_error # if sse < min_sse: # min_sse = sse # estimate_vol = vol # vol -= step # estimated_vols.update({evalDate: estimate_vol}) # print(evalDate, ' : ', estimate_vol) for evalDate in dates: # if evalDate in estimated_vols.keys(): continue ql.Settings.instance().evaluationDate = util.to_ql_date(evalDate) svi_data = svi_dataset.get(evalDate).dataSet curve = get_curve_treasury_bond(util.to_ql_date(evalDate), daycounter) yield_ts = ql.YieldTermStructureHandle(curve) dividend_ts = ql.YieldTermStructureHandle( ql.FlatForward(util.to_ql_date(evalDate), 0.0, daycounter)) vol = 0.0 flat_vol_ts = ql.BlackVolTermStructureHandle( ql.BlackConstantVol(util.to_ql_date(evalDate), calendar, vol, daycounter)) vols = [] for mdate in svi_data.keys(): data_mdate = svi_data.get(mdate) strikes = data_mdate.strike spot = data_mdate.spot for i in range(len(strikes)): maturitydt = ql.Date(mdate.day, mdate.month, mdate.year) strike = strikes[i]
spreads_avg_ts = {} callvol_avg_ts = {} putvol_avg_ts = {} call_trading_volum_dic = {} put_trading_volum_dic = {} while evalDate <= endDate: evalDate = calendar.advance(evalDate, ql.Period(1, ql.Days)) spreads_avg = [] callvol_avg = [] putvol_avg = [] trading_volums_call = [] trading_volums_put = [] ql.Settings.instance().evaluationDate = evalDate try: curve = raw_data.get_curve_treasury_bond(evalDate, daycounter) cal_vols_data, put_vols_data = svi_data.get_call_put_impliedVols_strikes(evalDate,curve,daycounter,calendar,maxVol=1.0,step=0.0001,precision=0.001,show=False) # Loop through contract months for idx_month,call_vol_dict in enumerate(cal_vols_data): put_vol_dict = put_vols_data[idx_month] vol_spreads_weights = [] strikes = [] call_sorted = sorted(call_vol_dict.items(), key=operator.itemgetter(0)) call_vol_dict_sorted = dict(call_sorted) put_sorted = sorted(put_vol_dict.items(), key=operator.itemgetter(0)) put_vol_dict_sorted = dict(put_sorted) spread_weightsum = 0.0 callvol_weightsum = 0.0 putvol_weightsum = 0.0 call_amount_strikesum = 0.0 put_amount_strikesum = 0.0