예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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
예제 #5
0
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