Exemplo n.º 1
0
def main():
    # if np_output is True, the output will be np.ndarray, otherwise pd.DataFrame
    np_output = False  # True
    t = "30-04-2021"
    r = 0.10
    S = 14661
    sigma = 0.2375
    # sigma = 0.23
    K = 14600
    T = "06-05-2021"
    # default market environment
    market_env = MarketEnvironment(t, r, S, sigma)
    # print(market_env)

    # define option style and type
    opt_style = "plain_vanilla"  # "digital" # "plain_vanilla"
    opt_type = "put"  # "put"
    option = option_factory(market_env, opt_style, opt_type, K, T)
    # print(option)
    # CalcualtePricesForRange(S, option)

    # print("Metrics:")
    # print("Payoff:", option.payoff())
    # print("Price upper limit:", option.price_upper_limit())
    # print("Price lower limit:", option.price_lower_limit())
    print("Price:", option.price())
    print("P&L:", option.PnL())
    print("Delta:", option.delta())
    print("Theta:", option.theta())
    print("Gamma:", option.gamma())
    print("Vega:", option.vega())
    print("Rho:", option.rho())
Exemplo n.º 2
0
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():
    # numeric greeks example

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

    # define option style and type
    opt_style = "plain_vanilla"  # "digital"
    opt_type = "call"  # "call"
    option = option_factory(market_env, opt_style, opt_type)
    print(option)

    # numeric greeks instance
    NumGreeks = NumericGreeks(option)

    # underlying range at which compute greeks
    S_range = np.linspace(50, 150, 2000)

    # 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)

    # select greek
    for greek_type in ["delta", "theta", "gamma", "vega", "rho"]:
        #
        # greek Vs Underlying level S
        # 

        # numeric greek calculation
        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")

        # plot title
        plot_title_S = greeks_title_factory(option, greek_type)

        # plot
        plot(x=S_range, f=greek_numeric_Vs_S, x_label=r"$S$",
             f_label=label_numeric_S, title=plot_title_S)

        #
        # greek Vs residual time to maturity tau
        # 

        # numeric greek calculation
        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")

        # plot title
        plot_title_tau = greeks_title_factory(option, greek_type, underlying=r"\tau")

        # plot
        plot(x=tau_range, f=greek_numeric_Vs_tau, x_label=r"$\tau$",
             f_label=label_numeric_tau, title=plot_title_tau)
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'] is 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 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)
Exemplo n.º 7
0
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)

    # 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"]))
Exemplo n.º 8
0
def CreateExpectedSpotLists(OptionType, currSymbol="Sheet1"):
    data = pd.read_excel(OptionsConstants.Location + "\\" +
                         OptionsConstants.TradeDate + "\\" + OptionType + "_" +
                         OptionsConstants.FileSuffix + ".xlsx",
                         sheet_name=currSymbol)
    OutputList = []
    for index, row in data.iterrows():
        t = OptionsConstants.TradeDate
        r = 0.1
        S = row['underlyingValue']
        sigma = float((row['impliedVolatility']) / 100)
        K = row['strikePrice']
        T = (datetime.datetime.strptime(row['expiryDate'],
                                        '%d-%b-%Y')).strftime('%d-%m-%Y')
        # default market environment
        market_env = MarketEnvironment(t, r, S, sigma)
        # define option style and type
        opt_style = "plain_vanilla"  # "digital" # "plain_vanilla"
        opt_type = OptionType
        option = option_factory(market_env, opt_style, opt_type, K, T)
        ProjectedPriceList = CalcualtePricesForRange(S, option)
        OutputList.append({
            'OptionType': OptionType,
            'StrikePrice': row['strikePrice'],
            'Underlying': row['underlyingValue'],
            'LastPrice': row['lastPrice'],
            'ExpiryDate': row['expiryDate'],
            'ProjectedSpot': ProjectedPriceList
        })

    newCalldf = pd.DataFrame(OutputList).dropna()
    filemode = 'w'
    if (os.path.exists(OptionsConstants.Location + "\\" +
                       OptionsConstants.TradeDate + "\\" + OptionType +
                       "Projected_" + OptionsConstants.FileSuffix + ".xlsx")):
        filemode = 'a'
    with pd.ExcelWriter(OptionsConstants.Location + "\\" +
                        OptionsConstants.TradeDate + "\\" + OptionType +
                        "Projected_" + OptionsConstants.FileSuffix + ".xlsx",
                        engine='openpyxl',
                        mode=filemode) as writer:
        newCalldf.to_excel(writer, sheet_name=currSymbol, index=False)
    return (OutputList)
Exemplo n.º 9
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)
Exemplo n.º 10
0
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():
    # output format: pd.DataFrame
    np_output = False

    # choose whether to plot expected IV or reconstructed one (takes longer)
    plot_expected_iv = True  # 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 = np.linspace(50, 150, 100)

    # 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)
    expected_IV.rename_axis('K', axis='columns', inplace=True)
    expected_IV.rename_axis('t', axis='rows', inplace=True)
    print("\nExpected Kxt Implied volatility Surface: \n", expected_IV)

    if plot_expected_iv:

        IV_plot = expected_IV

    else:

        # 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

        # 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 - Least-Squares constrained method - Metrics (NaN excluded): RMSE={:.1E}, "
            "RMSRE={:.1E}:\n".format(RMSE_ls, RMSRE_ls), ls_IV)

        IV_plot = ls_IV

    # option plotter instance
    plotter = OptionPlotter(option)
    plotter.plot(plot_metrics="implied_volatility", IV=IV_plot)
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))
Exemplo n.º 15
0
    def test_ReadURL(self):
        # url = "https://www.nseindia.com/api/option-chain-indices?symbol=NIFTY"
        # # url = "https://www.nseindia.com/get-quotes/derivatives?symbol=NIFTY&identifier=OPTIDXNIFTY"
        # headers = {
        #     'User-agent': 'Mozilla/5.0'
        # }
        # t = requests.get(url,headers=headers)
        # # print(t.text)
        # test = t.json()
        # # path="100%.data.expiryDate"
        # # for expiryDate in test.values():
        # #     try:
        # #         print(expiryDate)
        # #     except KeyError:
        # #         temp="dummy"
        #
        # print(test["records"]["data"])
        with open('C:\\Users\\srepswal\\Desktop\\test.json') as f:
            data = json.load(f)
        df = pd.DataFrame(list(data["records"]["data"][0:]),columns=['PE','CE']).dropna()

        df2 = pd.DataFrame(df['PE'].values.tolist())
        df2 = df2[(df2['openInterest']>2000) & (df2['impliedVolatility']>0 )& (df2['totalTradedVolume']>2000 )]

        df3 = pd.DataFrame(df['CE'].values.tolist())
        df3 = df3[(df3['openInterest'] > 2000) & (df3['impliedVolatility']>0) & (df3['totalTradedVolume']>2000 )]
        # print(data["records"]["data"][0]["PE"]["openInterest"])
        with pd.ExcelWriter("C:\\Users\\srepswal\\PycharmProjects\\EquityModelling\\Main\\DriverObject\\Trading\\Data\\Option\\02Apr2021\\temp.xlsx", engine='xlsxwriter') as writer:
            df2.to_excel(writer, index=False)
        with pd.ExcelWriter(
                "C:\\Users\\srepswal\\PycharmProjects\\EquityModelling\\Main\\DriverObject\\Trading\\Data\\Option\\02Apr2021\\call.xlsx",
                engine='xlsxwriter') as writer:
            df3.to_excel(writer, index=False)

        callList = []
        for index, row in df3.iterrows():
            print(row['strikePrice'], row['lastPrice'],row['impliedVolatility'],row['expiryDate'])
            t = "26-03-2021"
            r = 0.03
            S = row['underlyingValue']
            sigma = row['impliedVolatility']/100
            K = row['strikePrice']
            T =(datetime.datetime.strptime(row['expiryDate'], '%d-%b-%Y')).strftime('%d-%m-%Y')
            # default market environment
            market_env = MarketEnvironment(t, r, S, sigma)
            # 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, K, T)
            ProjectedPriceList =CalcualtePricesForRange(S, option)
            callList.append(
                {'OptionType': 'Call', 'StrikePrice': row['strikePrice'], 'Underlying': row['underlyingValue'],
                 'LastPrice': row['lastPrice'], 'ExpiryDate': row['expiryDate'],
                 'ProjectedSpot': ProjectedPriceList})


        newCalldf=   pd.DataFrame(callList).dropna()
        with pd.ExcelWriter(
                "C:\\Users\\srepswal\\PycharmProjects\\EquityModelling\\Main\\DriverObject\\Trading\\Data\\Option\\02Apr2021\\CallProjected.xlsx",
                engine='xlsxwriter') as writer:
            newCalldf.to_excel(writer, index=False)

        putList = []
        for index, row in df2.iterrows():
            print(row['strikePrice'], row['lastPrice'], row['impliedVolatility'], row['expiryDate'])
            t = "01-04-2021"
            r = 0.03
            S = row['underlyingValue']
            sigma = row['impliedVolatility'] / 100
            K = row['strikePrice']
            T = (datetime.datetime.strptime(row['expiryDate'], '%d-%b-%Y')).strftime('%d-%m-%Y')
            # default market environment
            market_env = MarketEnvironment(t, r, S, sigma)
            # print(market_env)

            # define option style and type
            opt_style = "plain_vanilla"  # "digital" # "plain_vanilla"
            opt_type = "put"  # "put"
            option = option_factory(market_env, opt_style, opt_type, K, T)
            ProjectedPriceList = CalcualtePricesForRange(S, option)
            putList.append(
                {'OptionType': 'Put', 'StrikePrice': row['strikePrice'], 'Underlying': row['underlyingValue'],
                 'LastPrice': row['lastPrice'], 'ExpiryDate': row['expiryDate'],
                 'ProjectedSpot': ProjectedPriceList})


        newPutdf = pd.DataFrame(putList).dropna()
        with pd.ExcelWriter(
                "C:\\Users\\srepswal\\PycharmProjects\\EquityModelling\\Main\\DriverObject\\Trading\\Data\\Option\\02Apr2021\\PutProjected.xlsx",
                engine='xlsxwriter') as writer:
            newPutdf.to_excel(writer, index=False)
        # CalculateMaxLossAndMinProfit(callList,putList)
        CalculateLossAndProfit(callList, putList)
Exemplo n.º 16
0
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" # "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'] is False)
        not_r_axis = ('r_axis'
                      not in param_dict) or (param_dict['r_axis'] is 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)))
Exemplo n.º 17
0
def CreateSpotListsWithGreeks(OptionType, currSymbol="Sheet1"):
    data = pd.read_excel(OptionsConstants.Location + "\\" +
                         OptionsConstants.TradeDate + "\\" + OptionType + "_" +
                         OptionsConstants.FileSuffix + ".xlsx",
                         sheet_name=currSymbol)
    OutputList = []
    # OutputList[OptionType+'_Delta']=0.000000
    # OutputList[OptionType + '_Theta'] = 0.000000
    # OutputList[OptionType + '_Gamma'] = 0.000000
    # OutputList[OptionType + '_Vega'] = 0.000000
    # OutputList[OptionType + '_Rho'] = 0.000000
    for index, row in data.iterrows():
        t = OptionsConstants.TradeDate
        r = 0.1
        S = row['underlyingValue']
        sigma = float((row['impliedVolatility']) / 100)
        K = row['strikePrice']
        T = (datetime.datetime.strptime(row['expiryDate'],
                                        '%d-%b-%Y')).strftime('%d-%m-%Y')
        # default market environment
        market_env = MarketEnvironment(t, r, S, sigma)
        # define option style and type
        opt_style = "plain_vanilla"  # "digital" # "plain_vanilla"
        opt_type = OptionType
        option = option_factory(market_env, opt_style, opt_type, K, T)
        Delta = option.delta()
        Theta = option.theta()
        Gamma = option.gamma()
        Vega = option.vega()
        Rho = option.rho()

        OutputList.append({
            'OptionType':
            OptionType,
            'StrikePrice':
            row['strikePrice'],
            'Underlying':
            row['underlyingValue'],
            'LastPrice':
            row['lastPrice'],
            'ExpiryDate':
            row['expiryDate'],
            OptionType + '_Delta':
            '%.4f' % float(option.delta()[0]),
            OptionType + '_Theta':
            '%.4f' % float(option.theta()[0]),
            OptionType + '_Gamma':
            '%.4f' % float(option.gamma()[0]),
            OptionType + '_Vega':
            '%.4f' % float(option.vega()[0]),
            OptionType + '_Rho':
            '%.4f' % float(option.rho()[0])
        })

    newCalldf = pd.DataFrame(OutputList).dropna()
    filemode = 'w'
    if (os.path.exists(OptionsConstants.Location + "\\" +
                       OptionsConstants.TradeDate + "\\" + OptionType +
                       "Greeks" + OptionsConstants.FileSuffix + ".xlsx")):
        filemode = 'a'
    with pd.ExcelWriter(OptionsConstants.Location + "\\" +
                        OptionsConstants.TradeDate + "\\" + OptionType +
                        "Greeks" + OptionsConstants.FileSuffix + ".xlsx",
                        engine='openpyxl',
                        mode=filemode) as writer:
        newCalldf.to_excel(writer, sheet_name=currSymbol, index=False)
    return (OutputList)
Exemplo n.º 18
0
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)
    expected_IV.rename_axis('K', axis='columns', inplace=True)
    expected_IV.rename_axis('t', axis='rows', inplace=True)
    print("\nExpected Kxt Implied volatility 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
    param_dict["minimization_method"] = "Newton"
    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 - Least-Squares constrained 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

    # newton method
    param_dict["minimization_method"] = "Newton"
    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 - Least-Squares constrained method - Metrics (NaN excluded): RMSE={:.1E}, RMSRE={:.1E}:\n"
        .format(RMSE_ls, RMSRE_ls), ls_IV)