コード例 #1
0
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
コード例 #2
0
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
コード例 #3
0
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)
コード例 #4
0
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)
コード例 #5
0
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)
コード例 #6
0
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)
コード例 #7
0
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."
コード例 #8
0
#    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()
コード例 #9
0
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)
コード例 #10
0
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)
コード例 #11
0
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)

コード例 #12
0
###############################################################################
# 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