コード例 #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_EquityChooserOptionDerivicom():
    """http://derivicom.com/support/finoptionsxl/index.html?complex_chooser.htm """

    valuation_date = Date(1, 1, 2007)
    chooseDate = Date(1, 2, 2007)
    call_expiry_date = Date(1, 4, 2007)
    put_expiry_date = Date(1, 5, 2007)
    call_strike = 40.0
    put_strike = 35.0
    stock_price = 38.0
    volatility = 0.20
    interest_rate = 0.08
    dividend_yield = 0.0625

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    chooserOption = EquityChooserOption(chooseDate, call_expiry_date,
                                        put_expiry_date, call_strike,
                                        put_strike)

    v = chooserOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    v_mc = chooserOption.value_mc(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model, 20000)

    v_derivicom = 1.0989
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "DERIVICOM", v_derivicom, "MC", v_mc)
コード例 #3
0
def test_EquityChooserOptionMatlab():
    """https://fr.mathworks.com/help/fininst/chooserbybls.html """

    valuation_date = Date(1, 6, 2007)
    chooseDate = Date(31, 8, 2007)
    call_expiry_date = Date(2, 12, 2007)
    put_expiry_date = Date(2, 12, 2007)
    call_strike = 60.0
    put_strike = 60.0
    stock_price = 50.0
    volatility = 0.20
    interest_rate = 0.10
    dividend_yield = 0.05

    model = BlackScholes(volatility)

    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    chooserOption = EquityChooserOption(chooseDate, call_expiry_date,
                                        put_expiry_date, call_strike,
                                        put_strike)

    v = chooserOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    v_mc = chooserOption.value_mc(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model, 20000)

    v_matlab = 8.9308
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "MATLAB", v_matlab, "MC", v_mc)
コード例 #4
0
def test_EquityChooserOptionHaug():
    """ Following example in Haug Page 130 """

    valuation_date = Date(1, 1, 2015)
    choose_date = Date(2, 4, 2015)
    call_expiry_date = Date(1, 7, 2015)
    put_expiry_date = Date(2, 8, 2015)
    call_strike = 55.0
    put_strike = 48.0
    stock_price = 50.0
    volatility = 0.35
    interest_rate = 0.10
    dividend_yield = 0.05

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    chooserOption = EquityChooserOption(choose_date, call_expiry_date,
                                        put_expiry_date, call_strike,
                                        put_strike)

    v = chooserOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    v_mc = chooserOption.value_mc(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model, 20000)

    v_haug = 6.0508
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "HAUG", v_haug, "MC", v_mc)
コード例 #5
0
def test_FinFXDigitalOption():

    # Not exactly T=1.0 but close so don't exact exact agreement
    # (in fact I do not get exact agreement even if I do set T=1.0)
    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.030  # EUR
    ccy2CCRate = 0.025  # USD

    currency_pair = ccy1 + ccy2  # Always ccy1ccy2
    spot_fx_rate = 1.20
    strike_fx_rate = 1.250
    volatility = 0.10

    notional = 1.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    digital_option = FXDigitalOption(expiry_date, strike_fx_rate,
                                     currency_pair, OptionTypes.DIGITAL_CALL,
                                     notional, "USD")

    spot_fx_rate = np.linspace(0.01, 2.0, 10)

    value = digital_option.value(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
コード例 #6
0
def test_EquityChooserOptionHaug():
    """ Following example in Haug Page 130 """

    valuation_date = Date(1, 1, 2015)
    choose_date = Date(2, 4, 2015)
    call_expiry_date = Date(1, 7, 2015)
    put_expiry_date = Date(2, 8, 2015)
    call_strike = 55.0
    put_strike = 48.0
    stock_price = 50.0
    volatility = 0.35
    interest_rate = 0.10
    dividend_yield = 0.05

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    chooserOption = EquityChooserOption(choose_date, call_expiry_date,
                                        put_expiry_date, call_strike,
                                        put_strike)

    v = chooserOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    v_mc = chooserOption.value_mc(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model, 20000)

    v_haug = 6.0508

    assert round(v, 4) == 6.0342
    assert round(v_haug, 4) == 6.0508
    assert round(v_mc, 4) == 6.0587
コード例 #7
0
def test_EquityChooserOptionDerivicom():
    """http://derivicom.com/support/finoptionsxl/index.html?complex_chooser.htm """

    valuation_date = Date(1, 1, 2007)
    chooseDate = Date(1, 2, 2007)
    call_expiry_date = Date(1, 4, 2007)
    put_expiry_date = Date(1, 5, 2007)
    call_strike = 40.0
    put_strike = 35.0
    stock_price = 38.0
    volatility = 0.20
    interest_rate = 0.08
    dividend_yield = 0.0625

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    chooserOption = EquityChooserOption(chooseDate, call_expiry_date,
                                        put_expiry_date, call_strike,
                                        put_strike)

    v = chooserOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    v_mc = chooserOption.value_mc(valuation_date, stock_price, discount_curve,
                                  dividend_curve, model, 20000)

    v_derivicom = 1.0989

    assert round(v, 4) == 1.1052
    assert round(v_derivicom, 4) == 1.0989
    assert round(v_mc, 4) == 1.1095
コード例 #8
0
def test_vega_theta():
    #   Example from Hull 4th edition page 284
    valuation_date = Date(1, 1, 2015)
    expiry_date = valuation_date.add_months(4)
    spot_fx_rate = 1.60
    volatility = 0.1411
    dom_interest_rate = 0.08
    forInterestRate = 0.11
    model = BlackScholes(volatility)
    dom_discount_curve = DiscountCurveFlat(valuation_date, dom_interest_rate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forInterestRate)

    strike_fx_rate = 1.6

    call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                  OptionTypes.EUROPEAN_CALL, 1000000, "USD")

    vega = call_option.vega(valuation_date, spot_fx_rate, dom_discount_curve,
                            for_discount_curve, model)

    assert round(vega, 4) == 0.3518

    theta = call_option.theta(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    assert round(theta, 4) == -0.0504
コード例 #9
0
def test_value_mc():
    #   Example from Hull 4th edition page 284
    valuation_date = Date(1, 1, 2015)
    expiry_date = valuation_date.add_months(4)
    spot_fx_rate = 1.60
    volatility = 0.1411
    dom_interest_rate = 0.08
    forInterestRate = 0.11
    model = BlackScholes(volatility)
    dom_discount_curve = DiscountCurveFlat(valuation_date, dom_interest_rate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forInterestRate)
    num_paths = 100000

    strike_fx_rate = 1.6

    call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                  OptionTypes.EUROPEAN_CALL, 1000000, "USD")

    value_mc = call_option.value_mc(valuation_date, spot_fx_rate,
                                    dom_discount_curve, for_discount_curve,
                                    model, num_paths)

    assert round(value_mc, 4) == 0.0429

    put_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                 OptionTypes.EUROPEAN_PUT, 1000000, "USD")

    value_mc = put_option.value_mc(valuation_date, spot_fx_rate,
                                   dom_discount_curve, for_discount_curve,
                                   model, num_paths)

    assert round(value_mc, 4) == 0.0582
コード例 #10
0
def test_FinFXVanillaOptionBloombergExample():

    # Example Bloomberg Pricing at
    # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg

    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(15, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    forName = "EUR"
    domName = "USD"
    forDepoRate = 0.05  # EUR
    domDepoRate = 0.02  # USD

    currency_pair = forName + domName  # Always FORDOM
    spot_fx_rate = 1.30
    strike_fx_rate = 1.3650
    volatility = 0.20

    spot_days = 0
    settlement_date = valuation_date.add_weekdays(spot_days)
    maturity_date = settlement_date.add_months(12)
    notional = 1000000.0
    notional_currency = "EUR"
    calendar_type = CalendarTypes.TARGET

    depos = []
    fras = []
    swaps = []
    depo = IborDeposit(settlement_date, maturity_date, domDepoRate,
                       DayCountTypes.ACT_360, notional, calendar_type)
    depos.append(depo)
    dom_discount_curve = IborSingleCurve(valuation_date, depos, fras, swaps)

    depos = []
    fras = []
    swaps = []
    depo = IborDeposit(settlement_date, maturity_date, forDepoRate,
                       DayCountTypes.ACT_360, notional, calendar_type)
    depos.append(depo)
    for_discount_curve = IborSingleCurve(valuation_date, depos, fras, swaps)

    model = BlackScholes(volatility)

    call_option = FXVanillaOption(expiry_date, strike_fx_rate, currency_pair,
                                  OptionTypes.EUROPEAN_CALL, notional,
                                  notional_currency, 2)

    value = call_option.value(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    delta = call_option.delta(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
コード例 #11
0
def test_FinFXVanillaOptionWystupExample2():
    # Example Bloomberg Pricing at
    # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg

    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.0396  # EUR
    ccy2CCRate = 0.0357  # USD

    currency_pair = ccy1 + ccy2  # Always ccy1ccy2
    spot_fx_rate = 0.9090
    strike_fx_rate = 0.9090
    volatility = 0.12

    notional = 1000000.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    call_option = FXVanillaOption(expiry_date, strike_fx_rate, currency_pair,
                                  OptionTypes.EUROPEAN_PUT, notional, "EUR", 2)

    value = call_option.value(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    assert round(value['v'], 4) == 0.0436
    assert round(value['cash_dom'], 4) == 43612.8769
    assert round(value['cash_for'], 4) == 47978.9625
    assert round(value['pips_dom'], 4) == 0.0436
    assert round(value['pips_for'], 4) == 0.0528
    assert round(value['pct_dom'], 4) == 0.0480
    assert round(value['pct_for'], 4) == 0.0480
    assert round(value['not_dom'], 4) == 909000.0
    assert round(value['not_for'], 4) == 1000000.0
    assert value['ccy_dom'] == 'USD'
    assert value['ccy_for'] == 'EUR'

    delta = call_option.delta(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    assert round(delta['pips_spot_delta'], 4) == -0.4700
    assert round(delta['pips_fwd_delta'], 4) == -0.4890
    assert round(delta['pct_spot_delta_prem_adj'], 4) == -0.5180
    assert round(delta['pct_fwd_delta_prem_adj'], 4) == -0.5389
コード例 #12
0
def test_FinFXVanillaOptionWystupExample1():

    # Example from Book extract by Uwe Wystup with results in Table 1.2
    # https://mathfinance.com/wp-content/uploads/2017/06/FXOptionsStructuredProducts2e-Extract.pdf

    # Not exactly T=1.0 but close so don't exact exact agreement
    # (in fact I do not get exact agreement even if I do set T=1.0)
    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.030  # EUR
    ccy2CCRate = 0.025  # USD

    currency_pair = ccy1 + ccy2  # Always ccy1ccy2
    spot_fx_rate = 1.20
    strike_fx_rate = 1.250
    volatility = 0.10

    notional = 1000000.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    call_option = FXVanillaOption(expiry_date, strike_fx_rate, currency_pair,
                                  OptionTypes.EUROPEAN_CALL, notional, "EUR",
                                  2)

    value = call_option.value(1.0, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    notional = 1250000.0
    call_option = FXVanillaOption(expiry_date, strike_fx_rate, currency_pair,
                                  OptionTypes.EUROPEAN_CALL, notional, "USD",
                                  2)

    value = call_option.value(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    delta = call_option.delta(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
コード例 #13
0
def test_BBGOneTouchOption():

    # 1YR ONETOUCH ON EURUSD

    valuation_date = Date(3, 12, 2021)
    expiry_date = Date(5, 12, 2022)
    barrier_level = 1.1865  # THIS IS NUMBER OF DOLLARS PER EURO

    spot_fx_rate = 1.1300  # EURUSD
    volatility = 0.06075

    model = BlackScholes(volatility)

    forRate = 0.00593  # EUR
    domRate = -0.00414  # USD

    num_paths = 50000
    num_steps_per_year = 252

    domCurve = DiscountCurveFlat(valuation_date, domRate)
    forCurve = DiscountCurveFlat(valuation_date, forRate)

    payment_size = 1000000  # EUR

    optionType = TouchOptionTypes.UP_AND_IN_CASH_AT_EXPIRY

    option = FXOneTouchOption(expiry_date, optionType, barrier_level,
                              payment_size)

    v = option.value(valuation_date, spot_fx_rate, domCurve, forCurve, model)

    v_mc = option.value_mc(valuation_date, spot_fx_rate, domCurve, forCurve,
                           model, num_steps_per_year, num_paths)

    d = option.delta(valuation_date, spot_fx_rate, domCurve, forCurve, model)

    g = option.gamma(valuation_date, spot_fx_rate, domCurve, forCurve, model)

    v = option.vega(valuation_date, spot_fx_rate, domCurve, forCurve, model)

    # I SHOULD GET 49.4934% OR 494,934 in EUR
    # VEGA IS 68,777.26
    # GAMMA IS 916,285
    # DELTA IS -9560266

    print(optionType)
    print("Value:", v)
    print("Value MC:", v_mc)
    print("Delta: ", d)
    print("Gamma:", g)
    print("Vega:", v)
コード例 #14
0
def test_FinFXVanillaOptionWystupExample2():

    # Example Bloomberg Pricing at
    # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg

    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.0396  # EUR
    ccy2CCRate = 0.0357  # USD

    currency_pair = ccy1 + ccy2  # Always ccy1ccy2
    spot_fx_rate = 0.9090
    strike_fx_rate = 0.9090
    volatility = 0.12

    notional = 1000000.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    call_option = FXVanillaOption(expiry_date, strike_fx_rate, currency_pair,
                                  FinOptionTypes.EUROPEAN_PUT, notional, "EUR",
                                  2)

    value = call_option.value(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    delta = call_option.delta(valuation_date, spot_fx_rate, dom_discount_curve,
                              for_discount_curve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
コード例 #15
0
def test_black_scholes():
    v = amOption.value(valuation_date, stock_price, discount_curve,
                       dividend_curve, modelTree)
    assert round(v, 4) == 6.8391

    modelApprox = BlackScholes(volatility, BlackScholesTypes.BARONE_ADESI)

    v = amOption.value(valuation_date, stock_price, discount_curve,
                       dividend_curve, modelApprox)

    assert round(v, 4) == 6.8277

    v = ameuOption.value(valuation_date, stock_price, discount_curve,
                         dividend_curve, modelTree)

    assert round(v, 4) == 6.7510

    v = euOption.value(valuation_date, stock_price, discount_curve,
                       dividend_curve, modelTree)

    assert round(v, 4) == 6.7493
コード例 #16
0
def test_EquityCliquetOption():

    start_date = Date(1, 1, 2014)
    final_expiry_date = Date(1, 1, 2017)
    freq_type = FrequencyTypes.QUARTERLY
    option_type = OptionTypes.EUROPEAN_CALL

    cliquetOption = EquityCliquetOption(start_date, final_expiry_date,
                                        option_type, freq_type)

    valuation_date = Date(1, 1, 2015)
    stock_price = 100.0
    volatility = 0.20
    interest_rate = 0.05
    dividend_yield = 0.02
    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    v = cliquetOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    assert round(v, 4) == 34.5287
コード例 #17
0
def test_EquityCliquetOption():

    start_date = Date(1, 1, 2014)
    final_expiry_date = Date(1, 1, 2017)
    freq_type = FrequencyTypes.QUARTERLY
    option_type = FinOptionTypes.EUROPEAN_CALL

    cliquetOption = EquityCliquetOption(start_date, final_expiry_date,
                                        option_type, freq_type)

    valuation_date = Date(1, 1, 2015)
    stock_price = 100.0
    volatility = 0.20
    interest_rate = 0.05
    dividend_yield = 0.02
    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    v = cliquetOption.value(valuation_date, stock_price, discount_curve,
                            dividend_curve, model)

    testCases.header("LABEL", "VALUE")
    testCases.print("FINANCEPY", v)
コード例 #18
0
def testEquityAmericanOption():

    valuation_date = Date(1, 1, 2016)
    expiry_date = Date(1, 1, 2017)
    stock_price = 50.0
    interest_rate = 0.06
    dividend_yield = 0.04
    volatility = 0.40
    strike_price = 50.0

    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    testCases.banner("================== EUROPEAN PUT =======================")

    put_option = EquityAmericanOption(expiry_date, strike_price,
                                      FinOptionTypes.EUROPEAN_PUT)

    model = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, 100)

    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("OPTION_TYPE", "VALUE", "DELTA", "GAMMA", "THETA")
    testCases.print("EUROPEAN_PUT_BS", value, delta, gamma, theta)

    option = EquityAmericanOption(expiry_date, strike_price,
                                  FinOptionTypes.EUROPEAN_PUT)

    testCases.header("OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA",
                     "TIME")

    num_steps_list = [100, 200, 500, 1000, 2000]

    for num_steps in num_steps_list:

        model = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps)

        start = time.time()
        results = option.value(valuation_date, stock_price, discount_curve,
                               dividend_curve, model)
        end = time.time()
        duration = end - start
        testCases.print("EUROPEAN_PUT_TREE", num_steps, results, duration)

    testCases.banner("================== AMERICAN PUT =======================")

    option = EquityAmericanOption(expiry_date, strike_price,
                                  FinOptionTypes.AMERICAN_PUT)

    testCases.header("OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA",
                     "TIME")

    for num_steps in num_steps_list:

        model = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps)

        start = time.time()
        results = option.value(valuation_date, stock_price, discount_curve,
                               dividend_curve, model)
        end = time.time()
        duration = end - start
        testCases.print("AMERICAN_PUT", num_steps, results, duration)

    testCases.banner(
        "================== EUROPEAN CALL =======================")

    call_option = EquityAmericanOption(expiry_date, strike_price,
                                       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)
    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("OPTION_TYPE", "VALUE", "DELTA", "GAMMA", "THETA")
    testCases.print("EUROPEAN_CALL_BS", value, delta, gamma, theta)

    option = EquityAmericanOption(expiry_date, strike_price,
                                  FinOptionTypes.EUROPEAN_CALL)

    testCases.header("OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA",
                     "TIME")

    for num_steps in num_steps_list:

        model = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps)
        start = time.time()
        results = option.value(valuation_date, stock_price, discount_curve,
                               dividend_curve, model)
        end = time.time()
        duration = end - start
        testCases.print("EUROPEAN_CALL_TREE", num_steps, results, duration)

    testCases.banner(
        "================== AMERICAN CALL =======================")
    testCases.header("OPTION_TYPE", "NUMSTEPS", "VALUE DELTA GAMMA THETA",
                     "TIME")

    option = EquityAmericanOption(expiry_date, strike_price,
                                  FinOptionTypes.AMERICAN_CALL)

    for num_steps in num_steps_list:

        model = BlackScholes(volatility, BlackScholesTypes.CRR_TREE, num_steps)

        start = time.time()

        results = option.value(valuation_date, stock_price, discount_curve,
                               dividend_curve, model)

        end = time.time()
        duration = end - start
        testCases.print("AMERICAN_CALL", num_steps, results, duration)
コード例 #19
0
def test_FinFXVanillaOptionHullExample():

    #   Example from Hull 4th edition page 284
    valuation_date = Date(1, 1, 2015)
    expiry_date = valuation_date.add_months(4)
    spot_fx_rate = 1.60
    volatility = 0.1411
    dom_interest_rate = 0.08
    forInterestRate = 0.11
    model = BlackScholes(volatility)
    dom_discount_curve = DiscountCurveFlat(valuation_date, dom_interest_rate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forInterestRate)

    num_paths_list = [10000, 20000, 40000, 80000, 160000, 320000]

    testCases.header("NUMPATHS", "VALUE_BS", "VALUE_MC")
    strike_fx_rate = 1.60

    for num_paths in num_paths_list:

        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)

        start = time.time()

        value_mc = call_option.value_mc(valuation_date, spot_fx_rate,
                                        dom_discount_curve, for_discount_curve,
                                        model, num_paths)

        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10)
    spot_fx_rates = spot_fx_rates / 100.0
    num_paths = 100000

    testCases.header("NUMPATHS", "CALL_VALUE_BS", "CALL_VALUE_MC")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        start = time.time()
        value_mc = call_option.value_mc(valuation_date, spot_fx_rate,
                                        dom_discount_curve, for_discount_curve,
                                        model, num_paths)
        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10) / 100.0
    num_paths = 100000

    testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "PUT_VALUE_MC")

    for spot_fx_rate in spot_fx_rates:

        put_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                     OptionTypes.EUROPEAN_PUT, 1000000, "USD")

        value = put_option.value(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        start = time.time()
        value_mc = put_option.value_mc(valuation_date, spot_fx_rate,
                                       dom_discount_curve, for_discount_curve,
                                       model, num_paths)
        end = time.time()
        duration = end - start
        testCases.print(spot_fx_rate, value, value_mc)

##########################################################################

    spot_fx_rates = np.arange(100, 200, 10) / 100.0

    testCases.header("SPOT FX RATE", "CALL_VALUE_BS", "DELTA_BS", "VEGA_BS",
                     "THETA_BS", "RHO_BS")

    for spot_fx_rate in spot_fx_rates:
        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")
        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        delta = call_option.delta(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        vega = call_option.vega(valuation_date, spot_fx_rate,
                                dom_discount_curve, for_discount_curve, model)
        theta = call_option.theta(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)
        #  call_option.rho(valuation_date,stock_price, interest_rate,
        #  dividend_yield, modelType, model_params)
        rho = 999
        testCases.print(spot_fx_rate, value, delta, vega, theta, rho)

    testCases.header("SPOT FX RATE", "PUT_VALUE_BS", "DELTA_BS", "VEGA_BS",
                     "THETA_BS", "RHO_BS")

    for spot_fx_rate in spot_fx_rates:
        put_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                     OptionTypes.EUROPEAN_PUT, 1000000, "USD")

        value = put_option.value(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        delta = put_option.delta(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        vega = put_option.vega(valuation_date, spot_fx_rate,
                               dom_discount_curve, for_discount_curve, model)
        theta = put_option.theta(valuation_date, spot_fx_rate,
                                 dom_discount_curve, for_discount_curve, model)
        # put_option.rho(valuation_date,stock_price, interest_rate, dividend_yield,
        # modelType, model_params)
        rho = 999
        testCases.print(spot_fx_rate, value, delta, vega, theta, rho)

##########################################################################

    testCases.header("SPOT FX RATE", "VALUE_BS", "VOL_IN", "IMPLD_VOL")

    spot_fx_rates = np.arange(100, 200, 10) / 100.0

    for spot_fx_rate in spot_fx_rates:
        call_option = FXVanillaOption(expiry_date, strike_fx_rate, "EURUSD",
                                      OptionTypes.EUROPEAN_CALL, 1000000,
                                      "USD")

        value = call_option.value(valuation_date, spot_fx_rate,
                                  dom_discount_curve, for_discount_curve,
                                  model)['v']

        impliedVol = call_option.implied_volatility(valuation_date,
                                                    spot_fx_rate,
                                                    dom_discount_curve,
                                                    for_discount_curve, value)

        testCases.print(spot_fx_rate, value, volatility, impliedVol)
コード例 #20
0
def test_EquityDigitalOption():

    underlying_type = FinDigitalOptionTypes.CASH_OR_NOTHING

    valuation_date = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    stock_price = 100.0
    volatility = 0.30
    interest_rate = 0.05
    dividend_yield = 0.01
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    model = BlackScholes(volatility)
    import time

    call_option_values = []
    call_option_valuesMC = []
    num_paths_list = [
        10000, 20000, 40000, 80000, 160000, 320000, 640000, 1280000, 2560000
    ]

    testCases.header("NumLoops", "ValueBS", "ValueMC", "TIME")

    for num_paths in num_paths_list:

        call_option = EquityDigitalOption(expiry_date, 100.0,
                                          OptionTypes.EUROPEAN_CALL,
                                          underlying_type)
        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)

        call_option_values.append(value)
        call_option_valuesMC.append(value_mc)

#    plt.figure(figsize=(10,8))
#    plt.plot(num_paths_list, call_option_values, color = 'b', label="Call Option")
#    plt.plot(num_paths_list, call_option_valuesMC, color = 'r', label = "Call Option MC")
#    plt.xlabel("Num Loops")
#    plt.legend(loc='best')

##########################################################################

    stock_prices = range(50, 150, 50)
    call_option_values = []
    call_optionDeltas = []
    call_optionVegas = []
    call_optionThetas = []

    for stock_price in stock_prices:
        call_option = EquityDigitalOption(expiry_date, 100.0,
                                          OptionTypes.EUROPEAN_CALL,
                                          underlying_type)
        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)
        call_option_values.append(value)
        call_optionDeltas.append(delta)
        call_optionVegas.append(vega)
        call_optionThetas.append(theta)

    put_option_values = []
    put_optionDeltas = []
    put_optionVegas = []
    put_optionThetas = []

    for stock_price in stock_prices:
        put_option = EquityDigitalOption(expiry_date, 100.0,
                                         OptionTypes.EUROPEAN_PUT,
                                         underlying_type)
        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)
        put_option_values.append(value)
        put_optionDeltas.append(delta)
        put_optionVegas.append(vega)
        put_optionThetas.append(theta)
コード例 #21
0
def test_FinFXOptionSABR():

    # UNFINISHED
    # There is no FXAmericanOption class. It is embedded in the FXVanillaOption
    # class. This test just compares it to the European

    valuation_date = Date(13, 2, 2018)
    expiry_date = Date(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1CCRate = 0.030  # EUR
    ccy2CCRate = 0.025  # USD

    spot_fx_rate = 1.20
    strike_fx_rate = 1.250
    volatility = 0.10

    notional = 1000000.0

    dom_discount_curve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = BlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0

    spot_fx_rates = np.arange(50, 200, 10)/100.0

    testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.EUROPEAN_CALL,
                                     notional,
                                     "USD")

        valueEuropean = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.AMERICAN_CALL,
                                     1000000,
                                     "USD")

        valueAmerican = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        diff = (valueAmerican - valueEuropean)

        testCases.print("CALL:",
                        "%9.6f" % spot_fx_rate,
                        "%9.7f" % valueEuropean,
                        "%9.7f" % valueAmerican,
                        "%9.7f" % diff)

    testCases.header("OPTION", "FX_RATE", "VALUE_BS", "VOL_IN", "DIFF")

    for spot_fx_rate in spot_fx_rates:

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.EUROPEAN_PUT,
                                     1000000,
                                     "USD")

        valueEuropean = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        call_option = FXVanillaOption(expiry_date,
                                     strike_fx_rate,
                                     "EURUSD",
                                     OptionTypes.AMERICAN_PUT,
                                     1000000,
                                     "USD")

        valueAmerican = call_option.value(valuation_date,
                                         spot_fx_rate,
                                         dom_discount_curve,
                                         for_discount_curve,
                                         model)['v']

        diff = (valueAmerican - valueEuropean)
        testCases.print("PUT:",
                        "%9.6f" % spot_fx_rate,
                        "%9.7f" % valueEuropean,
                        "%9.7f" % valueAmerican,
                        "%9.7f" % diff)
コード例 #22
0
def testConvergence():

    valuation_date = Date(1, 1, 2014)
    startAveragingDate = Date(1, 6, 2014)
    expiry_date = Date(1, 1, 2015)
    stock_price = 100.0
    volatility = 0.20
    interest_rate = 0.30
    dividend_yield = 0.10
    num_observations = 120  # daily as we have a half year
    accruedAverage = None
    K = 100
    seed = 1976

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    asianOption = EquityAsianOption(startAveragingDate,
                                    expiry_date,
                                    K,
                                    OptionTypes.EUROPEAN_CALL,
                                    num_observations)

    testCases.header(
        "K",
        "Geometric",
        "Turnbull_Wakeman",
        "Curran",
        "FastMC",
        "FastMC_CV")

    valuesTurnbull = []
    valuesCurran = []
    valuesGeometric = []
    valuesMC_fast = []
    valuesMC_CV = []

    num_paths_list = [5000]

    for num_paths in num_paths_list:

        accruedAverage = stock_price * 1.1

        value_mc_fast = asianOption._value_mc_fast(valuation_date,
                                                   stock_price,
                                                   discount_curve,
                                                   dividend_curve,
                                                   model,
                                                   num_paths,
                                                   seed,
                                                   accruedAverage)

        value_mc_CV = asianOption.value_mc(valuation_date,
                                           stock_price,
                                           discount_curve,
                                           dividend_curve,
                                           model,
                                           num_paths,
                                           seed,
                                           accruedAverage)

        valueGeometric = asianOption.value(valuation_date,
                                           stock_price,
                                           discount_curve,
                                           dividend_curve,
                                           model,
                                           AsianOptionValuationMethods.GEOMETRIC,
                                           accruedAverage)

        valueTurnbullWakeman = asianOption.value(valuation_date,
                                                 stock_price,
                                                 discount_curve,
                                                 dividend_curve,
                                                 model,
                                                 AsianOptionValuationMethods.TURNBULL_WAKEMAN,
                                                 accruedAverage)

        valueCurran = asianOption.value(valuation_date,
                                        stock_price,
                                        discount_curve,
                                        dividend_curve,
                                        model,
                                        AsianOptionValuationMethods.CURRAN,
                                        accruedAverage)

        valuesGeometric.append(valueGeometric)
        valuesTurnbull.append(valueTurnbullWakeman)
        valuesCurran.append(valueCurran)
        valuesMC_fast.append(value_mc_fast)
        valuesMC_CV.append(value_mc_CV)

        testCases.print(
            num_paths,
            valueGeometric,
            valueTurnbullWakeman,
            valueCurran,
            value_mc_fast,
            value_mc_CV)
コード例 #23
0
def testMCTimings():

    valuation_date = Date(1, 1, 2014)
    startAveragingDate = Date(1, 6, 2014)
    expiry_date = Date(1, 1, 2015)
    stock_price = 100.0
    volatility = 0.20
    interest_rate = 0.30
    dividend_yield = 0.10
    num_observations = 120  # daily as we have a half year
    accruedAverage = None
    K = 100
    seed = 1976

    model = BlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    asianOption = EquityAsianOption(startAveragingDate,
                                    expiry_date,
                                    K,
                                    OptionTypes.EUROPEAN_CALL,
                                    num_observations)

    testCases.header(
        "NUMPATHS",
        "VALUE",
        "TIME",
        "VALUE_MC",
        "TIME",
        "VALUE_MC_CV",
        "TIME")

    valuesMC = []
    valuesMC_fast = []
    valuesMC_fast_CV = []

    tvaluesMC = []
    tvaluesMC_fast = []
    tvaluesMC_fast_CV = []

    num_paths_list = [5000]

    for num_paths in num_paths_list:

        accruedAverage = stock_price * 1.1

        start = time.time()
        value_mc = asianOption.value_mc(valuation_date,
                                        stock_price,
                                        discount_curve,
                                        dividend_curve,
                                        model,
                                        num_paths,
                                        seed,
                                        accruedAverage)

        end = time.time()
        t_MC = end - start

        start = time.time()
        value_mc_fast = asianOption._value_mc_fast(valuation_date,
                                                   stock_price,
                                                   discount_curve,
                                                   dividend_curve,
                                                   model,
                                                   num_paths,
                                                   seed,
                                                   accruedAverage)

        end = time.time()
        t_MC_fast = end - start

        start = time.time()
        value_mc_fast_CV = asianOption.value_mc(valuation_date,
                                                stock_price,
                                                discount_curve,
                                                dividend_curve,
                                                model,
                                                num_paths,
                                                seed,
                                                accruedAverage)

        end = time.time()
        t_MC_fast_CV = end - start

        valuesMC.append(value_mc)
        valuesMC_fast.append(value_mc_fast)
        valuesMC_fast_CV.append(value_mc_fast_CV)

        tvaluesMC.append(t_MC)
        tvaluesMC_fast.append(t_MC_fast)
        tvaluesMC_fast_CV.append(t_MC_fast_CV)

        testCases.print(
            num_paths,
            value_mc,
            t_MC,
            value_mc_fast,
            t_MC_fast,
            value_mc_fast_CV,
            t_MC_fast_CV)
コード例 #24
0
def testTimeEvolution():

    startAveragingDate = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    stock_price = 100.0
    volatility = 0.20
    interest_rate = 0.30
    dividend_yield = 0.10
    num_observations = 100  # weekly as we have a year
    accruedAverage = None
    K = 100
    seed = 1976

    model = BlackScholes(volatility)

    asianOption = EquityAsianOption(startAveragingDate,
                                    expiry_date,
                                    K,
                                    OptionTypes.EUROPEAN_CALL,
                                    num_observations)

    testCases.header(
        "Date",
        "Geometric",
        "Turnbull_Wakeman",
        "Curran",
        "FastMC",
        "FastMC_CV")

    valuesTurnbull = []
    valuesCurran = []
    valuesGeometric = []
    valuesMC_fast = []
    valuesMC_CV = []

    valuation_dates = []
    valuation_dates.append(Date(1, 4, 2014))
    valuation_dates.append(Date(1, 6, 2014))
    valuation_dates.append(Date(1, 8, 2014))
    valuation_dates.append(Date(1, 2, 2015))
    valuation_dates.append(Date(1, 4, 2015))
    valuation_dates.append(Date(1, 6, 2015))
    valuation_dates.append(Date(1, 8, 2015))

    num_paths = 10000

    for valuation_date in valuation_dates:

        accruedAverage = stock_price * 0.9

        discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
        dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

        value_mc_fast = asianOption._value_mc_fast(valuation_date,
                                                   stock_price,
                                                   discount_curve,
                                                   dividend_curve,
                                                   model,
                                                   num_paths,
                                                   seed,
                                                   accruedAverage)

        value_mc_CV = asianOption.value_mc(valuation_date,
                                           stock_price,
                                           discount_curve,
                                           dividend_curve,
                                           model,
                                           num_paths,
                                           seed,
                                           accruedAverage)

        valueGeometric = asianOption.value(valuation_date,
                                           stock_price,
                                           discount_curve,
                                           dividend_curve,
                                           model,
                                           AsianOptionValuationMethods.GEOMETRIC,
                                           accruedAverage)

        valueTurnbullWakeman = asianOption.value(valuation_date,
                                                 stock_price,
                                                 discount_curve,
                                                 dividend_curve,
                                                 model,
                                                 AsianOptionValuationMethods.TURNBULL_WAKEMAN,
                                                 accruedAverage)

        valueCurran = asianOption.value(valuation_date,
                                        stock_price,
                                        discount_curve,
                                        dividend_curve,
                                        model,
                                        AsianOptionValuationMethods.CURRAN,
                                        accruedAverage)

        valuesGeometric.append(valueGeometric)
        valuesTurnbull.append(valueTurnbullWakeman)
        valuesCurran.append(valueCurran)
        valuesMC_fast.append(value_mc_fast)
        valuesMC_CV.append(value_mc_CV)

        testCases.print(
            str(valuation_date),
            valueGeometric,
            valueTurnbullWakeman,
            valueCurran,
            value_mc_fast,
            value_mc_CV)
コード例 #25
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)
コード例 #26
0
volatility = 0.20
interest_rate = 0.05
dividend_yield = 0.02
stock_price = 80
B = 110.0
K = 100.0
option_type = EquityBarrierTypes.DOWN_AND_OUT_CALL

drift = interest_rate - dividend_yield
scheme = FinGBMNumericalScheme.NORMAL
process_type = ProcessTypes.GBM

discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

model = BlackScholes(volatility)

num_observations_per_year = 100


def test_down_and_out_call():
    option_type = EquityBarrierTypes.DOWN_AND_OUT_CALL
    option = EquityBarrierOption(
        expiry_date, K, option_type, B, num_observations_per_year)

    value = option.value(
        valuation_date,
        stock_price,
        discount_curve,
        dividend_curve,
        model)
コード例 #27
0
def test_EquityOneTouchOption():
    # Examples Haug Page 180 Table 4-22
    # Agreement not exact at t is not exactly 0.50

    valuation_date = Date(1, 1, 2016)
    expiry_date = Date(2, 7, 2016)
    interest_rate = 0.10
    volatility = 0.20
    barrier_level = 100.0  # H
    model = BlackScholes(volatility)
    dividend_yield = 0.03
    num_paths = 10000
    num_steps_per_year = 252

    discount_curve = DiscountCurveFlat(valuation_date, interest_rate)
    dividend_curve = DiscountCurveFlat(valuation_date, dividend_yield)

    stock_price = 105.0
    payment_size = 15.0

    testCases.header("================================= CASH ONLY")

    downTypes = [
        FinTouchOptionPayoffTypes.DOWN_AND_IN_CASH_AT_HIT,
        FinTouchOptionPayoffTypes.DOWN_AND_IN_CASH_AT_EXPIRY,
        FinTouchOptionPayoffTypes.DOWN_AND_OUT_CASH_OR_NOTHING
    ]

    testCases.header("TYPE", "VALUE", "VALUE_MC")

    for downType in downTypes:

        option = EquityOneTouchOption(expiry_date, downType, barrier_level,
                                      payment_size)

        v = option.value(valuation_date, stock_price, discount_curve,
                         dividend_curve, model)

        v_mc = option.value_mc(valuation_date, stock_price, discount_curve,
                               dividend_curve, model, num_steps_per_year,
                               num_paths)

        testCases.print("%60s " % downType, "%9.5f" % v, "%9.5f" % v_mc)

    stock_price = 95.0
    payment_size = 15.0

    upTypes = [
        FinTouchOptionPayoffTypes.UP_AND_IN_CASH_AT_HIT,
        FinTouchOptionPayoffTypes.UP_AND_IN_CASH_AT_EXPIRY,
        FinTouchOptionPayoffTypes.UP_AND_OUT_CASH_OR_NOTHING
    ]

    testCases.header("TYPE", "VALUE", "VALUE_MC")

    for upType in upTypes:

        option = EquityOneTouchOption(expiry_date, upType, barrier_level,
                                      payment_size)

        v = option.value(valuation_date, stock_price, discount_curve,
                         dividend_curve, model)

        v_mc = option.value_mc(valuation_date, stock_price, discount_curve,
                               dividend_curve, model, num_steps_per_year,
                               num_paths)

        testCases.print("%60s " % upType, "%9.5f" % v, "%9.5f" % v_mc)

    ###########################################################################

    stock_price = 105.0

    testCases.banner("================= ASSET ONLY")

    downTypes = [
        FinTouchOptionPayoffTypes.DOWN_AND_IN_ASSET_AT_HIT,
        FinTouchOptionPayoffTypes.DOWN_AND_IN_ASSET_AT_EXPIRY,
        FinTouchOptionPayoffTypes.DOWN_AND_OUT_ASSET_OR_NOTHING
    ]

    testCases.header("TYPE", "VALUE", "VALUE_MC")
    for downType in downTypes:

        option = EquityOneTouchOption(expiry_date, downType, barrier_level)

        v = option.value(valuation_date, stock_price, discount_curve,
                         dividend_curve, model)

        v_mc = option.value_mc(valuation_date, stock_price, discount_curve,
                               dividend_curve, model, num_steps_per_year,
                               num_paths)

        testCases.print("%60s " % downType, "%9.5f" % v, "%9.5f" % v_mc)

    stock_price = 95.0

    upTypes = [
        FinTouchOptionPayoffTypes.UP_AND_IN_ASSET_AT_HIT,
        FinTouchOptionPayoffTypes.UP_AND_IN_ASSET_AT_EXPIRY,
        FinTouchOptionPayoffTypes.UP_AND_OUT_ASSET_OR_NOTHING
    ]

    for upType in upTypes:

        option = EquityOneTouchOption(expiry_date, upType, barrier_level)

        v = option.value(valuation_date, stock_price, discount_curve,
                         dividend_curve, model)

        v_mc = option.value_mc(valuation_date, stock_price, discount_curve,
                               dividend_curve, model, num_steps_per_year,
                               num_paths)

        testCases.print("%60s " % upType, "%9.5f" % v, "%9.5f" % v_mc)
コード例 #28
0
def test_EquityVanillaOptionFactored():

    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)

    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 = EquityVanillaOptionOLD(
            expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL)
        value = call_option.value(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        start = time.time()
        value_mc = call_option.value_mc(valuation_date, stock_price, discount_curve,
                                     dividend_yield, 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 = EquityVanillaOptionOLD(expiry_date, 100.0,
                                            FinOptionTypes.EUROPEAN_CALL)

        value = call_option.value(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)

        start = time.time()

        useSobol = False
        value_mc1 = call_option.value_mc(valuation_date, stock_price, discount_curve,
                                      dividend_yield, model, num_paths, useSobol)

        useSobol = True
        value_mc2 = call_option.value_mc(valuation_date, stock_price, discount_curve,
                                      dividend_yield, 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 = EquityVanillaOptionOLD(expiry_date, 100.0,
                                           FinOptionTypes.EUROPEAN_PUT)

        value = put_option.value(valuation_date, stock_price, discount_curve,
                                dividend_yield, model)

        start = time.time()

        useSobol = False
        value_mc1 = put_option.value_mc(valuation_date, stock_price, discount_curve,
                                      dividend_yield, model, num_paths, useSobol)

        useSobol = True
        value_mc2 = put_option.value_mc(valuation_date, stock_price, discount_curve,
                                      dividend_yield, 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")

    for stock_price in stock_prices:

        call_option = EquityVanillaOptionOLD(expiry_date, 100.0,
                                            FinOptionTypes.EUROPEAN_CALL)
        value = call_option.value(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        delta = call_option.delta(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        vega = call_option.vega(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        theta = call_option.theta(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        rho = call_option.rho(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        testCases.print(stock_price, value, delta, vega, theta, rho)

    ###########################################################################

    testCases.header("STOCK PRICE", "PUT_VALUE_BS", "PUT_DELTA_BS", 
                     "PUT_VEGA_BS", "PUT_THETA_BS", "PUT_RHO_BS")

    for stock_price in stock_prices:
        
        put_option = EquityVanillaOptionOLD(expiry_date, 100.0,
                                           FinOptionTypes.EUROPEAN_PUT)

        value = put_option.value(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        delta = put_option.delta(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        vega = put_option.vega(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        theta = put_option.theta(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        rho = put_option.rho(valuation_date, stock_price, discount_curve,
                                 dividend_yield, model)
        testCases.print(stock_price, value, delta, vega, theta, rho)

###############################################################################

    testCases.header("STOCK PRICE", "VALUE_BS", "VOL_IN", "IMPLD_VOL")

    stock_prices = range(60, 150, 10)

    for stock_price in stock_prices:
        call_option = EquityVanillaOptionOLD(
            expiry_date, 100.0, FinOptionTypes.EUROPEAN_CALL)
        value = call_option.value(
            valuation_date,
            stock_price,
            discount_curve,
            dividend_yield,
            model)
        impliedVol = call_option.implied_volatility(
            valuation_date, stock_price, discount_curve, dividend_yield, value)
        testCases.print(stock_price, value, volatility, impliedVol)
コード例 #29
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."
コード例 #30
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)