def main():
    # Bull-Spread implementation example

    # default market environment
    market_env = MarketEnvironment()
    print(market_env)

    # options strikes
    K_long = 80
    K_short = 110

    # bull-spread portfolio initialized (as empty portfolio)   
    bull_spread_ptf = Portfolio(name="Bull Spread Strategy")
    print(bull_spread_ptf)

    # 80-call
    Vanilla_Call_long = PlainVanillaOption(market_env, K=K_long, T='31-12-2021')
    print(Vanilla_Call_long)

    # 110-call
    Vanilla_Call_short = PlainVanillaOption(market_env, K=K_short, T='31-12-2021')
    print(Vanilla_Call_short)

    # creation of bull-spread portfolio strategy   
    bull_spread_ptf.add_instrument(Vanilla_Call_long, 1)
    bull_spread_ptf.add_instrument(Vanilla_Call_short, -1)
    print(bull_spread_ptf)

    # portfolio plotter instance
    bull_spread_ptf_plotter = PortfolioPlotter(bull_spread_ptf)

    # select metrics to plot
    for plot_metrics in ["price", "PnL", "delta", "theta", "gamma", "vega", "rho"]:

        plot_details_flag = True if plot_metrics == "price" else False

        # Bull-Spread price plot
        bull_spread_ptf_plotter.plot(t='01-06-2020', plot_metrics=plot_metrics,
                                     plot_details=plot_details_flag)

        for time_kind in ['date', 'tau']:
            # set time-parameter to plot
            multiple_valuation_dates = get_time_parameter(bull_spread_ptf, kind=time_kind)
            print(multiple_valuation_dates)

            # Plot at multiple dates
            bull_spread_ptf_plotter.plot(t=multiple_valuation_dates, plot_metrics=plot_metrics)

            # Surface plot
            bull_spread_ptf_plotter.plot(t=multiple_valuation_dates, plot_metrics=plot_metrics,
                                         surf_plot=True)

            # Surface plot (rotate) - Underlying value side
            bull_spread_ptf_plotter.plot(t=multiple_valuation_dates, plot_metrics=plot_metrics,
                                         surf_plot=True, view=(0, 180))

            # Price surface plot (rotate) - Date side
            bull_spread_ptf_plotter.plot(t=multiple_valuation_dates, plot_metrics=plot_metrics,
                                         surf_plot=True, view=(0, -90))
Esempio n. 2
0
def option_factory(mkt_env, plain_or_digital, option_type):
    option_dispatcher = {
        "plain_vanilla": {"call": PlainVanillaOption(mkt_env),
                          "put": PlainVanillaOption(mkt_env, option_type="put")
                          },
        "digital": {"call": DigitalOption(mkt_env),
                    "put": DigitalOption(mkt_env, option_type="put")
                    }
    }

    return option_dispatcher[plain_or_digital][option_type]
Esempio n. 3
0
def setPortfolio():
    
    mktEnv = MarketEnvironment()
    # strikes
    kl = 90
    ks = 110
    print(mktEnv)
    option_spread_ptf = Portfolio(name="Option Spread")
    print(option_spread_ptf)
      # 90-call
    vcl = PlainVanillaOption(mktEnv, K=kl, T='31-12-2021')
    print(vcl)
    
    vcs = PlainVanillaOption(mktEnv, K=ks, T='31-12-2021')
    print(vcs)

    # creation of bull-spread portfolio strategy   
    option_spread_ptf.add_instrument(vcl, 1)
    option_spread_ptf.add_instrument(vcs, -1)
    print(option_spread_ptf)
    def setUp(self) -> None:
        warnings.filterwarnings("ignore")

        # common market environment
        mkt_env = MarketEnvironment(t="01-06-2020")

        # underlying values to test
        S_vector = [60, 90, 120]

        # options maturities
        T_call = "31-12-2020"
        T_put = "30-06-2021"

        # time parameter
        t_range = pd.date_range(start=mkt_env.get_t(), end=T_call, periods=3)

        # pricing parameters
        self.params = {"S": S_vector, "t": t_range, "np_output": False}

        # options strikes
        K_put = 80
        K_call = 110

        # portfolio options positions
        self.call_pos = 2
        self.put_pos = -5

        # empty portfolio initialized
        self.ptf = Portfolio()

        # adding 2 long plain-vanilla call contracts
        self.call_opt = PlainVanillaOption(mkt_env, K=K_call, T=T_call)

        # adding 5 short plain-vanilla put contracts
        self.put_opt = PlainVanillaOption(mkt_env, option_type="put", K=K_put, T=T_put)

        # adding contracts to portfolio
        self.ptf.add_instrument(self.call_opt, self.call_pos)
        self.ptf.add_instrument(self.put_opt, self.put_pos)
def main():
    #
    # portfolio instantiation example
    #

    # if np_output is True, the output will be np.ndarray, otherwise pd.DataFrame    
    np_output = False  # True

    # default market environment
    market_env = MarketEnvironment(t="01-06-2020")
    print(market_env)

    # underlying values to test
    S_vector = [60, 90, 120]
    print("S_vector: {}\n".format(S_vector))

    # options maturities
    T_call = "31-12-2020"
    T_put = "30-06-2021"  # T_call

    # choose the kind of time-parameter to use: either a date ('date') or a 
    # time-to-maturity ('ttm'). Time-to-maturity time parameter is not allowed 
    # for multi-horizon portfolios.
    time_parameter = 'date'  # 'ttm'

    # get time parameter
    t_range = get_time_parameter(market_env,
                                 end_date=min(T_call, T_put, key=date_string_to_datetime_obj),
                                 periods=5,
                                 kind=time_parameter,
                                 multi_horizon_ptf=T_call != T_put)

    # options strikes
    K_put = 80
    K_call = 110

    # portfolio options positions
    call_pos = 2
    put_pos = -5

    #
    # Step 0: empty portfolio initialized
    #

    ptf = Portfolio()
    print(ptf)

    #
    # Step 1: adding 2 long plain-vanilla call contracts
    #

    # plain-vanilla call option
    call = PlainVanillaOption(market_env, K=K_call, T=T_call)
    print(call)

    # adding contract to portfolio  
    ptf.add_instrument(call, call_pos)
    print(ptf)

    # metrics to compare
    for metrics in ["price", "PnL", "delta", "theta", "gamma", "vega", "rho"]:
        # portfolio metrics
        ptf_metrics = getattr(ptf, metrics)(S=S_vector, t=t_range, np_output=np_output)
        print("\nPortfolio {}:\n{}".format(metrics, ptf_metrics))

        # verification with benchmark metrics
        call_metrics = getattr(call, metrics)(S=S_vector, t=t_range, np_output=np_output)
        benchmark_metrics = call_pos * call_metrics
        print("\nBenchmark {}:\n{}".format(metrics, benchmark_metrics))

        # check effective match
        diff = (ptf_metrics - benchmark_metrics).astype('float')
        num_nonzero_diff = np.count_nonzero(diff) - np.isnan(diff).sum().sum()
        exact_match = True if num_nonzero_diff == 0 else False
        print("\nIs replication exact (NaN excluded)? {}\n".format(exact_match))

    #
    # Step 2: adding 5 short plain-vanilla put contracts
    #

    # plain-vanilla put option
    put = PlainVanillaOption(market_env, option_type="put", K=K_put, T=T_put)
    print(put)

    # adding contract to portfolio  
    ptf.add_instrument(put, put_pos)
    print(ptf)

    # metrics to compare
    for metrics in ["price", "PnL", "delta", "theta", "gamma", "vega", "rho"]:
        # portfolio metrics
        ptf_metrics = getattr(ptf, metrics)(S=S_vector, t=t_range, np_output=np_output)
        print("\nPortfolio {}:\n{}".format(metrics, ptf_metrics))

        # verification with benchmark metrics
        call_metrics = getattr(call, metrics)(S=S_vector, t=t_range, np_output=np_output)
        put_metrics = getattr(put, metrics)(S=S_vector, t=t_range, np_output=np_output)
        benchmark_metrics = call_pos * call_metrics + put_pos * put_metrics
        print("\nBenchmark {}:\n{}".format(metrics, benchmark_metrics))

        # check effective match
        diff = (ptf_metrics - benchmark_metrics).astype('float')
        num_nonzero_diff = np.count_nonzero(diff) - np.isnan(diff).sum().sum()
        exact_match = True if num_nonzero_diff == 0 else False
        print("\nIs replication exact (NaN excluded)? {}\n".format(exact_match))
def main():
    # Bull-Spread implementation example

    # default market environment
    market_env = MarketEnvironment()
    print(market_env)

    # options strikes
    K_long = 80
    K_short = 110

    # bull-spread portfolio initialized (as empty portfolio)   
    bull_spread_ptf = Portfolio(name="Bull Spread Strategy")
    print(bull_spread_ptf)

    # 80-call
    Vanilla_Call_long = PlainVanillaOption(market_env, K=K_long, T='31-12-2021')
    print(Vanilla_Call_long)

    # 110-call
    Vanilla_Call_short = PlainVanillaOption(market_env, K=K_short, T='31-12-2021')
    print(Vanilla_Call_short)

    # creation of bull-spread portfolio strategy   
    bull_spread_ptf.add_instrument(Vanilla_Call_long, 1)
    bull_spread_ptf.add_instrument(Vanilla_Call_short, -1)
    print(bull_spread_ptf)

    # portfolio plotter instance
    bull_spread_ptf_plotter = PortfolioPlotter(bull_spread_ptf)

    # select dependency to plot as x-axis of the plot 
    # (strike 'K' is skipped because a bull-spread is a multi-strike portfolio)
    for dependency_type in ["S", "sigma", "r"]:

        # keyboard parameter and corresponding range to test
        x_axis_dict = options_x_axis_parameters_factory(bull_spread_ptf, dependency_type)

        # appropriate azimut angle for best viewing
        azimut_angle = get_azimut_angle(dependency_type)

        # select metrics to plot
        for plot_metrics in ["price", "PnL", "delta", "theta", "gamma", "vega", "rho"]:

            plot_details_flag = True if plot_metrics == "price" else False

            # Bull-Spread price plot
            bull_spread_ptf_plotter.plot(**x_axis_dict, t='01-06-2020', plot_metrics=plot_metrics,
                                         plot_details=plot_details_flag)

            for time_kind in ['date', 'tau']:
                # set time-parameter to plot
                multiple_valuation_dates = get_time_parameter(bull_spread_ptf, kind=time_kind)
                print(multiple_valuation_dates)

                # Plot at multiple dates
                bull_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates,
                                             plot_metrics=plot_metrics)

                # Surface plot
                bull_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates,
                                             plot_metrics=plot_metrics, surf_plot=True)

                # Surface plot (rotate) - x-axis side
                bull_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates,
                                             plot_metrics=plot_metrics, surf_plot=True,
                                             view=(0, azimut_angle["x-axis side"]))

                # Price surface plot (rotate) - Date side
                bull_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates,
                                             plot_metrics=plot_metrics, surf_plot=True,
                                             view=(0, azimut_angle["Date side"]))
def main():
    # Calendar-Spread implementation example

    # default market environment
    market_env = MarketEnvironment()
    print(market_env)

    # options expirations
    T_short = "31-05-2020"
    T_long = "30-08-2020"

    # current underlying level
    S_t = market_env.get_S()

    # calendar-spread portfolio initialized (as empty portfolio)
    calendar_spread_ptf = Portfolio(name="Calendar Spread Strategy")
    print(calendar_spread_ptf)

    # T_long-call
    Vanilla_Call_long = PlainVanillaOption(market_env, T=T_long, K=S_t)
    print(Vanilla_Call_long)

    # T_short-call
    Vanilla_Call_short = PlainVanillaOption(market_env, T=T_short, K=S_t)
    print(Vanilla_Call_short)

    # creation of Calendar-Spread portfolio strategy
    calendar_spread_ptf.add_instrument(Vanilla_Call_long, 1)
    calendar_spread_ptf.add_instrument(Vanilla_Call_short, -1)
    print(calendar_spread_ptf)

    # portfolio plotter instance
    calendar_spread_ptf_plotter = PortfolioPlotter(calendar_spread_ptf)

    # valuation date of the portfolio
    valuation_date = calendar_spread_ptf.get_t()
    print(valuation_date)

    # select metrics to plot
    for plot_metrics in [
            "price", "PnL", "delta", "theta", "gamma", "vega", "rho"
    ]:
        plot_details_flag = True if plot_metrics == "price" else False

        # time-parameter as a date-range of 5 valuation dates between t and T_short
        # being the Calendar-Spread a multi-horizon portfolio, time-to-maturity
        # time parameters are not allowed.
        last_date = T_short if plot_metrics in ["price", "PnL"] else date_string_to_datetime_obj(T_short) - \
                                                                     pd.Timedelta(days=1)
        multiple_valuation_dates = pd.date_range(start=valuation_date,
                                                 end=last_date,
                                                 periods=5)
        print(multiple_valuation_dates)

        # Bull-Spread price plot
        calendar_spread_ptf_plotter.plot(t=last_date,
                                         plot_metrics=plot_metrics,
                                         plot_details=plot_details_flag)

        # Plot at multiple dates
        calendar_spread_ptf_plotter.plot(t=multiple_valuation_dates,
                                         plot_metrics=plot_metrics)

        # Surface plot
        calendar_spread_ptf_plotter.plot(t=multiple_valuation_dates,
                                         plot_metrics=plot_metrics,
                                         surf_plot=True)

        # Surface plot (rotate) - Underlying value side
        calendar_spread_ptf_plotter.plot(t=multiple_valuation_dates,
                                         plot_metrics=plot_metrics,
                                         surf_plot=True,
                                         view=(0, 180))

        # Price surface plot (rotate) - Date side
        calendar_spread_ptf_plotter.plot(t=multiple_valuation_dates,
                                         plot_metrics=plot_metrics,
                                         surf_plot=True,
                                         view=(0, -90))
def main():
    #
    # portfolio instantiation example
    #

    # if np_output is True, the output will be np.ndarray, otherwise pd.DataFrame
    np_output = False  # True

    # default market environment
    market_env = MarketEnvironment(t="01-06-2020")
    print(market_env)

    # underlying values to test
    S_vector = [60, 90, 120]
    print("S_vector: {}\n".format(S_vector))

    # options maturities
    T_call = "31-12-2020"
    T_put = "30-06-2021"

    # options strikes are the same: single-strike portfolio can be evaluated
    # at different strike-price too
    K = 90
    K_put = K
    K_call = K

    # portfolio options positions
    call_pos = 2
    put_pos = -5

    #
    # Step 0: empty portfolio initialized
    #

    ptf = Portfolio()
    print(ptf)

    #
    # Step 1: adding 2 long plain-vanilla call contracts
    #

    # plain-vanilla call option
    opt1_style = "plain_vanilla"  # "digital"
    opt1_type = "call"  # "put"
    call = option_factory(market_env,
                          opt1_style,
                          opt1_type,
                          K=K_call,
                          T=T_call)
    print(call)

    # adding contract to portfolio
    ptf.add_instrument(call, call_pos)
    print(ptf)

    #
    # Step 2: adding 5 short plain-vanilla put contracts
    #

    # plain-vanilla put option
    opt2_style = "plain_vanilla"  # "digital"
    opt2_type = "put"  # "call"
    put = option_factory(market_env, opt2_style, opt2_type, K=K_put, T=T_put)
    print(put)

    # plain-vanilla put option
    put = PlainVanillaOption(market_env, option_type="put", K=K_put, T=T_put)
    print(put)

    # adding contract to portfolio
    ptf.add_instrument(put, put_pos)
    print(ptf)

    #
    # Step 3: portfolio evaluation
    #

    for case in [
            'All_scalar', 'S', 'S.sigma_distributed', 'S.r_distributed',
            'S.sigma_and_r_distributed', 'K', 'K.sigma_distributed',
            'K.r_distributed', 'K.sigma_and_r_distributed', 't',
            't.sigma_distributed', 't.r_distributed',
            't.sigma_and_r_distributed', 'S.t',
            'S.t.sigma_distributed_as_Sxt_grid',
            'S.t.r_distributed_as_Sxt_grid',
            'S.t.sigma_and_r_distributed_as_Sxt_grid', 'K.t',
            'K.t.sigma_distributed_as_Kxt_grid',
            'K.t.r_distributed_as_Kxt_grid',
            'K.t.sigma_and_r_distributed_as_Kxt_grid', 't.sigma_axis',
            't.r_axis'
    ]:

        # get parameters dictionary for case considered
        param_dict, case_info = get_param_dict_single_K_ptf(
            ptf,
            np_output,
            case,
            T=min(T_call, T_put, key=date_string_to_datetime_obj))

        print("\n--------------------------------------------\n")
        print("\n" + case_info + "\n")

        print("Parameters:")
        print("S: {}".format(param_dict["S"]))
        print("K: {}".format(param_dict["K"]))
        print("t: {}".format(param_dict["t"]))
        print("sigma: {}".format(param_dict["sigma"]))
        print("r: {}\n".format(param_dict["r"]))

        print("Metrics:")

        # metrics to compare
        for metrics in [
                "price", "PnL", "delta", "theta", "gamma", "vega", "rho"
        ]:
            # portfolio metrics
            ptf_metrics = getattr(ptf, metrics)(**param_dict)
            print("\nPortfolio {}:\n{}".format(metrics, ptf_metrics))

            # verification with benchmark metrics
            call_metrics = getattr(call, metrics)(**param_dict)
            put_metrics = getattr(put, metrics)(**param_dict)
            benchmark_metrics = call_pos * call_metrics + put_pos * put_metrics
            print("\nBenchmark {}:\n{}".format(metrics, benchmark_metrics))

            # check effective match
            diff = (ptf_metrics - benchmark_metrics).astype('float')
            num_nonzero_diff = np.count_nonzero(diff) - np.isnan(
                diff).sum().sum()
            exact_match = True if num_nonzero_diff == 0 else False
            print("\nIs replication exact (NaN excluded)? {}\n".format(
                exact_match))