def delta_hedge_svi(hedge_date, liquidition_date, daycounter, calendar, spot_c,
                    spot_h, spot_l, black_var_surface, calibrated_params,
                    orgnized_data_l, orgnized_data_h, rfs, optiontype):
    hedge_error_Ms = {}
    hedge_error_pct_Ms = {}
    if optiontype == ql.Option.Call: iscall = True
    else: iscall = False
    for nbr_month in range(4):
        params_Mi = calibrated_params[nbr_month]
        rf = rfs.get(nbr_month)
        moneyness_l, strikes_l, close_prices_l, expiration_date_l = orgnized_data_l.get(
            nbr_month)
        moneyness_h, strikes_h, close_prices_h, expiration_date_h = orgnized_data_h.get(
            nbr_month)
        temp_date = calendar.advance(liquidition_date, ql.Period(5, ql.Days))
        if expiration_date_l <= temp_date: continue
        hedge_errors = []
        hedge_errors_pct = []
        moneyness = []
        ttm = daycounter.yearFraction(hedge_date, expiration_date_h)
        svi = svimodel(ttm, params_Mi)
        discount = math.exp(-rf * ttm)
        forward = spot_c / math.exp(-rf * ttm)
        for idx_k, k in enumerate(strikes_h):
            if k in close_prices_l.keys():
                close_l = close_prices_l.get(k)
            else:
                continue
            close_h = close_prices_h.get(k)
            # No arbitrage condition
            if close_h < k * math.exp(-rf * ttm) - spot_h:
                continue
            if close_h < 0.0001:
                continue
            #delta = hedge_util.calculate_delta_svi(black_var_surface, hedge_date, daycounter, calendar,
            #                                     spot_c, rf, k, expiration_date_h, optiontype)
            dSigma_dK = svi.calculate_dSigma_dK(k, forward, ttm)
            stdDev = svi.svi_iv_function(math.log(k / forward,
                                                  math.e)) * math.sqrt(ttm)
            black = blackcalculator(k, forward, stdDev, discount, iscall)
            delta = black.delta_total(spot_c, dSigma_dK)
            #delta = hedge_util.calculate_effective_delta_svi(hedge_date,daycounter,calendar,params_Mi,spot_c,rf,k,expiration_date_h,optiontype)
            #cash_on_hedge_date = hedge_util.calculate_cash_position(hedge_date, close_h, spot_h, delta)
            #hedge_error = hedge_util.calculate_hedging_error(hedge_date, liquidition_date, daycounter, spot_l, close_l, delta,
            #                                     cash_on_hedge_date, rf)
            t = daycounter.yearFraction(hedge_date, liquidition_date)
            cash_h = close_h - delta * spot_h
            pnl = delta * spot_l + cash_h * math.exp(rf * t) - close_l
            pnl_pct = pnl / close_h
            if abs(pnl_pct) > 10:
                #print(liquidition_date, ',', nbr_month, ',', k, 'too large error', pnl_pct)
                continue
            hedge_error = round(pnl, 4)
            pnl_pct = round(pnl_pct, 4)
            hedge_errors.append(hedge_error)
            hedge_errors_pct.append(pnl_pct)
            moneyness.append(round(spot_h / k, 4))
        hedge_error_Ms.update({nbr_month: [moneyness, hedge_errors]})
        hedge_error_pct_Ms.update({nbr_month: [moneyness, hedge_errors_pct]})
    return hedge_error_Ms, hedge_error_pct_Ms
예제 #2
0
vols = {2.2: 0.2449897447635236, 2.25: 0.22837076995826824, 2.3: 0.21949149068217633, 2.35: 0.20985304700906196, 2.4: 0.2041719266214876, 2.45: 0.20033927445461783, 2.5: 0.19807488063669001, 2.55: 0.19085764979481112, 2.6: 0.19159774017588876, 2.65: 0.1919016701828232, 2.7: 0.1934624432856883, 2.75: 0.19404949435809657}

ttm = (maturitydt-hedge_date).days/365
discount = math.exp(-rf*ttm)
dS = 0.001
iscall = False
engineType = 'AnalyticEuropeanEngine'

print('spot = ',spot)
print('='*100)
print("%10s %25s %25s %25s " % ("Strike","delta_total","delta_eff ","delta_constant_vol "))
print('-'*100)
underlying_ql = ql.SimpleQuote(spot)
daycounter = ql.ActualActual()
calendar = ql.China()
svi = svimodel(ttm,params)
for strike in vols.keys():
    #option_call = OptionPlainVanilla(strike, to_ql_date(maturitydt), ql.Option.Call).get_european_option()
    vol = vols.get(strike)
    #process = evaluation.get_bsmprocess_cnstvol(daycounter,calendar, underlying_ql, vol)
    #engine = OptionEngine(process, engineType).engine
    #option_call.setPricingEngine(engine)
    stdDev = vol * math.sqrt(ttm)
    forward = spot/discount
    black = blackcalculator(strike,forward,stdDev,discount,iscall)

    delta = black.delta(spot)
    # 隐含波动率对行权价的一阶倒数
    dSigma_dK = svi.calculate_dSigma_dK(strike,forward,ttm)
    # 全Delta
    delta_total = black.delta_total(spot,ttm,dSigma_dK)
예제 #3
0
# 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']
result = pd.DataFrame()
for spot in np.arange(2, 3.5, 0.025):
    forward = spot / discount
    x = math.log(strike / forward, math.e)
    vol = svi_c.svi_iv_function(x)
    stdDev = vol * math.sqrt(ttm)

    black = blackcalculator(strike, forward, stdDev, discount, iscall)

    delta = black.delta(spot)