def option_factory(mkt_env, plain_or_digital, option_type, **kwargs): option_dispatcher = { "plain_vanilla": {"call": PlainVanillaOption(mkt_env, **kwargs), "put": PlainVanillaOption(mkt_env, option_type="put", **kwargs) }, "digital": {"call": DigitalOption(mkt_env, **kwargs), "put": DigitalOption(mkt_env, option_type="put", **kwargs) } } return option_dispatcher[plain_or_digital][option_type]
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(): # # 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 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))
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))
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 dependency to plot as x-axis of the plot for dependency_type in ["S", "K", "sigma", "r"]: # keyboard parameter and corresponding range to test x_axis_dict = options_x_axis_parameters_factory(calendar_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 # time-parameter as a date-range of 5 valuation dates between t and T_short 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(**x_axis_dict, t=last_date, plot_metrics=plot_metrics, plot_details=plot_details_flag) # Plot at multiple dates calendar_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates, plot_metrics=plot_metrics) # Surface plot calendar_spread_ptf_plotter.plot(**x_axis_dict, t=multiple_valuation_dates, plot_metrics=plot_metrics, surf_plot=True) # Surface plot (rotate) - Underlying value side calendar_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 calendar_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" # 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))