def main(): # if np_output is True, the output will be np.ndarray, otherwise pd.DataFrame np_output = False # True # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) 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(option, np_output, case) 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:") print("Payoff:\n", option.payoff(**param_dict)) print("\nPrice upper limit:\n", option.price_upper_limit(**param_dict)) print("\nPrice lower limit:\n", option.price_lower_limit(**param_dict)) print("\nPrice:\n", option.price(**param_dict)) print("\nP&L:\n", option.PnL(**param_dict)) print("\nDelta:\n", option.delta(**param_dict)) print("\nTheta:\n", option.theta(**param_dict)) print("\nGamma:\n", option.gamma(**param_dict)) print("\nVega:\n", option.vega(**param_dict)) print("\nRho:\n", option.rho(**param_dict)) # Implied volatility calculation is not implemented for x-axis # (columns) spanned by sigma if ('sigma_axis' not in param_dict) or (param_dict['sigma_axis'] == False): print("\nExpected Implied Volatility: \n{}\n".format(param_dict["sigma"])) print("\nImplied Volatility - Newton method:\n{}\n"\ .format(option.implied_volatility(**param_dict))) param_dict["minimization_method"] = "Least-Squares" print("\nImplied Volatility - Least-Squares constrained method:\n{}\n"\ .format(option.implied_volatility(**param_dict)))
def main(): # vanilla call implementation example # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # option plotter instance plotter = OptionPlotter(option) # valuation date of the option emission_date = option.get_t() print(emission_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( option, 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 # Plot at t plotter.plot(**x_axis_dict, t=[emission_date], plot_metrics=plot_metrics, plot_details=plot_details_flag) # Plot at another date-string date 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(option, kind=time_kind) print(multiple_valuation_dates) # Plot at multiple dates plotter.plot(**x_axis_dict, t=multiple_valuation_dates, plot_metrics=plot_metrics)
def main(): # vanilla call implementation example # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # option plotter instance plotter = OptionPlotter(option) # valuation date of the option emission_date = option.get_t() print(emission_date) # select metrics to plot for plot_metrics in ["implied_volatility"]: plot_details_flag = True if plot_metrics == "price" else False # Plot at t plotter.plot(t=[emission_date], plot_metrics=plot_metrics, plot_details=plot_details_flag) # Plot at another date-string date 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(option, kind=time_kind) print(multiple_valuation_dates) # Plot at multiple dates plotter.plot(t=multiple_valuation_dates, plot_metrics=plot_metrics)
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(): # numeric Vs analytic greeks example # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # select greek for greek_type in ["delta", "theta", "gamma", "vega", "rho"]: # numeric greeks instance NumGreeks = NumericGreeks(option) # # greek Vs Underlying level S # # underlying range at which compute greeks S_range = np.linspace(50, 150, 2000) # analytic greek greek_analytic_Vs_S = greeks_factory(option, greek_type)(S=S_range) # numeric greek greek_numeric_Vs_S = greeks_factory(NumGreeks, greek_type)(S=S_range) # labels label_numeric_S = greeks_label_factory(greek_type, opt_type, kind="num") label_analytic_S = greeks_label_factory(greek_type, opt_type, kind="exact") # plot title plot_title_S = greeks_title_factory(option, greek_type) # comparison plot_compare(S_range, f=greek_numeric_Vs_S, f_ref=greek_analytic_Vs_S, f_label=label_numeric_S, f_ref_label=label_analytic_S, x_label="S",f_test_name="Numeric " + greek_type, f_ref_name="Exact " + greek_type, title=plot_title_S) # # greek Vs residual time to maturity tau # # time-to-maturity range at which compute greeks tau_range = np.linspace(1e-4,1.0,1000) tau_range = homogenize(tau_range, reverse_order=True) # analytic greek greek_analytic_Vs_tau = greeks_factory(option, greek_type)(tau=tau_range) # numeric greek greek_numeric_Vs_tau = greeks_factory(NumGreeks, greek_type)(tau=tau_range) # labels label_numeric_tau = greeks_label_factory(greek_type, opt_type, kind="num", underlying=r"\tau") label_analytic_tau = greeks_label_factory(greek_type, opt_type, kind="exact", underlying=r"\tau") # plot title plot_title_tau = greeks_title_factory(option, greek_type, underlying=r"\tau") # comparison plot_compare(tau_range, f=greek_numeric_Vs_tau, f_ref=greek_analytic_Vs_tau, f_label=label_numeric_tau, f_ref_label=label_analytic_tau, x_label=r"\tau", f_test_name="Numeric " + greek_type, f_ref_name="Exact " + greek_type, title=plot_title_tau)
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(): # # Black-Scholes implied volatility calculation with user-defined 'sigma' # parameter surface, used to evaluate the quality of the implied volatility # calculation. # # output format: pd.DataFrame np_output = False # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # K K_vector = [50, 75, 100, 125, 150] # tau: a date-range of 5 valuation dates between t and T-10d n = 6 valuation_date = option.get_t() expiration_date = option.get_T() t_vector = pd.date_range(start=valuation_date, end=expiration_date - pd.Timedelta(days=25), periods=n) # sigma (qualitatively reproducing the smile) k, tau = np.meshgrid(K_vector, option.time_to_maturity(t=t_vector)) sigma_grid_K = 0.01 + ((k - 100)**2) / (100 * k * tau) # pricing parameters param_dict = { "S": 100, "K": K_vector, "t": t_vector, "sigma": sigma_grid_K, "r": 0.01, "np_output": np_output } print("Parameters:") print("S: {}".format(param_dict["S"])) print("K: {}".format(param_dict["K"])) print("t: {}".format(param_dict["t"])) print("sigma: \n{}".format(param_dict["sigma"])) print("r: {}\n".format(param_dict["r"])) # expected implied volatility: is the 'sigma' parameter with which the # target price has been generated expected_IV = pd.DataFrame(data=param_dict["sigma"], columns=K_vector, index=t_vector) print("\nExpected Kxt Implied volatiltiy Surface: \n", expected_IV) # # Without target_price in input: param_dict['sigma'] parameter is # used to construct target price, used in minimization # print("\n--- WITHOUT target_price in input ---\n") # newton method newton_IV = option.implied_volatility(**param_dict) RMSE_newton = np.sqrt(np.nanmean((newton_IV - expected_IV)**2)) RMSRE_newton = np.sqrt( np.nanmean(((newton_IV - expected_IV) / expected_IV)**2)) print("\nImplied Volatility - Newton method - Metrics (NaN excluded): RMSE={:.1E}, RMSRE={:.1E}:\n"\ .format(RMSE_newton, RMSRE_newton), newton_IV) # Least=Squares method param_dict["minimization_method"] = "Least-Squares" ls_IV = option.implied_volatility(**param_dict) RMSE_ls = np.sqrt(np.nanmean((ls_IV - expected_IV)**2)) RMSRE_ls = np.sqrt(np.nanmean(((ls_IV - expected_IV) / expected_IV)**2)) print("\nImplied Volatility - Newton method - Metrics (NaN excluded): RMSE={:.1E}, RMSRE={:.1E}:\n"\ .format(RMSE_ls, RMSRE_ls), ls_IV) # # With target_price in input: target_price, but no param_dict['sigma'], # is used in minimization. # print("\n--- WITH target_price in input ---\n") # compute target price target_price = option.price(**param_dict) print("\nTarget Price in input: \n", target_price) # Add target_price to parameters dictionary: param_dict['target_price'] = target_price # Remove from implied volatility parameters in input the 'sigma' parameter # it's not necessary, but this way for sure the .implied_volatility() method # is agnostic of the expected implied volatility del param_dict['sigma'] # newton method newton_IV = option.implied_volatility(**param_dict) RMSE_newton = np.sqrt(np.nanmean((newton_IV - expected_IV)**2)) RMSRE_newton = np.sqrt( np.nanmean(((newton_IV - expected_IV) / expected_IV)**2)) print("\nImplied Volatility - Newton method - Metrics (NaN excluded): RMSE={:.1E}, RMSRE={:.1E}:\n"\ .format(RMSE_newton, RMSRE_newton), newton_IV) # Least=Squares method param_dict["minimization_method"] = "Least-Squares" ls_IV = option.implied_volatility(**param_dict) RMSE_ls = np.sqrt(np.nanmean((ls_IV - expected_IV)**2)) RMSRE_ls = np.sqrt(np.nanmean(((ls_IV - expected_IV) / expected_IV)**2)) print("\nImplied Volatility - Newton method - Metrics (NaN excluded): RMSE={:.1E}, RMSRE={:.1E}:\n"\ .format(RMSE_ls, RMSRE_ls), ls_IV)
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))
def main(): # vanilla call implementation example # default market environment market_env = MarketEnvironment() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # option plotter instance plotter = OptionPlotter(option) # valuation date of the option emission_date = option.get_t() # 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( option, 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" ]: for time_kind in ['date', 'tau']: # set time-parameter to plot multiple_valuation_dates = get_time_parameter(option, kind=time_kind) print(multiple_valuation_dates) # Surface plot plotter.plot(**x_axis_dict, t=multiple_valuation_dates, plot_metrics=plot_metrics, surf_plot=True) # Surface plot (rotate) - x-axis side 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 plotter.plot(**x_axis_dict, t=multiple_valuation_dates, plot_metrics=plot_metrics, surf_plot=True, view=(0, azimut_angle["Date side"]))
def main(): # # option (underlying, time-parameter) 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() print(market_env) # define option style and type opt_style = "plain_vanilla" # "digital" # "plain_vanilla" opt_type = "call" # "put" option = option_factory(market_env, opt_style, opt_type) print(option) # loop over different cases: for case in ["S_scalar_default.t_scalar_default", \ "S_scalar.t_scalar_dt", \ "S_scalar.t_scalar_str", \ "S_scalar.tau_scalar", \ "S_vector.t_scalar_default", \ "S_scalar_default.t_date_range", \ "S_vector.t_date_range", \ "S_vector.t_str_list", \ "S_vector.tau_list", \ "S_scalar_default.t_scalar_default.sigma_axis", \ "S_scalar_default.t_scalar_default.r_axis"]: # get parameters dictionary for case considered param_dict, case_info = get_param_dict(option, np_output, case) not_sigma_axis = ('sigma_axis' not in param_dict) or (param_dict['sigma_axis'] == False) not_r_axis = ('r_axis' not in param_dict) or (param_dict['r_axis'] == False) print("\n--------------------------------------------\n") print("\n" + case_info + "\n") print("Parameters:") print( "S: {}".format(param_dict["S"] if "S" in param_dict else str(option.get_S()) + " (default)")) print( "K: {}".format(param_dict["K"] if "K" in param_dict else str(option.get_K()) + " (default)")) print("t: {}".format(param_dict["t"] if "t" in param_dict else str(option.get_tau()) + " (default)")) print("sigma: {}".format(param_dict["sigma"] if "sigma" in param_dict else str(option.get_sigma()) + " (default)")) print("r: {}\n".format(param_dict["r"] if "r" in param_dict else str(option.get_r()) + " (default)")) print("Metrics:") print("Payoff:\n", option.payoff(**param_dict)) print("\nPrice upper limit:\n", option.price_upper_limit(**param_dict)) print("\nPrice lower limit:\n", option.price_lower_limit(**param_dict)) print("\nPrice:\n", option.price(**param_dict)) print("\nP&L:\n", option.PnL(**param_dict)) print("\nDelta:\n", option.delta(**param_dict)) print("\nTheta:\n", option.theta(**param_dict)) print("\nGamma:\n", option.gamma(**param_dict)) print("\nVega:\n", option.vega(**param_dict)) print("\nRho:\n", option.rho(**param_dict)) # Implied volatility calculation is not implemented for x-axis (columns) # spanned by parameters different from S or K (like sigma or r) if not_sigma_axis and not_r_axis: print("\nExpected Implied Volatility: \n{}\n"\ .format(option.get_sigma())) print("\nImplied Volatility - Newton method:\n{}\n"\ .format(option.implied_volatility(**param_dict))) param_dict["minimization_method"] = "Least-Squares" print("\nImplied Volatility - Least-Squares constrained method:\n{}\n"\ .format(option.implied_volatility(**param_dict)))