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
import numpy as np import datetime evalDate = ql.Date(1, 6, 2016) endDate = ql.Date(1, 4, 2017) calendar = ql.China() daycounter = ql.ActualActual() calibrered_params_ts = {} svi_dataset_ts = [] while evalDate <= endDate: evalDate = calendar.advance(evalDate, ql.Period(1, ql.Days)) ql.Settings.instance().evaluationDate = evalDate try: curve = get_curve_treasury_bond(evalDate, daycounter) vols, spot, mktData, mktFlds, optionData, optionFlds, optionids = get_wind_data( evalDate) except: continue yield_ts = ql.YieldTermStructureHandle(curve) dividend_ts = ql.YieldTermStructureHandle( ql.FlatForward(evalDate, 0.0, daycounter)) svi_dataset = SviInputSet(evalDate) for optionid in optionids: optionDataIdx = optionData[optionFlds.index('wind_code')].index( optionid) if optionData[optionFlds.index('call_or_put')][optionDataIdx] == '认购': temp = pd.to_datetime( optionData[optionFlds.index('exercise_date')][optionDataIdx]) mdate = datetime.date(temp.year, temp.month, temp.day) maturitydt = ql.Date(mdate.day, mdate.month, mdate.year)
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