def syncetic_payoff(dt_issue, df_daily, vol, N): vol = float(vol) trading_dates = sorted(df_daily[utl.col_date].unique()) idx = trading_dates.index(dt_issue) dt_maturity = trading_dates[idx + 20] dt_list = sorted(df_daily[(df_daily[utl.col_date] >= dt_issue) & (df_daily[utl.col_date] <= dt_maturity)][utl.col_date].unique()) dt1 = dt_list[0] spot = df_daily[df_daily[utl.col_date] == dt1][utl.col_close].values[0] dict_replicates = {} dict_options = {} dict_options2 = {} for i in np.arange(N): df_simulate = montecarlo(s0, vol, dt_list) replication = Replication(s0, dt_issue, dt_maturity, rf=rf, fee=fee_rate) # df_vol = replication.calculate_hist_vol('1M', df_daily) df_res = replication.replicate_put(df_simulate, vol) S = df_simulate[utl.col_close].values[-1] R = df_res['pnl replicate'].values[-1] O = df_res['pnl option'].values[-1] O2 = df_res['value option'].values[-1] dict_replicates.update({S: R}) dict_options.update({S: O}) dict_options2.update({S: O2}) stocks = sorted(dict_replicates) replicates = [value for (key, value) in sorted(dict_replicates.items())] options = [value for (key, value) in sorted(dict_options.items())] options2 = [value for (key, value) in sorted(dict_options2.items())] df = pd.DataFrame() df['stocks'] = stocks df['replicating pnl'] = replicates df['option pnl'] = options df['option payoff'] = options2 return df
def historic_example(dt_issue, df_inderlying, df_cf, df_cf_minute, df_vix): res_histvol = pd.DataFrame() res_vix = pd.DataFrame() trading_dates = sorted(df_cf[utl.col_date].unique()) fut = df_cf[df_cf[utl.col_date] == dt_issue][utl.col_close].values[0] spot = df_inderlying[df_inderlying[utl.col_date] == dt_issue][utl.col_close].values[0] idx = trading_dates.index(dt_issue) # dt_maturity = trading_dates[idx + 20] dt_maturity = trading_dates[idx + 20] strike_dict = creat_replication_set(fut) df_vol = get_hist_vol('1M', df_cf) for m in strike_dict.keys(): strike = strike_dict[m] replication = Replication(strike, dt_issue, dt_maturity, rf=rf, fee=fee_rate) df_res1 = replication.replicate_delta_bounds(df_cf_minute, df_vol) df_res2 = replication.replicate_delta_bounds(df_cf_minute, df_vix) df_res1.loc[:, 'm'] = m df_res2.loc[:, 'm'] = m df_res1.loc[:, 'init underlying'] = spot df_res2.loc[:, 'init underlying'] = spot res_histvol = res_histvol.append(df_res1, ignore_index=True) res_vix = res_vix.append(df_res2, ignore_index=True) # strike = spot # m = 1 # replication = Replication(strike, dt_issue, dt_maturity, rf=rf, fee=fee_rate) # df_res1 = replication.replicate_put(df_intraday, df_vol) # df_res2 = replication.replicate_put(df_intraday, df_vix) # df_res1.loc[:, 'm'] = m # df_res2.loc[:, 'm'] = m # res_histvol = res_histvol.append(df_res1, ignore_index=True) # res_vix = res_vix.append(df_res2, ignore_index=True) return res_histvol, res_vix
def analysis_strikes(dt1, dt2, df_daily, df_intraday, df_vix, df_underlying, cd_vol='1M'): res1 = [] res2 = [] trading_dates = sorted(df_daily[utl.col_date].unique()) dt_list = df_daily[(df_daily[utl.col_date] >= dt1) & (df_daily[utl.col_date] <= dt2)][utl.col_date].unique() df_vol = get_hist_vol(cd_vol, df_daily) for dt in dt_list: print(dt, ' - ', datetime.datetime.now()) dt_issue = dt idx = trading_dates.index(dt_issue) dt_maturity = trading_dates[idx + 20] if dt not in df_underlying[utl.col_date].values: continue spot = df_underlying[df_underlying[utl.col_date] == dt][utl.col_close].values[0] strike_dict = creat_replication_set(spot) res_dic1 = {} res_dic2 = {} replication = Replication(spot, dt_issue, dt_maturity, rf=rf, fee=fee_rate) for m in strike_dict.keys(): strike = strike_dict[m] replication.strike = strike df_res1 = replication.replicate_put(df_intraday, df_vol) r_cost = df_res1['replication cost'].values[-1] r_pnl = df_res1['pnl replicate'].values[-1] o_pnl = df_res1['pnl option'].values[-1] o_payoff = df_res1['value option'].values[-1] pct_cost = df_res1['pct cost'].values[-1] fee = df_res1['transaction fee'].values[-1] r_error = df_res1['replicate error'].values[-1] # mark to option payoff at maturity m = round(m, 2) res_dic1.update({ str(m) + ' pnl replicate ': r_pnl, str(m) + ' pnl option ': o_pnl, str(m) + ' payoff option ': o_payoff, 'cost/spot ' + str(m): r_cost / spot, 'replicate error pct ' + str(m): r_error / spot, 'cost/init_option ' + str(m): pct_cost, 'pct_transaction ' + str(m): fee / spot, 'cd_vol': 'histvol' }) # df_res2 = replication.replicate_put(df_intraday, df_vix) # r_cost2 = df_res2['replication cost'].values[-1] # r_pnl2 = df_res2['pnl replicate'].values[-1] # o_pnl2 = df_res2['pnl option'].values[-1] # o_payoff2 = df_res2['value option'].values[-1] # pct_cost2 = df_res2['pct cost'].values[-1] # fee2 = df_res2['transaction fee'].values[-1] # r_error2 = df_res2['replicate error'].values[-1] # mark to option payoff at maturity # res_dic2.update({ # str(m) + ' pnl replicate ': r_pnl2, # str(m) + ' pnl option ': o_pnl2, # str(m) + ' payoff option ': o_payoff2, # 'cost/spot ' + str(m): r_cost2 / spot, # 'replicate error pct ' + str(m): r_error2 / spot, # 'cost/init_option ' + str(m): pct_cost2, # 'pct_transaction ' + str(m): fee2 / spot, # 'cd_vol': 'vix' # }) res_dic1.update({'dt_date': dt, 'init spot': spot}) # res_dic2.update({'dt_date': dt, 'init spot': spot}) res1.append(res_dic1) # res2.append(res_dic2) df_res1 = pd.DataFrame(res1) df_res2 = pd.DataFrame(res2) return df_res1, df_res2
def hedging_2year_ttm(dt1, dt2, df_daily, df_intraday, df_index, pct_strike, cd_vol): res = [] # 构建期限为1M的平值认沽期权,距到期1W进行期权合约转换 df_vol = get_hist_vol(cd_vol, df_index) df_daily = df_daily[(df_daily[utl.col_date] >= dt1) & (df_daily[utl.col_date] <= dt2)] df_index = df_index[(df_index[utl.col_date] >= dt1) & (df_index[utl.col_date] <= dt2)] trading_dates = sorted(df_index[utl.col_date].unique()) dt_last_issue = trading_dates[-22] df_intraday = df_intraday[ (df_intraday[utl.col_date] >= dt1) & (df_intraday[utl.col_date] <= dt_last_issue)].reset_index(drop=True) # First Option dt_date = trading_dates[0] dt_issue = dt_date spot = df_daily[df_daily[utl.col_date] == dt_date][utl.col_close].values[0] strike = pct_strike * df_index[df_index[utl.col_date] == dt_date][utl.col_close].values[0] underlying = df_index[df_index[utl.col_date] <= dt_date][utl.col_close].values[-1] dt_maturity = dt_issue + datetime.timedelta(days=365*2) Option = EuropeanOption(strike, dt_maturity, utl.type_put) replication = Replication(strike, dt_date, dt_maturity) vol = replication.get_vol(dt_date, df_vol) black = replication.pricing_utl.get_blackcalculator(dt_date, spot, Option, replication.rf, vol) delta0 = black.Delta() option0 = black.NPV() asset = delta0 * spot replicate = asset margin = abs(delta0) * spot * replication.margin_rate transaction_fee = abs(delta0) * (spot * replication.fee + replication.slippage) replicate_pnl = - transaction_fee portfolio0 = underlying + replicate_pnl underlying0 = underlying dt_last = dt_date delta = delta0 for (i, row) in df_intraday.iterrows(): dt_time = pd.to_datetime(row[utl.col_datetime]) dt_date = row[utl.col_date] if dt_date == datetime.date(2017,11,9): print(dt_date) if dt_time.time() < datetime.time(9, 30, 0) or dt_time.time() > datetime.time(15, 0, 0): continue if dt_time.minute % 5 != 0: continue # 5min调整一次delta if dt_date <= dt_issue: continue # issue date 按收盘价 change_pnl = 0.0 if i > 10 and dt_date != dt_last: id_current = row[utl.id_instrument] id_last = df_intraday.loc[i - 1, utl.id_instrument] spot_last = df_intraday.loc[i - 1, utl.col_close] close_list = df_index[df_index[utl.col_date] <= dt_last][utl.col_close] underlying = close_list.values[-1] if len(close_list) >=20: l=close_list.values[-20:0] strike = pct_strike*sum(l)/len(l) replication.strike = strike # 移仓换月 if id_current != id_last: transaction_fee += abs(delta) * (spot_last + spot) * replication.fee # 移仓换月成本 change_pnl = delta * (spot_last - spot) dt_last = dt_date # 每日以收盘价更新组合净值 portfolio = (underlying + replicate_pnl) npv = (underlying + replicate_pnl)/portfolio0 benchmark = underlying/underlying0 res.append({'dt_date': dt_last, 'portfolio': portfolio,'benchmark':benchmark, 'npv':npv,'if spot':spot,'strike':replication.strike, 'margin': margin,'index':underlying,'replicate_pnl':replicate_pnl, 'replicate position':replicate,'delta':delta}) elif dt_date != dt_last: dt_last = dt_date spot = row[utl.col_close] vol = replication.get_vol(dt_date, df_vol) black = replication.pricing_utl.get_blackcalculator(dt_date, spot, Option, replication.rf, vol) gamma = black.Gamma() delta = black.Delta() option_price = black.NPV() H = replication.whalley_wilmott(dt_time.date(), Option, gamma, vol, spot) # 移仓换月 if abs(delta - delta0) >= H: d_asset = (delta - delta0) * spot transaction_fee += abs(delta - delta0) * (spot * replication.fee + replication.slippage) delta0 = delta else: d_asset = 0.0 # delta变化在一定范围内则不选择对冲。 asset += d_asset replicate = asset replicate_pnl = delta * spot - replicate - transaction_fee + change_pnl option_pnl = option_price - option0 replicate_cost = -replicate_pnl + option_pnl replicate_error = -replicate_pnl + max(0, strike - spot) # Mark to option payoff at maturity margin = abs(delta) * spot * replication.margin_rate df_res = pd.DataFrame(res) return df_res
def hedging(dt1, dt2, df_daily, df_intraday, df_index, pct_strike, cd_vol): res = [] # 构建期限为1M的平值认沽期权,距到期1W进行期权合约转换 df_vol = get_hist_vol(cd_vol, df_index) df_intraday[utl.col_date] = df_intraday[utl.col_datetime].apply( lambda x: datetime.date(x.year, x.month, x.day)) df_daily = df_daily[(df_daily[utl.col_date] >= dt1) & (df_daily[utl.col_date] <= dt2)] df_index = df_index[(df_index[utl.col_date] >= dt1) & (df_index[utl.col_date] <= dt2)] trading_dates = sorted(df_index[utl.col_date].unique()) dt_last_issue = trading_dates[-22] df_intraday = df_intraday[ (df_intraday[utl.col_date] >= dt1) & (df_intraday[utl.col_date] <= dt_last_issue)].reset_index(drop=True) # First Option dt_date = trading_dates[0] dt_issue = dt_date dt_maturity = trading_dates[21] spot = df_daily[df_daily[utl.col_date] == dt_date][utl.col_close].values[0] strike = pct_strike * df_index[df_index[utl.col_date] <= dt_date][utl.col_close].values[-1] Option = EuropeanOption(strike, dt_maturity, utl.type_put) replication = Replication(strike, dt_date, dt_maturity) vol = replication.get_vol(dt_date, df_vol) black = replication.pricing_utl.get_blackcalculator(dt_date, spot, Option, replication.rf, vol) delta0 = black.Delta() option0 = black.NPV() asset = delta0 * spot replicate = asset margin = abs(delta0) * spot * replication.margin_rate transaction_fee = abs(delta0) * (spot * replication.fee + replication.slippage) replicate_pnl = - transaction_fee dt_last = dt_date for (i, row) in df_intraday.iterrows(): dt_time = pd.to_datetime(row[utl.col_datetime]) dt_date = row[utl.col_date] if dt_time.time() < datetime.time(9, 30, 0) or dt_time.time() > datetime.time(15, 0, 0): continue if dt_time.minute % 5 != 0: continue # 5min调整一次delta if dt_date <= dt_issue: continue # issue date 按收盘价 idx_today = trading_dates.index(dt_date) idx_maturity = trading_dates.index(dt_maturity) spot = row[utl.col_close] if idx_maturity - idx_today <= 5: dt_issue = dt_date dt_maturity = trading_dates[trading_dates.index(dt_issue) + 21] # spot = df_index[df_index[utl.col_date] == dt_issue][utl.col_close].values[0] spot = df_daily[df_daily[utl.col_date] == dt_date][utl.col_close].values[0] strike = pct_strike * df_index[df_index[utl.col_date] <= dt_date][utl.col_close].values[-1] # 距到期5天以内,按当日收盘价重置期权行权价与到期日 Option = EuropeanOption(strike, dt_maturity, utl.type_put) replication = Replication(strike, dt_issue, dt_maturity) vol = replication.get_vol(dt_date, df_vol) black = replication.pricing_utl.get_blackcalculator(dt_date, spot, Option, replication.rf, vol) gamma = black.Gamma() delta = black.Delta() option_price = black.NPV() H = replication.whalley_wilmott(dt_time.date(), Option, gamma, vol, spot) # 移仓换月 change_pnl = 0.0 if i > 10 and dt_date != dt_last: id_current = row[utl.id_instrument] id_last = df_intraday.loc[i - 1, utl.id_instrument] spot_last = df_intraday.loc[i - 1, utl.col_close] if id_current != id_last: transaction_fee += abs(delta) * (spot_last + spot) * replication.fee # 移仓换月成本 change_pnl = delta * (spot_last - spot) dt_last = dt_date # 每日以收盘价更新组合净值 underlying = df_index[df_index[utl.col_date] <= dt_last][utl.col_close].values[-1] portfolio = underlying + replicate_pnl res.append({'dt_date': dt_last, 'portfolio': portfolio,'if spot':spot, 'margin': margin,'index':underlying,'replicate_pnl':replicate_pnl, 'replicate position':replicate,'delta':delta}) elif dt_date != dt_last: dt_last = dt_date if abs(delta - delta0) >= H: d_asset = (delta - delta0) * spot transaction_fee += abs(delta - delta0) * (spot * replication.fee + replication.slippage) delta0 = delta else: d_asset = 0.0 # delta变化在一定范围内则不选择对冲。 asset += d_asset replicate = asset replicate_pnl = delta * spot - replicate - transaction_fee + change_pnl option_pnl = option_price - option0 replicate_cost = -replicate_pnl + option_pnl replicate_error = -replicate_pnl + max(0, strike - spot) # Mark to option payoff at maturity margin = abs(delta) * spot * replication.margin_rate df_res = pd.DataFrame(res) return df_res