def testBlackScholes(): valuation_date = Date(8, 5, 2015) expiry_date = Date(15, 1, 2016) strike_price = 130.0 stock_price = 127.62 volatility = 0.20 interest_rate = 0.001 dividend_yield = 0.0163 option_type = OptionTypes.AMERICAN_CALL euOptionType = OptionTypes.EUROPEAN_CALL amOption = EquityAmericanOption(expiry_date, strike_price, option_type) ameuOption = EquityAmericanOption(expiry_date, strike_price, euOptionType) euOption = EquityVanillaOption(expiry_date, strike_price, euOptionType) discount_curve = DiscountCurveFlat(valuation_date, interest_rate, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) num_steps_per_year = 400 modelTree = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps_per_year) v = amOption.value(valuation_date, stock_price, discount_curve, dividend_curve, modelTree) # print(v) modelApprox = BlackScholes(volatility, BlackScholesTypes.BARONE_ADESI) v = amOption.value(valuation_date, stock_price, discount_curve, dividend_curve, modelApprox) # print(v) v = ameuOption.value(valuation_date, stock_price, discount_curve, dividend_curve, modelTree) # print(v) v = euOption.value(valuation_date, stock_price, discount_curve, dividend_curve, modelTree) # print(v) amTreeValue = [] amBAWValue = [] euTreeValue = [] euAnalValue = [] volatility = 0.20
def test_heston(): rho = -0.90000 sigma = 0.75000 strike_price = 105.00 hestonModel = Heston(v0, kappa, theta, sigma, rho) call_option = EquityVanillaOption(expiry_date, strike_price, OptionTypes.EUROPEAN_CALL) value_mc_Heston = hestonModel.value_mc(valuation_date, call_option, stock_price, interest_rate, dividend_yield, num_paths, num_steps, seed) valueGatheral = hestonModel.value_gatheral(valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueLewisRouah = hestonModel.value_lewis_rouah(valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueLewis = hestonModel.value_lewis(valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueWeber = hestonModel.value_weber(valuation_date, call_option, stock_price, interest_rate, dividend_yield) assert round(value_mc_Heston, 4) == 1.7333 assert round(valueGatheral, 4) == 1.8416 assert round(valueLewisRouah, 4) == 1.8416 assert round(valueLewis, 4) == 1.8416 assert round(valueWeber, 4) == 1.8416
def testAnalyticalModels(): # Reference see table 4.1 of Rouah book valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 4, 2015) v0 = 0.05 # initial variance of volatility theta = 0.05 # long term variance kappa = 2.0 # speed of variance reversion sigma = 0.10 # volatility of variance rho = -0.9 # correlation interest_rate = 0.05 dividend_yield = 0.01 seed = 2838 num_steps = 100 num_paths = 20000 stock_price = 100.0 testCases.header("TIME", "RHO", "SIGMA", "K", "MC", "GATH", "LEWROU", "LEWIS", "WEBER", "MCERR") for sigma in [0.5, 0.75, 1.0]: for rho in [-0.9, -0.5, 0.0]: hestonModel = Heston(v0, kappa, theta, sigma, rho) for strike_price in np.linspace(95, 105, 3): call_option = EquityVanillaOption(expiry_date, strike_price, OptionTypes.EUROPEAN_CALL) value_mc_Heston = hestonModel.value_mc( valuation_date, call_option, stock_price, interest_rate, dividend_yield, num_paths, num_steps, seed) start = time.time() valueGatheral = hestonModel.value_gatheral( valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueLewisRouah = hestonModel.value_lewis_rouah( valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueLewis = hestonModel.value_lewis(valuation_date, call_option, stock_price, interest_rate, dividend_yield) valueWeber = hestonModel.value_weber(valuation_date, call_option, stock_price, interest_rate, dividend_yield) err = (value_mc_Heston - valueWeber) end = time.time() elapsed = end - start testCases.print( "%6.3f" % elapsed, "% 7.5f" % rho, "%7.5f" % sigma, "%7.2f" % strike_price, "%12.9f" % value_mc_Heston, "%12.9f" % valueGatheral, # problem "%12.9f" % valueLewisRouah, "%12.9f" % valueLewis, "%12.9f" % valueWeber, "%12.9f" % err)
def testMonteCarlo(): import time # Reference see table 4.1 of Rouah book valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 1, 2016) v0 = 0.04 # initial variance of volatility theta = 0.04 # long term variance kappa = 2.0 # speed of variance reversion sigma = 1.0 # volatility of variance rho = -0.9 # correlation interest_rate = 0.05 dividend_yield = 0.01 seed = 238 stock_price = 100.0 testCases.header("TIME", "RHO", "SIGMA", "K", "NSTEPS", "NPATHS", "FORMULA", "EULER_ERR", "EULLOG_ERR", "QE_ERR") for strike_price in np.linspace(95, 105, 3): for num_steps in [25, 50]: for num_paths in [10000, 20000]: hestonModel = Heston(v0, kappa, theta, sigma, rho) call_option = EquityVanillaOption(expiry_date, strike_price, OptionTypes.EUROPEAN_CALL) valueWeber = hestonModel.value_weber(valuation_date, call_option, stock_price, interest_rate, dividend_yield) start = time.time() value_mc_EULER = hestonModel.value_mc( valuation_date, call_option, stock_price, interest_rate, dividend_yield, num_paths, num_steps, seed, HestonNumericalScheme.EULER) value_mc_EULERLOG = hestonModel.value_mc( valuation_date, call_option, stock_price, interest_rate, dividend_yield, num_paths, num_steps, seed, HestonNumericalScheme.EULERLOG) value_mc_QUADEXP = hestonModel.value_mc( valuation_date, call_option, stock_price, interest_rate, dividend_yield, num_paths, num_steps, seed, HestonNumericalScheme.QUADEXP) err_EULER = (value_mc_EULER - valueWeber) err_EULERLOG = (value_mc_EULERLOG - valueWeber) err_QUADEXP = (value_mc_QUADEXP - valueWeber) end = time.time() elapsed = end - start testCases.print(elapsed, rho, sigma, strike_price, num_steps, num_paths, valueWeber, err_EULER, err_EULERLOG, err_QUADEXP)
def test_FinBinomialTree(): stock_price = 50.0 risk_free_rate = 0.06 dividend_yield = 0.04 volatility = 0.40 valuation_date = Date(1, 1, 2016) expiry_date = Date(1, 1, 2017) model = BlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, risk_free_rate) dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield) num_steps_list = [100, 500, 1000, 2000, 5000] strike_price = 50.0 testCases.banner("================== EUROPEAN PUT =======================") put_option = EquityVanillaOption(expiry_date, strike_price, OptionTypes.EUROPEAN_PUT) value = put_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) delta = put_option.delta(valuation_date, stock_price, discount_curve, dividend_curve, model) gamma = put_option.gamma(valuation_date, stock_price, discount_curve, dividend_curve, model) theta = put_option.theta(valuation_date, stock_price, discount_curve, dividend_curve, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = EquityTreePayoffTypes.VANILLA_OPTION exercise = EquityTreeExerciseTypes.EUROPEAN params = np.array([-1, strike_price]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_steps_list: start = time.time() tree = EquityBinomialTree() results = tree.value(stock_price, discount_curve, dividend_curve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner("================== AMERICAN PUT =======================") payoff = EquityTreePayoffTypes.VANILLA_OPTION exercise = EquityTreeExerciseTypes.AMERICAN params = np.array([-1, strike_price]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_steps_list: start = time.time() tree = EquityBinomialTree() results = tree.value(stock_price, discount_curve, dividend_curve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner( "================== EUROPEAN CALL =======================") call_option = EquityVanillaOption(expiry_date, strike_price, OptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) delta = call_option.delta(valuation_date, stock_price, discount_curve, dividend_curve, model) gamma = call_option.gamma(valuation_date, stock_price, discount_curve, dividend_curve, model) theta = call_option.theta(valuation_date, stock_price, discount_curve, dividend_curve, model) testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta") testCases.print(value, delta, gamma, theta) payoff = EquityTreePayoffTypes.VANILLA_OPTION exercise = EquityTreeExerciseTypes.EUROPEAN params = np.array([1.0, strike_price]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_steps_list: start = time.time() tree = EquityBinomialTree() results = tree.value(stock_price, discount_curve, dividend_curve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration) testCases.banner( "================== AMERICAN CALL =======================") payoff = EquityTreePayoffTypes.VANILLA_OPTION exercise = EquityTreeExerciseTypes.AMERICAN params = np.array([1.0, strike_price]) testCases.header("NumSteps", "Results", "TIME") for num_steps in num_steps_list: start = time.time() tree = EquityBinomialTree() results = tree.value(stock_price, discount_curve, dividend_curve, volatility, num_steps, valuation_date, payoff, expiry_date, payoff, exercise, params) end = time.time() duration = end - start testCases.print(num_steps, results, duration)
def test_EquityVanillaOption(): valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 7, 2015) stock_price = 100 volatility = 0.30 interest_rate = 0.05 dividend_yield = 0.01 model = BlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interest_rate) dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield) num_paths_list = [10000, 20000, 40000, 80000, 160000, 320000] testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") for num_paths in num_paths_list: call_option = EquityVanillaOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) start = time.time() value_mc = call_option.value_mc(valuation_date, stock_price, discount_curve, dividend_curve, model, num_paths) end = time.time() duration = end - start testCases.print(num_paths, value, value_mc, duration) ############################################################################### stock_prices = range(80, 120, 10) num_paths = 100000 testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC", "CALL_VALUE_MC_SOBOL", "TIME") useSobol = True for stock_price in stock_prices: call_option = EquityVanillaOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) start = time.time() useSobol = False value_mc1 = call_option.value_mc(valuation_date, stock_price, discount_curve, dividend_curve, model, num_paths, useSobol) useSobol = True value_mc2 = call_option.value_mc(valuation_date, stock_price, discount_curve, dividend_curve, model, num_paths, useSobol) end = time.time() duration = end - start testCases.print(num_paths, value, value_mc1, value_mc2, duration) ############################################################################### stock_prices = range(80, 120, 10) num_paths = 100000 testCases.header("NUMPATHS", "PUT_VALUE_BS", "PUT_VALUE_MC", "PUT_VALUE_MC_SOBOL", "TIME") for stock_price in stock_prices: put_option = EquityVanillaOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_PUT) value = put_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) start = time.time() useSobol = False value_mc1 = put_option.value_mc(valuation_date, stock_price, discount_curve, dividend_curve, model, num_paths, useSobol) useSobol = True value_mc2 = put_option.value_mc(valuation_date, stock_price, discount_curve, dividend_curve, model, num_paths, useSobol) end = time.time() duration = end - start testCases.print(num_paths, value, value_mc1, value_mc2, duration) ############################################################################### stock_prices = range(80, 120, 10) testCases.header("STOCK PRICE", "CALL_VALUE_BS", "CALL_DELTA_BS", "CALL_VEGA_BS", "CALL_THETA_BS", "CALL_RHO_BS", "CALL_VANNA_BS") for stock_price in stock_prices: call_option = EquityVanillaOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) delta = call_option.delta(valuation_date, stock_price, discount_curve, dividend_curve, model) vega = call_option.vega(valuation_date, stock_price, discount_curve, dividend_curve, model) theta = call_option.theta(valuation_date, stock_price, discount_curve, dividend_curve, model) rho = call_option.rho(valuation_date, stock_price, discount_curve, dividend_curve, model) vanna = call_option.vanna(valuation_date, stock_price, discount_curve, dividend_curve, model) testCases.print(stock_price, value, delta, vega, theta, rho, vanna) ########################################################################### testCases.header("STOCK PRICE", "PUT_VALUE_BS", "PUT_DELTA_BS", "PUT_VEGA_BS", "PUT_THETA_BS", "PUT_RHO_BS", "PUT_VANNA_BS") for stock_price in stock_prices: put_option = EquityVanillaOption(expiry_date, 100.0, FinOptionTypes.EUROPEAN_PUT) value = put_option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) delta = put_option.delta(valuation_date, stock_price, discount_curve, dividend_curve, model) vega = put_option.vega(valuation_date, stock_price, discount_curve, dividend_curve, model) theta = put_option.theta(valuation_date, stock_price, discount_curve, dividend_curve, model) rho = put_option.rho(valuation_date, stock_price, discount_curve, dividend_curve, model) vanna = put_option.vanna(valuation_date, stock_price, discount_curve, dividend_curve, model) testCases.print(stock_price, value, delta, vega, theta, rho, vanna)
def testImpliedVolatility_NEW(): valuation_date = Date(1, 1, 2015) stock_price = 100.0 interest_rate = 0.05 dividend_yield = 0.03 discount_curve = DiscountCurveFlat(valuation_date, interest_rate) dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield) strikes = np.linspace(50, 150, 11) timesToExpiry = [0.003, 0.01, 0.1, 0.5, 1.0, 2.0, 5.0] sigmas = np.arange(1, 100, 5) / 100.0 option_types = [FinOptionTypes.EUROPEAN_CALL, FinOptionTypes.EUROPEAN_PUT] testCases.header("OPT_TYPE", "TEXP", "STOCK_PRICE", "STRIKE", "INTRINSIC", "VALUE", "INPUT_VOL", "IMPLIED_VOL") tol = 1e-5 numTests = 0 numFails = 0 for vol in sigmas: model = BlackScholes(vol) for time_to_expiry in timesToExpiry: expiry_date = valuation_date.add_years(time_to_expiry) for strike in strikes: for option_type in option_types: option = EquityVanillaOption(expiry_date, strike, option_type) value = option.value(valuation_date, stock_price, discount_curve, dividend_curve, model) intrinsic = option.intrinsic(valuation_date, stock_price, discount_curve, dividend_curve) # I remove the cases where the time value is zero # This is arbitrary but 1e-10 seems good enough to me impliedVol = -999 if value - intrinsic > 1e-10: impliedVol = option.implied_volatility( valuation_date, stock_price, discount_curve, dividend_curve, value) numTests += 1 errVol = np.abs(impliedVol - vol) if errVol > tol: testCases.print(option_type, time_to_expiry, stock_price, strike, intrinsic, value, vol, impliedVol) # These fails include ones due to the zero time value numFails += 1 testCases.print(option_type, time_to_expiry, stock_price, strike, stock_price, value, vol, impliedVol) assert numFails == 694, "Num Fails has changed."
# print("Num Tests", numTests, "numFails", numFails) ############################################################################### if 1 == 0: valuation_date = Date(30, 11, 2021) expiry_date = valuation_date.add_years(1) stock_price = 100 volatility = 0.20 model = BlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, 0.05) dividend_curve = DiscountCurveFlat(valuation_date, 0.0) call_option = EquityVanillaOption(expiry_date, 100.0, OptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, 105.0, discount_curve, dividend_curve, model) else: test_EquityVanillaOption() start = time.time() testImpliedVolatility_NEW() end = time.time() elapsed = end - start # print("Elapsed:", elapsed) testCases.compareTestCases()
def test_FinNumbaNumbaParallel(useSobol): valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 7, 2015) stock_price = 100 volatility = 0.30 interest_rate = 0.05 dividend_yield = 0.01 seed = 2021 model = BlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interest_rate) useSobolInt = int(useSobol) testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") call_option = EquityVanillaOption(expiry_date, 100.0, OptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_yield, model) num_points = 20 v_exact = [value] * num_points num_paths_list = np.arange(1, num_points+1, 1) * 1000000 NUMBA_ONLY_v = [] NUMBA_ONLY_t = [] print("NUMBA ONLY") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numba_only(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMBA_ONLY_v.append(value_mc) NUMBA_ONLY_t.append(duration) NUMBA_PARALLEL_v = [] NUMBA_PARALLEL_t = [] print("NUMBA PARALLEL") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numba_parallel(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMBA_PARALLEL_v.append(value_mc) NUMBA_PARALLEL_t.append(duration) ########################################################################### import matplotlib.pyplot as plt if useSobol: title = "SOBOL: NUMBA VS NUMBA + PARALLEL" else: title = "PSEUDORANDOM: NUMBA VS NUMBA + PARALLEL" plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, NUMBA_ONLY_t, 'o-', label="NUMBA ONLY") plt.plot(num_paths_list, NUMBA_PARALLEL_t, 'o-', label="NUMBA PARALLEL") plt.xlabel("Number of Paths") plt.ylabel("Wall Time (s)") plt.legend() plt.title(title) plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, v_exact, label="EXACT") plt.plot(num_paths_list, NUMBA_ONLY_v, 'o-', label="NUMBA ONLY") plt.plot(num_paths_list, NUMBA_PARALLEL_v, 'o-', label="NUMBA PARALLEL") plt.xlabel("Number of Paths") plt.ylabel("Option Value") plt.legend() plt.title(title)
def test_FinNumbaNumpySpeed(useSobol): valuation_date = Date(1, 1, 2015) expiry_date = Date(1, 7, 2015) stock_price = 100 volatility = 0.30 interest_rate = 0.05 dividend_yield = 0.01 seed = 1999 model = BlackScholes(volatility) discount_curve = DiscountCurveFlat(valuation_date, interest_rate) useSobolInt = int(useSobol) testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC", "TIME") call_option = EquityVanillaOption(expiry_date, 100.0, OptionTypes.EUROPEAN_CALL) value = call_option.value(valuation_date, stock_price, discount_curve, dividend_yield, model) num_points = 20 v_exact = [value] * num_points ########################################################################### # DO UP TO 100K AS IT IS SLOW ########################################################################### num_paths_list = np.arange(1, num_points+1, 1) * 100000 NONUMBA_NONUMPY_v = [] NONUMBA_NONUMPY_t = [] print("PURE PYTHON") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_nonumba_nonumpy(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NONUMBA_NONUMPY_v.append(value_mc) NONUMBA_NONUMPY_t.append(duration+1e-10) NUMPY_ONLY_v = [] NUMPY_ONLY_t = [] print("NUMPY ONLY") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numpy_only(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMPY_ONLY_v.append(value_mc) NUMPY_ONLY_t.append(duration+1e-10) # speedUp = np.array(NONUMBA_NONUMPY_t)/np.array(NUMPY_ONLY_t) # print(NUMPY_ONLY_t) # print(NONUMBA_NONUMPY_t) # print(speedUp) if useSobol: title = "SOBOL: PURE PYTHON VS NUMPY" else: title = "PSEUDORANDOM: PURE PYTHON VS NUMPY" plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, NONUMBA_NONUMPY_t, 'o-', label="PURE PYTHON") plt.plot(num_paths_list, NUMPY_ONLY_t, 'o-', label="NUMPY ONLY") plt.xlabel("Number of Paths") plt.ylabel("Wall Time (s)") plt.legend() plt.title(title) plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, v_exact, label="EXACT") plt.plot(num_paths_list, NONUMBA_NONUMPY_v, 'o-', label="PURE PYTHON") plt.plot(num_paths_list, NUMPY_ONLY_v, 'o-', label="NUMPY ONLY") plt.xlabel("Number of Paths") plt.ylabel("Option Value") plt.legend() plt.title(title) ########################################################################### # DO UP TO 10 MILLION NOW THAT WE HAVE NUMPY ########################################################################### num_paths_list = np.arange(1, num_points+1, 1) * 1000000 NUMPY_ONLY_v = [] NUMPY_ONLY_t = [] print("NUMPY ONLY") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numpy_only(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMPY_ONLY_v.append(value_mc) NUMPY_ONLY_t.append(duration) NUMBA_NUMPY_v = [] NUMBA_NUMPY_t = [] print("NUMBA+NUMPY") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numpy_numba(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMBA_NUMPY_v.append(value_mc) NUMBA_NUMPY_t.append(duration) NUMBA_ONLY_v = [] NUMBA_ONLY_t = [] print("NUMBA ONLY") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numba_only(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMBA_ONLY_v.append(value_mc) NUMBA_ONLY_t.append(duration) NUMBA_PARALLEL_v = [] NUMBA_PARALLEL_t = [] print("NUMBA PARALLEL") for num_paths in num_paths_list: start = time.time() value_mc = call_option.value_mc_numba_parallel(valuation_date, stock_price, discount_curve, dividend_yield, model, num_paths, seed, useSobolInt) end = time.time() duration = end - start print("%10d %9.5f %9.5f %9.6f" % (num_paths, value, value_mc, duration)) NUMBA_PARALLEL_v.append(value_mc) NUMBA_PARALLEL_t.append(duration) # speedUp = np.array(NUMBA_ONLY_t)/np.array(NUMBA_PARALLEL_t) # print("PARALLEL:", speedUp) ########################################################################### # COMPUTED USING NUMSTEPS FROM 1M to 10M ########################################################################### CPP_t = np.array([0.075, 0.155, 0.223, 0.313, 0.359, 0.421, 0.495, 0.556, 0.64, 0.702, 0.765, 0.841, 0.923, 0.982, 1.05, 1.125, 1.195, 1.261, 1.333, 1.408]) CPP_v = np.array([9.30872, 9.29576, 9.29422, 9.29832, 9.29863, 9.30153, 9.2994, 9.3025, 9.29653, 9.29875, 9.29897, 9.29996, 9.29931, 9.29796, 9.29784, 9.2992, 9.3001, 9.30093, 9.29876, 9.29921]) if useSobol: title = "SOBOL: COMPARING OPTIMISATIONS" else: title = "PSEUDORANDOM: COMPARING OPTIMISATIONS" plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, NUMPY_ONLY_t, 'o-', label="NUMPY ONLY") plt.plot(num_paths_list, NUMBA_NUMPY_t, 'o-', label="NUMBA + NUMPY") plt.xlabel("Number of Paths") plt.ylabel("Wall Time (s)") plt.legend() plt.title(title) ########################################################################### if useSobol: title = "SOBOL: COMPARING OPTIMISATIONS" else: title = "PSEUDORANDOM: COMPARING OPTIMISATIONS" plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, NUMPY_ONLY_t, 'o-', label="NUMPY ONLY") plt.plot(num_paths_list, NUMBA_NUMPY_t, 'o-', label="NUMBA + NUMPY") plt.plot(num_paths_list, NUMBA_ONLY_t, 'o-', label="NUMBA ONLY") plt.plot(num_paths_list, NUMBA_PARALLEL_t, 'o-', label="NUMBA PARALLEL") if useSobol == False: plt.plot(num_paths_list, CPP_t, 'o-', label="C++") plt.xlabel("Number of Paths") plt.ylabel("Wall Time (s)") plt.legend() plt.title(title) ########################################################################### plt.figure(figsize=(8, 6)) plt.plot(num_paths_list, v_exact, label="EXACT") plt.plot(num_paths_list, NUMBA_ONLY_v, 'o-', label="NUMBA ONLY") plt.plot(num_paths_list, CPP_v, 'o-', label="C++") plt.xlabel("Number of Paths") plt.ylabel("Option Value") plt.legend() plt.title(title)
expiry_date = Date(15, 1, 2016) strike_price = 130.0 stock_price = 127.62 volatility = 0.20 interest_rate = 0.001 dividend_yield = 0.0163 option_type = OptionTypes.AMERICAN_CALL euOptionType = OptionTypes.EUROPEAN_CALL amOption = EquityAmericanOption(expiry_date, strike_price, option_type) ameuOption = EquityAmericanOption(expiry_date, strike_price, euOptionType) euOption = EquityVanillaOption(expiry_date, strike_price, euOptionType) discount_curve = DiscountCurveFlat(valuation_date, interest_rate, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield, FrequencyTypes.CONTINUOUS, DayCountTypes.ACT_365F) num_steps_per_year = 400 modelTree = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps_per_year)
############################################################################### # Copyright (C) 2018, 2019, 2020 Dominic O'Kane ############################################################################### from financepy.utils.global_types import FinOptionTypes from financepy.products.equity.equity_vanilla_option import EquityVanillaOption from financepy.market.curves.discount_curve_flat import DiscountCurveFlat from financepy.models.black_scholes import BlackScholes from financepy.utils.date import Date expiryDate = Date(1, 7, 2015) call_option = EquityVanillaOption( expiryDate, 100.0, FinOptionTypes.EUROPEAN_CALL) put_option = EquityVanillaOption( expiryDate, 100.0, FinOptionTypes.EUROPEAN_PUT) valueDate = Date(1, 1, 2015) stockPrice = 100 volatility = 0.30 interest_rate = 0.05 dividend_yield = 0.01 model = BlackScholes(volatility) discountCurve = DiscountCurveFlat(valueDate, interest_rate) dividendCurve = DiscountCurveFlat(valueDate, dividend_yield) def test_call_option(): v = call_option.value(valueDate, stockPrice, discountCurve, dividendCurve, model) assert v.round(4) == 9.3021