def test_FinFXMktVolSurface5(verboseCalibration):

    ###########################################################################
    # Here I remove the 10D Vols
    ###########################################################################
    
    if 1 == 1:

        # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARK")

        valuation_date = Date(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate)
        forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]
        marketStrangle10DeltaVols = [2.433, 2.83, 3.228, 3.485, 3.806, 3.208]
        riskReversal10DeltaVols = [-1.258, -1.297, -1.332, -1.408, -1.359, -1.208]

        marketStrangle10DeltaVols = None
        riskReversal10DeltaVols = None
        
        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA
        volFunctionType = FinVolFunctionTypes.CLARK
        alpha = 0.50 # FIT WINGS AT 10D if ALPHA = 1.0

        fxMarketPlus = FinFXVolSurfacePlus(valuation_date,
                                       spotFXRate,
                                       currencyPair,
                                       notionalCurrency,
                                       domDiscountCurve,
                                       forDiscountCurve,
                                       tenors,
                                       atmVols,
                                       marketStrangle25DeltaVols,
                                       riskReversal25DeltaVols,
                                       marketStrangle10DeltaVols,
                                       riskReversal10DeltaVols,
                                       alpha,
                                       atmMethod,
                                       deltaMethod, 
                                       volFunctionType)

        fxMarketPlus.checkCalibration(False)
示例#2
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

    currencyPair = ccy1 + ccy2  # Always ccy1ccy2
    spotFXRate = 1.20
    strikeFXRate = 1.250
    volatility = 0.10

    notional = 1000000.0

    domDiscountCurve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    forDiscountCurve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = FinModelBlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair,
                                    FinOptionTypes.EUROPEAN_CALL, notional,
                                    "EUR", 2)

    value = callOption.value(1.0, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    notional = 1250000.0
    callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair,
                                    FinOptionTypes.EUROPEAN_CALL, notional,
                                    "USD", 2)

    value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
示例#3
0
def test_BondOptionAmericanConvergenceONE():

    # Build discount curve
    settlement_date = Date(1, 12, 2019)
    discount_curve = DiscountCurveFlat(settlement_date, 0.05)

    # Bond details
    maturity_date = Date(1, 9, 2025)
    issue_date = Date(1, 9, 2016)
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    # Option Details
    expiry_date = Date(1, 12, 2020)
    strikePrice = 100.0
    face = 100.0

    testCases.header("TIME", "N", "PUT_AMER", "PUT_EUR", "CALL_AME",
                     "CALL_EUR")

    timeSteps = range(30, 100, 10)

    for numTimeSteps in timeSteps:

        sigma = 0.20
        a = 0.1

        start = time.time()

        optionType = FinOptionTypes.AMERICAN_PUT
        bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)
        model1 = FinModelRatesBK(sigma, a, numTimeSteps)
        v1put = bondOption1.value(settlement_date, discount_curve, model1)

        optionType = FinOptionTypes.EUROPEAN_PUT
        bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)
        model2 = FinModelRatesBK(sigma, a, numTimeSteps)
        v2put = bondOption2.value(settlement_date, discount_curve, model2)

        optionType = FinOptionTypes.AMERICAN_CALL
        bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)
        model1 = FinModelRatesBK(sigma, a, numTimeSteps)
        v1call = bondOption1.value(settlement_date, discount_curve, model1)

        optionType = FinOptionTypes.EUROPEAN_CALL
        bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)
        model2 = FinModelRatesBK(sigma, a, numTimeSteps)
        v2call = bondOption2.value(settlement_date, discount_curve, model2)

        end = time.time()

        period = end - start

        testCases.print(period, numTimeSteps, v1put, v2put, v1call, v2call)
示例#4
0
def testBlackModelCheck():

    # Checking Andersen paper using Black's model
    # Used to check swaption price below - we have Ts = 1 and Te = 4
    # Expect a price around 122 cents which is what I find.

    valuation_date = Date(1, 1, 2020)
    libor_curve = DiscountCurveFlat(valuation_date, 0.06,
                                    FrequencyTypes.SEMI_ANNUAL)

    settlement_date = Date(1, 1, 2020)
    exerciseDate = Date(1, 1, 2021)
    maturity_date = Date(1, 1, 2024)

    fixedCoupon = 0.06
    fixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    fixedDayCountType = DayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    # Pricing a PAY
    swaptionType = FinSwapTypes.PAY
    swaption = FinIborSwaption(settlement_date, exerciseDate, maturity_date,
                               swaptionType, fixedCoupon, fixedFrequencyType,
                               fixedDayCountType, notional)

    model = FinModelBlack(0.20)
    v = swaption.value(valuation_date, libor_curve, model)
    testCases.header("LABEL", "VALUE")
    testCases.print("BLACK'S MODEL PRICE:", v * 100)
示例#5
0
def test_FinFloatIborLeg():

    effective_date = Date(28, 10, 2020)
    maturity_date = Date(28, 10, 2025)

    spread = 0.0
    freq_type = FrequencyTypes.ANNUAL
    day_count_type = DayCountTypes.THIRTY_360_BOND
    notional = 10.0 * ONE_MILLION
    legPayRecType = FinSwapTypes.PAY
    calendar_type = CalendarTypes.TARGET
    bus_day_adjust_type = BusDayAdjustTypes.FOLLOWING
    date_gen_rule_type = DateGenRuleTypes.BACKWARD
    payment_lag = 0
    principal = 0.0

    swapFloatLeg = FinFloatLeg(effective_date, maturity_date, legPayRecType,
                               spread, freq_type, day_count_type, notional,
                               principal, payment_lag, calendar_type,
                               bus_day_adjust_type, date_gen_rule_type)

    libor_curve = DiscountCurveFlat(effective_date, 0.05)

    firstFixing = 0.03

    v = swapFloatLeg.value(effective_date, libor_curve, libor_curve,
                           firstFixing)
示例#6
0
def test_FinFXMktVolSurface2(verboseCalibration):

        #print("==============================================================")

        # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
        # print("EURJPY EXAMPLE CLARK")

        valuation_date = Date(10, 4, 2020)

        forName = "EUR"
        domName = "JPY"
        forCCRate = 0.0294  # EUR
        domCCRate = 0.0171  # USD

        domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate)
        forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 90.72

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.50, 20.50, 19.85, 18.00, 15.95, 14.009]
        marketStrangle25DeltaVols = [0.35, 0.325, 0.300, 0.225, 0.175, 0.100]
        riskReversal25DeltaVols = [-8.350, -8.650, -8.950, -9.250, -9.550, -9.500]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

        fxMarket = FinFXVolSurface(valuation_date,
                                   spotFXRate,
                                   currencyPair,
                                   notionalCurrency,
                                   domDiscountCurve,
                                   forDiscountCurve,
                                   tenors,
                                   atmVols,
                                   marketStrangle25DeltaVols,
                                   riskReversal25DeltaVols,
                                   atmMethod,
                                   deltaMethod)

        fxMarket.checkCalibration(verboseCalibration)

        if PLOT_GRAPHS:
            fxMarket.plotVolCurves()
示例#7
0
def test_FinFXMktVolSurface4(verboseCalibration):

        # USDJPY Example from Paper by Uwe Wystup using Tables 4
#        print("USDJPY EXAMPLE WYSTUP")

        valuation_date = Date(20, 1, 2009)

        forName = "USD"
        domName = "JPY"
        forCCRate = 0.003525  # USD
        domCCRate = 0.0042875  # JPY

        domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate)
        forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 90.68

        tenors = ['1M']
        atmVols = [21.00]
        marketStrangle25DeltaVols = [0.184]
        riskReversal25DeltaVols = [-5.30]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

        fxMarket = FinFXVolSurface(valuation_date,
                                   spotFXRate,
                                   currencyPair,
                                   notionalCurrency,
                                   domDiscountCurve,
                                   forDiscountCurve,
                                   tenors,
                                   atmVols,
                                   marketStrangle25DeltaVols,
                                   riskReversal25DeltaVols,
                                   atmMethod,
                                   deltaMethod)

        fxMarket.checkCalibration(verboseCalibration)

        if PLOT_GRAPHS:
            fxMarket.plotVolCurves()
示例#8
0
def test_FinFXMktVolSurface3(verboseCalibration):

        # EURUSD Example from Paper by Uwe Wystup using Tables 4
#        print("EURUSD EXAMPLE WYSTUP")

        valuation_date = Date(20, 1, 2009)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.020113  # EUR
        domCCRate = 0.003525  # USD

        domDiscountCurve = DiscountCurveFlat(valuation_date, domCCRate)
        forDiscountCurve = DiscountCurveFlat(valuation_date, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3088

        tenors = ['1M']
        atmVols = [21.6215]
        marketStrangle25DeltaVols = [0.7375]
        riskReversal25DeltaVols = [-0.50]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA

        fxMarket = FinFXVolSurface(valuation_date,
                                   spotFXRate,
                                   currencyPair,
                                   notionalCurrency,
                                   domDiscountCurve,
                                   forDiscountCurve,
                                   tenors,
                                   atmVols,
                                   marketStrangle25DeltaVols,
                                   riskReversal25DeltaVols,
                                   atmMethod,
                                   deltaMethod)

        fxMarket.checkCalibration(verboseCalibration)

        if PLOT_GRAPHS:
            fxMarket.plotVolCurves()
示例#9
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

    currencyPair = ccy1 + ccy2  # Always ccy1ccy2
    spotFXRate = 0.9090
    strikeFXRate = 0.9090
    volatility = 0.12

    notional = 1000000.0

    domDiscountCurve = DiscountCurveFlat(valuation_date, ccy2CCRate)
    forDiscountCurve = DiscountCurveFlat(valuation_date, ccy1CCRate)

    model = FinModelBlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    callOption = FinFXVanillaOption(expiry_date, strikeFXRate, currencyPair,
                                    FinOptionTypes.EUROPEAN_PUT, notional,
                                    "EUR", 2)

    value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
def test_FinEquityVarianceSwap():

    start_date = Date(20, 3, 2018)
    tenor = "3M"
    strike = 0.3 * 0.3

    volSwap = FinEquityVarianceSwap(start_date, tenor, strike)

    valuation_date = Date(20, 3, 2018)
    stock_price = 100.0
    dividendYield = 0.0
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    maturity_date = start_date.addMonths(3)

    atmVol = 0.20
    atmK = 100.0
    skew = -0.02 / 5.0  # defined as dsigma/dK
    strikes = np.linspace(50.0, 135.0, 18)
    vols = volSkew(strikes, atmVol, atmK, skew)
    volCurve = FinEquityVolCurve(valuation_date, maturity_date, strikes, vols)

    strikeSpacing = 5.0
    numCallOptions = 10
    numPutOptions = 10
    r = 0.05

    discount_curve = DiscountCurveFlat(valuation_date, r)

    useForward = False

    testCases.header("LABEL", "VALUE")

    k1 = volSwap.fairStrike(valuation_date, stock_price, dividendCurve,
                            volCurve, numCallOptions, numPutOptions,
                            strikeSpacing, discount_curve, useForward)

    testCases.print("REPLICATION VARIANCE:", k1)

    k2 = volSwap.fairStrikeApprox(valuation_date, stock_price, strikes, vols)
    testCases.print("DERMAN SKEW APPROX for K:", k2)
示例#11
0
def test_FinEquityChooserOptionMatlab():
    """https://fr.mathworks.com/help/fininst/chooserbybls.html """

    valuation_date = Date(1, 6, 2007)
    chooseDate = Date(31, 8, 2007)
    callExpiryDate = Date(2, 12, 2007)
    putExpiryDate = Date(2, 12, 2007)
    callStrike = 60.0
    putStrike = 60.0
    stock_price = 50.0
    volatility = 0.20
    interestRate = 0.10
    dividendYield = 0.05

    model = FinModelBlackScholes(volatility)

    discount_curve = DiscountCurveFlat(valuation_date, interestRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate,
                                           callExpiryDate,
                                           putExpiryDate,
                                           callStrike,
                                           putStrike)

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

    v_mc = chooserOption.valueMC(valuation_date,
                                 stock_price,
                                 discount_curve,
                                 dividendCurve,
                                 model, 20000)

    v_matlab = 8.9308
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "MATLAB", v_matlab, "MC", v_mc)
示例#12
0
def test_FinEquityChooserOptionHaug():
    """ Following example in Haug Page 130 """

    valuation_date = Date(1, 1, 2015)
    chooseDate = Date(2, 4, 2015)
    callExpiryDate = Date(1, 7, 2015)
    putExpiryDate = Date(2, 8, 2015)
    callStrike = 55.0
    putStrike = 48.0
    stock_price = 50.0
    volatility = 0.35
    interestRate = 0.10
    dividendYield = 0.05

    model = FinModelBlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interestRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate,
                                           callExpiryDate,
                                           putExpiryDate,
                                           callStrike,
                                           putStrike)

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

    v_mc = chooserOption.valueMC(valuation_date,
                                 stock_price,
                                 discount_curve,
                                 dividendCurve,
                                 model, 20000)

    v_haug = 6.0508
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "HAUG", v_haug, "MC", v_mc)
示例#13
0
def test_FinEquityChooserOptionDerivicom():
    """http://derivicom.com/support/finoptionsxl/index.html?complex_chooser.htm """

    valuation_date = Date(1, 1, 2007)
    chooseDate = Date(1, 2, 2007)
    callExpiryDate = Date(1, 4, 2007)
    putExpiryDate = Date(1, 5, 2007)
    callStrike = 40.0
    putStrike = 35.0
    stock_price = 38.0
    volatility = 0.20
    interestRate = 0.08
    dividendYield = 0.0625

    model = FinModelBlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, interestRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate,
                                           callExpiryDate,
                                           putExpiryDate,
                                           callStrike,
                                           putStrike)

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

    v_mc = chooserOption.valueMC(valuation_date,
                                 stock_price,
                                 discount_curve,
                                 dividendCurve,
                                 model, 20000)

    v_derivicom = 1.0989
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "DERIVICOM", v_derivicom, "MC", v_mc)
示例#14
0
def test_FinEquityForward():

    valuation_date = Date(13, 2, 2018)
    expiry_date = valuation_date.addMonths(12)

    stock_price = 130.0
    forwardPrice = 125.0 # Locked
    discountRate = 0.05
    dividendRate = 0.02

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

    expiry_date = valuation_date.addMonths(12)
    notional = 100.0

    discount_curve = DiscountCurveFlat(valuation_date, discountRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendRate)

    equityForward = FinEquityForward(expiry_date,
                                     forwardPrice,
                                     notional,
                                     FinLongShort.LONG)

    testCases.header("SPOT FX", "FX FWD", "VALUE_BS")

    fwdPrice = equityForward.forward(valuation_date,
                                     stock_price,
                                     discount_curve, 
                                     dividendCurve)

    fwdValue = equityForward.value(valuation_date,
                                   stock_price,
                                   discount_curve, 
                                   dividendCurve)

#    print(stock_price, fwdPrice, fwdValue)
    testCases.print(stock_price, fwdPrice, fwdValue)
示例#15
0
def test_example():

    expiry_date = Date(1, 1, 2021)
    strikePrice = 105.0
    optionTypeCall = FinOptionTypes.EUROPEAN_CALL
    optionTypePut = FinOptionTypes.EUROPEAN_PUT
    lookbackCall = FinEquityFixedLookbackOption(expiry_date, optionTypeCall, strikePrice)
    lookbackPut = FinEquityFixedLookbackOption(expiry_date, optionTypePut, strikePrice)

    valuation_date = Date(1, 1, 2020)
    interestRate = 0.10
    stock_price = 100.0
    dividendYield = 0.0
    stockMinMax = 100.0

    discount_curve = DiscountCurveFlat(valuation_date, interestRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    volatilities = [0.30]

    testCases.header("VALUE")
    for vol in volatilities:
        v = lookbackCall.value(valuation_date, stock_price, discount_curve, dividendCurve, vol, stockMinMax)
        testCases.print(v)
示例#16
0
def test_FinFixedOIS():

    # Here I follow the example in
    # https://blog.deriscope.com/index.php/en/excel-quantlib-overnight-index-swap

    effective_date = Date(30, 11, 2018)
    end_date = Date(30, 11, 2023)

    end_date = effective_date.addMonths(60)
    oisRate = 0.04
    fixed_legType = FinSwapTypes.PAY
    fixedFreqType = FrequencyTypes.ANNUAL
    fixedDayCount = DayCountTypes.ACT_360
    floatFreqType = FrequencyTypes.ANNUAL
    floatDayCount = DayCountTypes.ACT_360
    floatSpread = 0.0
    notional = ONE_MILLION
    payment_lag = 1

    ois = FinOIS(effective_date, end_date, fixed_legType, oisRate,
                 fixedFreqType, fixedDayCount, notional, payment_lag,
                 floatSpread, floatFreqType, floatDayCount)

    #    print(ois)

    valuation_date = effective_date
    marketRate = 0.05
    oisCurve = DiscountCurveFlat(valuation_date, marketRate,
                                 FrequencyTypes.ANNUAL)

    v = ois.value(effective_date, oisCurve)

    #    print(v)

    #    ois._fixed_leg.printValuation()
    #    ois._floatLeg.printValuation()

    testCases.header("LABEL", "VALUE")
    testCases.print("SWAP_VALUE", v)
def test_FinIborCapletHull():

    #  Hull Page 703, example 29.3
    todayDate = Date(20, 6, 2019)
    valuation_date = todayDate
    maturity_date = valuation_date.addTenor("2Y")
    libor_curve = DiscountCurveFlat(valuation_date,
                                    0.070,
                                    FrequencyTypes.QUARTERLY,
                                    DayCountTypes.THIRTY_E_360)

    k = 0.08
    capFloorType = FinCapFloorTypes.CAP
    capFloor = FinIborCapFloor(valuation_date,
                                maturity_date,
                                capFloorType,
                                k,
                                None,
                                FrequencyTypes.QUARTERLY,
                                DayCountTypes.THIRTY_E_360)

    # Value cap using a single flat cap volatility
    model = FinModelBlack(0.20)
    capFloor.value(valuation_date, libor_curve, model)

    # Value cap by breaking it down into caplets using caplet vols
    capletStartDate = valuation_date.addTenor("1Y")
    capletEndDate = capletStartDate.addTenor("3M")

    vCaplet = capFloor.valueCapletFloorLet(valuation_date,
                                           capletStartDate,
                                           capletEndDate,
                                           libor_curve,
                                           model)

    # Cannot match Hull due to dates being adjusted
    testCases.header("CORRECT PRICE", "MODEL_PRICE")
    testCases.print(517.29, vCaplet)
def test_FinSwaptionVolSurface1(verboseCalibration):

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

    if 1 == 1:

        # https://fr.mathworks.com/help/fininst/pricing-a-swaption-using-the-sabr-model.html

        valuation_date = Date(12, 6, 2013)

        # These are 3M, 1Y, 2Y, 3Y, 4Y, 5Y, 7Y, 10Y
        exerciseDates = [Date(12, 9, 2013), Date(12, 6, 2014),
                         Date(12, 6, 2015), Date(12, 6, 2016),
                         Date(12, 6, 2017), Date(12, 6, 2018),
                         Date(12, 6, 2020), Date(12, 6, 2023)]

        # First dimension is the strike, then the expiry date
        marketVolatilities = [[57.6, 53.7, 49.4, 45.6, 44.1, 41.1, 35.2, 32.0],
                              [46.6, 46.9, 44.8, 41.6, 39.8, 37.4, 33.4, 31.0],
                              [35.9, 39.3, 39.6, 37.9, 37.2, 34.7, 30.5, 28.9],
                              [34.1, 36.5, 37.8, 36.6, 35.0, 31.9, 28.1, 26.6],
                              [41.0, 41.3, 39.5, 37.8, 36.0, 32.6, 29.0, 26.0],
                              [45.8, 43.4, 41.9, 39.2, 36.9, 33.2, 29.6, 26.3],
                              [50.3, 46.9, 44.0, 40.0, 37.5, 33.8, 30.2, 27.3]]
        
        marketVolatilities = np.array(marketVolatilities) / 100.0

        # First dimension is the strike, then the expiry date
        marketStrikes = [[1.00, 1.25, 1.68, 2.00, 2.26, 2.41, 2.58, 2.62],
                         [1.50, 1.75, 2.18, 2.50, 2.76, 2.91, 3.08, 3.12],
                         [2.00, 2.25, 2.68, 3.00, 3.26, 3.41, 3.58, 3.62],
                         [2.50, 2.75, 3.18, 3.50, 3.76, 3.91, 4.08, 4.12],
                         [3.00, 3.25, 3.68, 4.00, 4.26, 4.41, 4.58, 4.62],
                         [3.50, 3.75, 4.18, 4.50, 4.76, 4.91, 5.08, 5.12],
                         [4.00, 4.25, 4.68, 5.00, 5.26, 5.41, 5.58, 5.62]]
        
        marketStrikes = np.array(marketStrikes) / 100.0
        
        fwdSwapRates = marketStrikes[3]
        atmVols = marketVolatilities[3]

        rfrRate = 0.020  # USD
        discount_curve = DiscountCurveFlat(valuation_date, rfrRate)

        divRate = 0.010  # USD
        dividendCurve = DiscountCurveFlat(valuation_date, divRate)

        volFunctionType = FinVolFunctionTypes.SABR_BETA_HALF

        swaptionSurface = FinSwaptionVolSurface(valuation_date,
                                                exerciseDates,
                                                fwdSwapRates,
                                                marketStrikes,
                                                marketVolatilities,
                                                volFunctionType)

        tol = 1e-4
        swaptionSurface.checkCalibration(False, tol)

        if 1==1: # PLOT_GRAPHS:

            swaptionSurface.plotVolCurves()
示例#19
0
def test_Bond():
    import pandas as pd
    path = os.path.join(os.path.dirname(__file__), './data/giltBondPrices.txt')
    bondDataFrame = pd.read_csv(path, sep='\t')
    bondDataFrame['mid'] = 0.5 * (bondDataFrame['bid'] + bondDataFrame['ask'])

    freq_type = FrequencyTypes.SEMI_ANNUAL
    settlement_date = Date(19, 9, 2012)
    face = ONE_MILLION

    for accrual_type in DayCountTypes:

        testCases.header("MATURITY", "COUPON", "CLEAN_PRICE", "ACCD_DAYS",
                         "ACCRUED", "YTM")

        for _, bond in bondDataFrame.iterrows():
            dateString = bond['maturity']
            matDatetime = dt.datetime.strptime(dateString, '%d-%b-%y')
            maturityDt = fromDatetime(matDatetime)
            issueDt = Date(maturityDt._d, maturityDt._m, 2000)

            coupon = bond['coupon'] / 100.0
            clean_price = bond['mid']
            bond = Bond(issueDt, maturityDt,
                        coupon, freq_type, accrual_type, 100)

            ytm = bond.yield_to_maturity(settlement_date, clean_price)
            accrued_interest= bond._accruedInterest
            accd_days = bond._accrued_days

            testCases.print("%18s" % maturityDt, "%8.4f" % coupon,
                            "%10.4f" % clean_price, "%6.0f" % accd_days,
                            "%10.4f" % accrued_interest, "%8.4f" % ytm)

    ###########################################################################
    #  EXAMPLE FROM http://bondtutor.com/btchp4/topic6/topic6.htm

    accrualConvention = DayCountTypes.ACT_ACT_ICMA
    y = 0.062267
    settlement_date = Date(19, 4, 1994)
    issue_date = Date(15, 7, 1990)
    maturity_date = Date(15, 7, 1997)
    coupon = 0.085
    face = ONE_MILLION
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issue_date, maturity_date,
                coupon, freq_type, accrualConvention, face)

    testCases.header("FIELD", "VALUE")
    full_price = bond.full_price_from_ytm(settlement_date, y)
    testCases.print("Full Price = ", full_price)
    clean_price = bond.clean_price_from_ytm(settlement_date, y)
    testCases.print("Clean Price = ", clean_price)
    accrued_interest= bond._accruedInterest
    testCases.print("Accrued = ", accrued_interest)
    ytm = bond.yield_to_maturity(settlement_date, clean_price)
    testCases.print("Yield to Maturity = ", ytm)

    bump = 1e-4
    priceBumpedUp = bond.full_price_from_ytm(settlement_date, y + bump)
    testCases.print("Price Bumped Up:", priceBumpedUp)

    priceBumpedDn = bond.full_price_from_ytm(settlement_date, y - bump)
    testCases.print("Price Bumped Dn:", priceBumpedDn)

    durationByBump = -(priceBumpedUp - full_price) / bump
    testCases.print("Duration by Bump = ", durationByBump)

    duration = bond.dollar_duration(settlement_date, y)
    testCases.print("Dollar Duration = ", duration)
    testCases.print("Duration Difference:", duration - durationByBump)

    modified_duration = bond.modified_duration(settlement_date, y)
    testCases.print("Modified Duration = ", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, y)
    testCases.print("Macauley Duration = ", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, y)
    testCases.print("Convexity = ", conv)

    # ASSET SWAP SPREAD

    # When the libor curve is the flat bond curve then the ASW is zero by
    # definition
    flatCurve = DiscountCurveFlat(settlement_date,
                                  ytm,
                                  FrequencyTypes.SEMI_ANNUAL)

    testCases.header("FIELD", "VALUE")

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    asw = bond.asset_swap_spread(settlement_date, clean_price, flatCurve)
    testCases.print("Discounted on Bond Curve ASW:", asw * 10000)

    # When the libor curve is the Libor curve then the ASW is positive
    libor_curve = buildIborCurve(settlement_date)
    asw = bond.asset_swap_spread(settlement_date, clean_price, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, clean_price, libor_curve)
    testCases.print("Discounted on LIBOR Curve ASW:", asw * 10000)
    testCases.print("Discounted on LIBOR Curve OAS:", oas * 10000)

    p = 90.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Deep discount bond at 90 ASW:", asw * 10000)
    testCases.print("Deep discount bond at 90 OAS:", oas * 10000)

    p = 100.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Par bond at 100 ASW:", asw * 10000)
    testCases.print("Par bond at 100 OAS:", oas * 10000)

    p = 120.0
    asw = bond.asset_swap_spread(settlement_date, p, libor_curve)
    oas = bond.option_adjusted_spread(settlement_date, p, libor_curve)
    testCases.print("Above par bond at 120 ASW:", asw * 10000)
    testCases.print("Above par bond at 120 OAS:", oas * 10000)

    ##########################################################################
    # https://data.bloomberglp.com/bat/sites/3/2017/07/SF-2017_Paul-Fjeldsted.pdf
    # Page 10 TREASURY NOTE SCREENSHOT
    ##########################################################################

    testCases.banner("BLOOMBERG US TREASURY EXAMPLE")
    settlement_date = Date(21, 7, 2017)
    issue_date = Date(15, 5, 2010)
    maturity_date = Date(15, 5, 2027)
    coupon = 0.02375
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    face = 100.0

    bond = Bond(issue_date,
                maturity_date,
                coupon,
                freq_type,
                accrual_type,
                face)

    testCases.header("FIELD", "VALUE")
    clean_price = 99.7808417

    yld = bond.current_yield(clean_price)
    testCases.print("Current Yield = ", yld)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.UK_DMO)
    testCases.print("UK DMO Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_STREET)
    testCases.print("US STREET Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_TREASURY)
    testCases.print("US TREASURY Yield To Maturity = ", ytm)

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    testCases.print("Full Price = ", full_price)

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    testCases.print("Clean Price = ", clean_price)

    accrued_interest= bond._accruedInterest
    testCases.print("Accrued = ", accrued_interest)

    accddays = bond._accrued_days
    testCases.print("Accrued Days = ", accddays)

    duration = bond.dollar_duration(settlement_date, ytm)
    testCases.print("Dollar Duration = ", duration)

    modified_duration = bond.modified_duration(settlement_date, ytm)
    testCases.print("Modified Duration = ", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    testCases.print("Macauley Duration = ", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    testCases.print("Convexity = ", conv)

    ##########################################################################
    # Page 11 APPLE NOTE SCREENSHOT
    ##########################################################################

    testCases.banner("BLOOMBERG APPLE CORP BOND EXAMPLE")
    settlement_date = Date(21, 7, 2017)
    issue_date = Date(13, 5, 2012)
    maturity_date = Date(13, 5, 2022)
    coupon = 0.027
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.THIRTY_E_360_ISDA
    face = 100.0

    bond = Bond(issue_date, maturity_date,
                coupon, freq_type, accrual_type, face)

    testCases.header("FIELD", "VALUE")
    clean_price = 101.581564

    yld = bond.current_yield(clean_price)
    testCases.print("Current Yield", yld)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.UK_DMO)
    testCases.print("UK DMO Yield To Maturity", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_STREET)
    testCases.print("US STREET Yield To Maturity", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_TREASURY)
    testCases.print("US TREASURY Yield To Maturity", ytm)

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    testCases.print("Full Price", full_price)

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    testCases.print("Clean Price", clean_price)

    accddays = bond._accrued_days
    testCases.print("Accrued Days", accddays)

    accrued_interest= bond._accruedInterest
    testCases.print("Accrued", accrued_interest)

    duration = bond.dollar_duration(settlement_date, ytm)
    testCases.print("Dollar Duration", duration)

    modified_duration = bond.modified_duration(settlement_date, ytm)
    testCases.print("Modified Duration", modified_duration)

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    testCases.print("Macauley Duration", macauley_duration)

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    testCases.print("Convexity", conv)
def test_FinBinomialTree():

    stock_price = 50.0
    riskFreeRate = 0.06
    dividendYield = 0.04
    volatility = 0.40

    valuation_date = Date(1, 1, 2016)
    expiry_date = Date(1, 1, 2017)

    model = FinModelBlackScholes(volatility)
    discount_curve = DiscountCurveFlat(valuation_date, riskFreeRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

    num_stepsList = [100, 500, 1000, 2000, 5000]

    strikePrice = 50.0

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

    putOption = FinEquityVanillaOption(expiry_date, strikePrice,
                                       FinOptionTypes.EUROPEAN_PUT)
    value = putOption.value(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    delta = putOption.delta(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    gamma = putOption.gamma(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    theta = putOption.theta(valuation_date, stock_price, discount_curve,
                            dividendCurve, model)
    testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta")
    testCases.print(value, delta, gamma, theta)

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.EUROPEAN
    params = np.array([-1, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")

    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()
        results = tree.value(stock_price, discount_curve, dividendCurve,
                             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 = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.AMERICAN
    params = np.array([-1, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")

    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()
        results = tree.value(stock_price, discount_curve, dividendCurve,
                             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 =======================")

    callOption = FinEquityVanillaOption(expiry_date, strikePrice,
                                        FinOptionTypes.EUROPEAN_CALL)
    value = callOption.value(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    delta = callOption.delta(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    gamma = callOption.gamma(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    theta = callOption.theta(valuation_date, stock_price, discount_curve,
                             dividendCurve, model)
    testCases.header("BS Value", "BS Delta", "BS Gamma", "BS Theta")
    testCases.print(value, delta, gamma, theta)

    payoff = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.EUROPEAN
    params = np.array([1.0, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")
    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()

        results = tree.value(stock_price, discount_curve, dividendCurve,
                             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 = FinEquityTreePayoffTypes.VANILLA_OPTION
    exercise = FinEquityTreeExerciseTypes.AMERICAN
    params = np.array([1.0, strikePrice])

    testCases.header("NumSteps", "Results", "TIME")
    for num_steps in num_stepsList:
        start = time.time()
        tree = FinEquityBinomialTree()

        results = tree.value(stock_price, discount_curve, dividendCurve,
                             volatility, num_steps, valuation_date, payoff,
                             expiry_date, payoff, exercise, params)

        end = time.time()
        duration = end - start
        testCases.print(num_steps, results, duration)
def test_FinIborBermudanSwaptionBKModel():
    """ Replicate examples in paper by Leif Andersen which can be found at
    file:///C:/Users/Dominic/Downloads/SSRN-id155208.pdf """

    valuation_date = Date(1, 1, 2011)
    settlement_date = valuation_date
    exerciseDate = settlement_date.addYears(1)
    swapMaturityDate = settlement_date.addYears(4)

    swapFixedCoupon = 0.060
    swapFixedFrequencyType = FrequencyTypes.SEMI_ANNUAL
    swapFixedDayCountType = DayCountTypes.ACT_365F

    libor_curve = DiscountCurveFlat(valuation_date, 0.0625,
                                    FrequencyTypes.SEMI_ANNUAL,
                                    DayCountTypes.ACT_365F)

    fwdPAYSwap = FinIborSwap(exerciseDate, swapMaturityDate, FinSwapTypes.PAY,
                             swapFixedCoupon, swapFixedFrequencyType,
                             swapFixedDayCountType)

    fwdSwapValue = fwdPAYSwap.value(settlement_date, libor_curve, libor_curve)

    testCases.header("LABEL", "VALUE")
    testCases.print("FWD SWAP VALUE", fwdSwapValue)

    # fwdPAYSwap.printFixedLegPV()

    # Now we create the European swaptions
    fixed_legType = FinSwapTypes.PAY
    europeanSwaptionPay = FinIborSwaption(settlement_date, exerciseDate,
                                          swapMaturityDate, fixed_legType,
                                          swapFixedCoupon,
                                          swapFixedFrequencyType,
                                          swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    europeanSwaptionRec = FinIborSwaption(settlement_date, exerciseDate,
                                          swapMaturityDate, fixed_legType,
                                          swapFixedCoupon,
                                          swapFixedFrequencyType,
                                          swapFixedDayCountType)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BLACK'S MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("======= ZERO VOLATILITY ========")
    model = FinModelBlack(0.0000001)
    testCases.print("Black Model", model._volatility)

    valuePay = europeanSwaptionPay.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK PAY VALUE ZERO VOL:", valuePay)

    valueRec = europeanSwaptionRec.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK REC VALUE ZERO VOL:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("======= 20%% BLACK VOLATILITY ========")

    model = FinModelBlack(0.20)
    testCases.print("Black Model", model._volatility)

    valuePay = europeanSwaptionPay.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(settlement_date, libor_curve, model)
    testCases.print("EUROPEAN BLACK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BK MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("==================== BK MODEL =========================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("======= 0% VOLATILITY EUROPEAN SWAPTION BK MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.000000001
    a = 0.01
    numTimeSteps = 100
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY EUROPEAN SWAPTION BK MODEL ========")

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.EUROPEAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    exerciseType = FinExerciseTypes.EUROPEAN

    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.2
    a = 0.01
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.BERMUDAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    exerciseType = FinExerciseTypes.BERMUDAN

    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BK MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = FinModelRatesBK(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BK REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BDT MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("======================= BDT MODEL =====================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("====== 0% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.00001
    numTimeSteps = 200
    model = FinModelRatesBDT(sigma, numTimeSteps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("===== 20% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = FinModelRatesBDT(sigma, numTimeSteps)

    testCases.banner("BDT MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.EUROPEAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    model = FinModelRatesBDT(sigma, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.2
    model = FinModelRatesBDT(sigma, numTimeSteps)

    testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.BERMUDAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = FinModelRatesBDT(sigma, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 20% VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE BDT MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.20
    a = 0.01
    model = FinModelRatesBDT(sigma, numTimeSteps)

    #    print("BDT MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    ###########################################################################
    ###########################################################################
    # BDT MODEL
    ###########################################################################
    ###########################################################################
    ###########################################################################

    testCases.banner("=======================================================")
    testCases.banner("=======================================================")
    testCases.banner("======================= HW MODEL ======================")
    testCases.banner("=======================================================")
    testCases.banner("=======================================================")

    testCases.banner("====== 0% VOLATILITY EUROPEAN SWAPTION HW MODEL ======")

    sigma = 0.0000001
    a = 0.1
    numTimeSteps = 200
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner("===== 20% VOLATILITY EUROPEAN SWAPTION BDT MODEL ======")

    # Used BK with constant short-rate volatility
    sigma = 0.01
    a = 0.01
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    testCases.banner("HW MODEL SWAPTION CLASS EUROPEAN EXERCISE")

    valuePay = europeanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW PAY VALUE:", valuePay)

    valueRec = europeanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("EUROPEAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

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

    # Now we create the Bermudan swaptions but only allow European exercise
    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.EUROPEAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= 0% VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE HW MODEL ========"
    )

    sigma = 0.000001
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    testCases.banner("BK MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 100bp VOLATILITY BERMUDAN SWAPTION EUROPEAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.01
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    testCases.banner("BDT MODEL BERMUDAN SWAPTION CLASS EUROPEAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN BDT REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    ###########################################################################
    # Now we create the Bermudan swaptions but allow Bermudan exercise
    ###########################################################################

    fixed_legType = FinSwapTypes.PAY
    exerciseType = FinExerciseTypes.BERMUDAN

    bermudanSwaptionPay = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    fixed_legType = FinSwapTypes.RECEIVE
    bermudanSwaptionRec = FinIborBermudanSwaption(
        settlement_date, exerciseDate, swapMaturityDate, fixed_legType,
        exerciseType, swapFixedCoupon, swapFixedFrequencyType,
        swapFixedDayCountType)

    testCases.banner(
        "======= ZERO VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.000001
    a = 0.01
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)

    testCases.banner(
        "======= 100bps VOLATILITY BERMUDAN SWAPTION BERMUDAN EXERCISE HW MODEL ========"
    )

    # Used BK with constant short-rate volatility
    sigma = 0.01
    a = 0.01
    model = FinModelRatesHW(sigma, a, numTimeSteps)

    testCases.banner("HW MODEL BERMUDAN SWAPTION CLASS BERMUDAN EXERCISE")
    valuePay = bermudanSwaptionPay.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW PAY VALUE:", valuePay)

    valueRec = bermudanSwaptionRec.value(valuation_date, libor_curve, model)
    testCases.print("BERMUDAN HW REC VALUE:", valueRec)

    payRec = valuePay - valueRec
    testCases.print("PAY MINUS RECEIVER :", payRec)
示例#22
0
def test_FinEquityRainbowOption():

    #        import matplotlib.pyplot as plt

    valuation_date = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    interestRate = 0.05

    discount_curve = DiscountCurveFlat(valuation_date, interestRate)

    numAssets = 2
    volatilities = np.ones(numAssets) * 0.3

    dividend_yields = np.ones(numAssets) * 0.01

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

    stock_prices = np.ones(numAssets) * 100
    num_pathsList = [10000]
    corrList = np.linspace(0.0, 0.999999, 6)
    strike = 100.0

    testCases.banner(
        "===================================================================")
    testCases.banner("                      CALL ON MAXIMUM")
    testCases.banner(
        "===================================================================")

    payoffType = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM
    payoffParams = [strike]
    rainbowOption = FinEquityRainbowOption(expiry_date, payoffType,
                                           payoffParams, numAssets)

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            start = time.time()
            v = rainbowOption.value(valuation_date, stock_prices,
                                    discount_curve, dividendCurves,
                                    volatilities, corrMatrix)

            v_MC = rainbowOption.valueMC(valuation_date, stock_prices,
                                         discount_curve, dividendCurves,
                                         volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MAX Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

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

    testCases.banner(
        "===================================================================")
    testCases.banner("                       CALL ON MINIMUM")
    testCases.banner(
        "===================================================================")
    payoffType = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM
    payoffParams = [strike]
    rainbowOption = FinEquityRainbowOption(expiry_date, payoffType,
                                           payoffParams, numAssets)

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            start = time.time()

            v = rainbowOption.value(valuation_date, stock_prices,
                                    discount_curve, dividendCurves,
                                    volatilities, corrMatrix)

            v_MC = rainbowOption.valueMC(valuation_date, stock_prices,
                                         discount_curve, dividendCurves,
                                         volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON MIN Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

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

    testCases.banner(
        "===================================================================")
    testCases.banner("                      PUT ON MAXIMUM")
    testCases.banner(
        "===================================================================")

    payoffType = FinEquityRainbowOptionTypes.PUT_ON_MAXIMUM
    payoffParams = [strike]
    rainbowOption = FinEquityRainbowOption(expiry_date, payoffType,
                                           payoffParams, numAssets)

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            start = time.time()

            v = rainbowOption.value(valuation_date, stock_prices,
                                    discount_curve, dividendCurves,
                                    volatilities, corrMatrix)

            v_MC = rainbowOption.valueMC(valuation_date, stock_prices,
                                         discount_curve, dividendCurves,
                                         volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MAX Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MAX Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

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

    testCases.banner(
        "===================================================================")
    testCases.banner("                       PUT ON MINIMUM")
    testCases.banner(
        "===================================================================")
    payoffType = FinEquityRainbowOptionTypes.PUT_ON_MINIMUM
    payoffParams = [strike]
    rainbowOption = FinEquityRainbowOption(expiry_date, payoffType,
                                           payoffParams, numAssets)

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            start = time.time()
            v = rainbowOption.value(valuation_date, stock_prices,
                                    discount_curve, dividendCurves,
                                    volatilities, corrMatrix)
            v_MC = rainbowOption.valueMC(valuation_date, stock_prices,
                                         discount_curve, dividendCurves,
                                         volatilities, corrMatrix, num_paths)
            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "PUT ON MIN Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "PUT ON MIN Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

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

    numAssets = 2
    volatilities = np.ones(numAssets) * 0.3
    dividend_yields = np.ones(numAssets) * 0.01
    stock_prices = np.ones(numAssets) * 100
    strike = 100.0
    correlation = 0.50

    testCases.banner(
        "===================================================================")
    testCases.banner("                      CALL ON 1st")
    testCases.banner(
        "===================================================================")

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MAXIMUM
            payoffParams1 = [strike]
            rainbowOption1 = FinEquityRainbowOption(expiry_date, payoffType1,
                                                    payoffParams1, numAssets)

            payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH
            payoffParams2 = [1, strike]
            rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2,
                                                    payoffParams2, numAssets)

            start = time.time()

            v = rainbowOption1.value(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix)

            v_MC = rainbowOption2.valueMC(valuation_date, stock_prices,
                                          discount_curve, dividendCurves,
                                          volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MAX Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 1st Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

    testCases.banner(
        "===================================================================")
    testCases.banner("                      CALL ON 2nd")
    testCases.banner(
        "===================================================================")

    rainboxOptionValues = []
    rainbowOptionValuesMC = []

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

    for correlation in corrList:

        betas = np.ones(numAssets) * sqrt(correlation)
        corrMatrix = betaVectorToCorrMatrix(betas)

        for num_paths in num_pathsList:

            payoffType1 = FinEquityRainbowOptionTypes.CALL_ON_MINIMUM
            payoffParams1 = [strike]
            rainbowOption1 = FinEquityRainbowOption(expiry_date, payoffType1,
                                                    payoffParams1, numAssets)

            payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH
            payoffParams2 = [2, strike]
            rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2,
                                                    payoffParams2, numAssets)

            start = time.time()

            v = rainbowOption1.value(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix)

            v_MC = rainbowOption2.valueMC(valuation_date, stock_prices,
                                          discount_curve, dividendCurves,
                                          volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, v, v_MC, duration)

            rainboxOptionValues.append(v)
            rainbowOptionValuesMC.append(v_MC)

#    plt.figure(figsize=(10,8))
#    plt.plot(corrList, rainboxOptionValues, color = 'r', label = "CALL ON MIN Rainbow Option Analytical")
#    plt.plot(corrList, rainbowOptionValuesMC, 'o', color = 'b', label = "CALL ON 2nd Rainbow Option MC")
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

    testCases.banner(
        "===================================================================")
    testCases.banner("                      CALL ON 1-5")
    testCases.banner(
        "===================================================================")

    rainboxOptionValues = []
    rainbowOptionValuesMC = []
    num_paths = 10000
    numAssets = 5
    volatilities = np.ones(numAssets) * 0.3
    dividend_yields = np.ones(numAssets) * 0.01
    stock_prices = np.ones(numAssets) * 100

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

#    plt.figure(figsize=(10,8))

    testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC",
                     "TIME")

    for n in [1, 2, 3, 4, 5]:

        rainboxOptionValues = []
        rainbowOptionValuesMC = []

        payoffType2 = FinEquityRainbowOptionTypes.CALL_ON_NTH
        payoffParams2 = [n, strike]
        rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2,
                                                payoffParams2, numAssets)

        for correlation in corrList:

            betas = np.ones(numAssets) * sqrt(correlation)
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()

            v_MC = rainbowOption2.valueMC(valuation_date, stock_prices,
                                          discount_curve, dividendCurves,
                                          volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, n, v, v_MC, duration)

            rainbowOptionValuesMC.append(v_MC)

#        plt.plot(corrList, rainbowOptionValuesMC, 'o-', label = "CALL Rainbow Option MC NTH = " + str(n))
#    plt.xlabel("Correlation")
#    plt.legend(loc='best')

    testCases.banner(
        "===================================================================")
    testCases.banner("                      PUT ON 1-5")
    testCases.banner(
        "===================================================================")

    rainboxOptionValues = []
    rainbowOptionValuesMC = []
    num_paths = 10000
    numAssets = 5
    volatilities = np.ones(numAssets) * 0.3
    dividend_yields = np.ones(numAssets) * 0.01
    stock_prices = np.ones(numAssets) * 100

    #    plt.figure(figsize=(10,8))

    testCases.header("NUMPATHS", "CORRELATION", "NTD", "VALUE", "VALUE_MC",
                     "TIME")

    for n in [1, 2, 3, 4, 5]:

        rainboxOptionValues = []
        rainbowOptionValuesMC = []

        payoffType2 = FinEquityRainbowOptionTypes.PUT_ON_NTH
        payoffParams2 = [n, strike]
        rainbowOption2 = FinEquityRainbowOption(expiry_date, payoffType2,
                                                payoffParams2, numAssets)

        for correlation in corrList:

            betas = np.ones(numAssets) * sqrt(correlation)
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()

            v_MC = rainbowOption2.valueMC(valuation_date, stock_prices,
                                          discount_curve, dividendCurves,
                                          volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, correlation, n, v, v_MC, duration)

            rainbowOptionValuesMC.append(v_MC)
示例#23
0
def test_FinFXVanillaOptionHullExample():

    #   Example from Hull 4th edition page 284
    valuation_date = Date(1, 1, 2015)
    expiry_date = valuation_date.addMonths(4)
    spotFXRate = 1.60
    volatility = 0.1411
    domInterestRate = 0.08
    forInterestRate = 0.11
    model = FinModelBlackScholes(volatility)
    domDiscountCurve = DiscountCurveFlat(valuation_date, domInterestRate)
    forDiscountCurve = DiscountCurveFlat(valuation_date, forInterestRate)

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

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

    for num_paths in num_pathsList:

        callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                        FinOptionTypes.EUROPEAN_CALL, 1000000,
                                        "USD")

        value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)

        start = time.time()

        valueMC = callOption.valueMC(valuation_date, spotFXRate,
                                     domDiscountCurve, forDiscountCurve, model,
                                     num_paths)

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

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

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

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

    for spotFXRate in spotFXRates:

        callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                        FinOptionTypes.EUROPEAN_CALL, 1000000,
                                        "USD")

        value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)
        start = time.time()
        valueMC = callOption.valueMC(valuation_date, spotFXRate,
                                     domDiscountCurve, forDiscountCurve, model,
                                     num_paths)
        end = time.time()
        duration = end - start
        testCases.print(num_paths, value, valueMC, duration)

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

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

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

    for spotFXRate in spotFXRates:

        putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                       FinOptionTypes.EUROPEAN_PUT, 1000000,
                                       "USD")

        value = putOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                forDiscountCurve, model)
        start = time.time()
        valueMC = putOption.valueMC(valuation_date, spotFXRate,
                                    domDiscountCurve, forDiscountCurve, model,
                                    num_paths)
        end = time.time()
        duration = end - start
        testCases.print(spotFXRate, value, valueMC, duration)

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

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

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

    for spotFXRate in spotFXRates:
        callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                        FinOptionTypes.EUROPEAN_CALL, 1000000,
                                        "USD")
        value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)
        delta = callOption.delta(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)
        vega = callOption.vega(valuation_date, spotFXRate, domDiscountCurve,
                               forDiscountCurve, model)
        theta = callOption.theta(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)
        #  callOption.rho(valuation_date,stock_price, interestRate,
        #  dividendYield, modelType, modelParams)
        rho = 999
        testCases.print(spotFXRate, value, delta, vega, theta, rho)

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

    for spotFXRate in spotFXRates:
        putOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                       FinOptionTypes.EUROPEAN_PUT, 1000000,
                                       "USD")

        value = putOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                forDiscountCurve, model)
        delta = putOption.delta(valuation_date, spotFXRate, domDiscountCurve,
                                forDiscountCurve, model)
        vega = putOption.vega(valuation_date, spotFXRate, domDiscountCurve,
                              forDiscountCurve, model)
        theta = putOption.theta(valuation_date, spotFXRate, domDiscountCurve,
                                forDiscountCurve, model)
        # putOption.rho(valuation_date,stock_price, interestRate, dividendYield,
        # modelType, modelParams)
        rho = 999
        testCases.print(spotFXRate, value, delta, vega, theta, rho)

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

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

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

    for spotFXRate in spotFXRates:
        callOption = FinFXVanillaOption(expiry_date, strikeFXRate, "EURUSD",
                                        FinOptionTypes.EUROPEAN_CALL, 1000000,
                                        "USD")

        value = callOption.value(valuation_date, spotFXRate, domDiscountCurve,
                                 forDiscountCurve, model)['v']

        impliedVol = callOption.impliedVolatility(valuation_date, spotFXRate,
                                                  domDiscountCurve,
                                                  forDiscountCurve, value)

        testCases.print(spotFXRate, value, volatility, impliedVol)
def test_FinEquityVolSurface(verboseCalibration):

    valuation_date = Date(11, 1, 2021)

    stock_price = 3800.0  # Check

    expiry_dates = [
        Date(11, 2, 2021),
        Date(11, 3, 2021),
        Date(11, 4, 2021),
        Date(11, 7, 2021),
        Date(11, 10, 2021),
        Date(11, 1, 2022),
        Date(11, 1, 2023)
    ]

    strikes = np.array([3037, 3418, 3608, 3703, 3798, 3893, 3988, 4178, 4557])

    volSurface = [
        [42.94, 31.30, 25.88, 22.94, 19.72, 16.90, 15.31, 17.54, 25.67],
        [37.01, 28.25, 24.19, 21.93, 19.57, 17.45, 15.89, 15.34, 21.15],
        [34.68, 27.38, 23.82, 21.85, 19.83, 17.98, 16.52, 15.31, 18.94],
        [31.41, 26.25, 23.51, 22.05, 20.61, 19.25, 18.03, 16.01, 15.90],
        [29.91, 25.58, 23.21, 22.01, 20.83, 19.70, 18.62, 16.63, 14.94],
        [29.26, 25.24, 23.03, 21.91, 20.81, 19.73, 18.69, 16.76, 14.63],
        [27.59, 24.33, 22.72, 21.93, 21.17, 20.43, 19.71, 18.36, 16.26]
    ]

    volSurface = np.array(volSurface)
    volSurface = volSurface / 100.0

    r = 0.020  # USD
    discount_curve = DiscountCurveFlat(valuation_date, r)

    q = 0.010  # USD
    dividendCurve = DiscountCurveFlat(valuation_date, q)

    volFunctionType = FinVolFunctionTypes.SVI

    equitySurface = FinEquityVolSurface(valuation_date, stock_price,
                                        discount_curve, dividendCurve,
                                        expiry_dates, strikes, volSurface,
                                        volFunctionType)

    #    tol = 1e-4
    #    equitySurface.checkCalibration(False, tol)

    if 1 == 0:  # PLOT_GRAPHS:

        equitySurface.plotVolCurves()

        plt.figure()

        mins = strikes[0] * 0.5
        maxs = strikes[-1] * 1.5

        dbns = equitySurface.impliedDbns(mins, maxs, 1000)

        for i in range(0, len(dbns)):
            expiry_dateStr = str(equitySurface._expiry_dates[i])
            plt.plot(dbns[i]._x, dbns[i]._densitydx, label=expiry_dateStr)
            plt.title(volFunctionType)
            plt.legend()
            print("SUM:", dbns[i].sum())

    deltas = np.linspace(0.10, 0.90, 9)

    testCases.header("EXPIRY", "DELTA", "VOL", "STRIKE")
    for expiry_date in expiry_dates:
        for delta in deltas:
            vol = equitySurface.volatilityFromDeltaDate(delta, expiry_date)
            testCases.print(expiry_date, delta, vol[0], vol[1])
def test_FinEquityBasketOption():

    import time

    valuation_date = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    volatility = 0.30
    interestRate = 0.05
    discount_curve = DiscountCurveFlat(valuation_date, interestRate)

    ##########################################################################
    # Homogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.ones(numAssets) * volatility
    dividend_yields = np.ones(numAssets) * 0.01
    stock_prices = np.ones(numAssets) * 100

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:
        for num_paths in [10000]:
            callOption = FinEquityBasketOption(expiry_date, 100.0,
                                               FinOptionTypes.EUROPEAN_CALL,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valuation_date, stock_prices, discount_curve,
                                 dividendCurves, volatilities, corrMatrix)

            vMC = callOption.valueMC(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix, num_paths)
            end = time.time()
            duration = end - start
            testCases.print(num_paths, beta, v, vMC, duration)

    ##########################################################################
    # INHomogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4])
    dividend_yields = np.array([0.01, 0.02, 0.04, 0.01, 0.02])
    stock_prices = np.array([100, 105, 120, 100, 90])

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:

        for num_paths in [10000]:

            callOption = FinEquityBasketOption(expiry_date, 100.0,
                                               FinOptionTypes.EUROPEAN_CALL,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()

            v = callOption.value(valuation_date, stock_prices, discount_curve,
                                 dividendCurves, volatilities, corrMatrix)

            vMC = callOption.valueMC(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix, num_paths)

            end = time.time()
            duration = end - start
            testCases.print(num_paths, beta, v, vMC, duration)

    ##########################################################################
    # Homogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.ones(numAssets) * volatility
    dividend_yields = np.ones(numAssets) * 0.01
    stock_prices = np.ones(numAssets) * 100
    betaList = np.linspace(0.0, 0.999999, 11)

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:
        for num_paths in [10000]:
            callOption = FinEquityBasketOption(expiry_date, 100.0,
                                               FinOptionTypes.EUROPEAN_PUT,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valuation_date, stock_prices, discount_curve,
                                 dividendCurves, volatilities, corrMatrix)
            vMC = callOption.valueMC(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix, num_paths)
            end = time.time()
            duration = end - start
            testCases.print(num_paths, beta, v, vMC, duration)

    ##########################################################################
    # INHomogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4])
    dividend_yields = np.array([0.01, 0.02, 0.04, 0.01, 0.02])
    stock_prices = np.array([100, 105, 120, 100, 90])
    betaList = np.linspace(0.0, 0.999999, 11)

    dividendCurves = []
    for q in dividend_yields:
        dividendCurve = DiscountCurveFlat(valuation_date, q)
        dividendCurves.append(dividendCurve)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:

        for num_paths in [10000]:

            callOption = FinEquityBasketOption(expiry_date, 100.0,
                                               FinOptionTypes.EUROPEAN_PUT,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valuation_date, stock_prices, discount_curve,
                                 dividendCurves, volatilities, corrMatrix)
            vMC = callOption.valueMC(valuation_date, stock_prices,
                                     discount_curve, dividendCurves,
                                     volatilities, corrMatrix, num_paths)
            end = time.time()
            duration = end - start
            testCases.print(num_paths, beta, v, vMC, duration)
示例#26
0
def testFinModelBlackScholes():

    valuation_date = Date(8, 5, 2015)
    expiry_date = Date(15, 1, 2016)

    strikePrice = 130.0
    stock_price = 127.62
    volatility = 0.20
    interestRate = 0.001
    dividendYield = 0.0163

    optionType = FinOptionTypes.AMERICAN_CALL
    euOptionType = FinOptionTypes.EUROPEAN_CALL

    amOption = FinEquityAmericanOption(expiry_date, strikePrice, optionType)

    ameuOption = FinEquityAmericanOption(expiry_date, strikePrice,
                                         euOptionType)

    euOption = FinEquityVanillaOption(expiry_date, strikePrice, euOptionType)

    discount_curve = DiscountCurveFlat(valuation_date, interestRate,
                                       FrequencyTypes.CONTINUOUS,
                                       DayCountTypes.ACT_365F)

    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield,
                                      FrequencyTypes.CONTINUOUS,
                                      DayCountTypes.ACT_365F)

    num_steps_per_year = 400

    modelTree = FinModelBlackScholes(volatility,
                                     FinModelBlackScholesTypes.CRR_TREE,
                                     num_steps_per_year)

    v = amOption.value(valuation_date, stock_price, discount_curve,
                       dividendCurve, modelTree)
    #    print(v)

    modelApprox = FinModelBlackScholes(volatility,
                                       FinModelBlackScholesTypes.BARONE_ADESI)

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

    #    print(v)

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

    #    print(v)

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

    #    print(v)

    amTreeValue = []
    amBAWValue = []
    euTreeValue = []
    euAnalValue = []
    volatility = 0.20
示例#27
0
def test_BondOptionZEROVOLConvergence():

    # Build discount curve
    settlement_date = Date(1, 9, 2019)
    rate = 0.05
    discount_curve = DiscountCurveFlat(settlement_date, rate,
                                       FrequencyTypes.ANNUAL)

    # Bond details
    issue_date = Date(1, 9, 2014)
    maturity_date = Date(1, 9, 2025)
    coupon = 0.06
    freq_type = FrequencyTypes.ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    # Option Details
    expiry_date = Date(1, 12, 2021)
    face = 100.0

    dfExpiry = discount_curve.df(expiry_date)
    fwdCleanValue = bond.clean_price_from_discount_curve(
        expiry_date, discount_curve)
    #    fwdFullValue = bond.full_price_from_discount_curve(expiry_date, discount_curve)
    #    print("BOND FwdCleanBondPx", fwdCleanValue)
    #    print("BOND FwdFullBondPx", fwdFullValue)
    #    print("BOND Accrued:", bond._accruedInterest)

    spotCleanValue = bond.clean_price_from_discount_curve(
        settlement_date, discount_curve)

    testCases.header("STRIKE", "STEPS", "CALL_INT", "CALL_INT_PV", "CALL_EUR",
                     "CALL_AMER", "PUT_INT", "PUT_INT_PV", "PUT_EUR",
                     "PUT_AMER")

    numTimeSteps = range(100, 1000, 100)
    strikePrices = [90, 100, 110, 120]

    for strikePrice in strikePrices:

        callIntrinsic = max(spotCleanValue - strikePrice, 0)
        putIntrinsic = max(strikePrice - spotCleanValue, 0)
        callIntrinsicPV = max(fwdCleanValue - strikePrice, 0) * dfExpiry
        putIntrinsicPV = max(strikePrice - fwdCleanValue, 0) * dfExpiry

        for num_steps in numTimeSteps:

            sigma = 0.0000001
            a = 0.1
            model = FinModelRatesHW(sigma, a, num_steps)

            optionType = FinOptionTypes.EUROPEAN_CALL
            bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v1 = bondOption1.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.AMERICAN_CALL
            bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v2 = bondOption2.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.EUROPEAN_PUT
            bondOption3 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v3 = bondOption3.value(settlement_date, discount_curve, model)

            optionType = FinOptionTypes.AMERICAN_PUT
            bondOption4 = BondOption(bond, expiry_date, strikePrice, face,
                                     optionType)
            v4 = bondOption4.value(settlement_date, discount_curve, model)

            testCases.print(strikePrice, num_steps, callIntrinsic,
                            callIntrinsicPV, v1, v2, putIntrinsic,
                            putIntrinsicPV, v3, v4)
示例#28
0
def test_BondOptionAmericanConvergenceTWO():

    # Build discount curve
    settlement_date = Date(1, 12, 2019)
    discount_curve = DiscountCurveFlat(settlement_date, 0.05)

    # Bond details
    issue_date = Date(1, 12, 2015)
    maturity_date = settlement_date.addTenor("10Y")
    coupon = 0.05
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)
    expiry_date = settlement_date.addTenor("18m")
    face = 100.0

    spotValue = bond.clean_price_from_discount_curve(settlement_date,
                                                     discount_curve)
    testCases.header("LABEL", "VALUE")
    testCases.print("BOND PRICE", spotValue)

    testCases.header("TIME", "N", "EUR_CALL", "AMER_CALL", "EUR_PUT",
                     "AMER_PUT")

    sigma = 0.01
    a = 0.1
    hwModel = FinModelRatesHW(sigma, a)
    K = 102.0

    vec_ec = []
    vec_ac = []
    vec_ep = []
    vec_ap = []

    num_stepsVector = range(100, 500, 100)

    for num_steps in num_stepsVector:
        hwModel = FinModelRatesHW(sigma, a, num_steps)

        start = time.time()

        europeanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            FinOptionTypes.EUROPEAN_CALL)

        v_ec = europeanCallBondOption.value(settlement_date, discount_curve,
                                            hwModel)

        americanCallBondOption = BondOption(bond, expiry_date, K, face,
                                            FinOptionTypes.AMERICAN_CALL)

        v_ac = americanCallBondOption.value(settlement_date, discount_curve,
                                            hwModel)

        europeanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           FinOptionTypes.EUROPEAN_PUT)

        v_ep = europeanPutBondOption.value(settlement_date, discount_curve,
                                           hwModel)

        americanPutBondOption = BondOption(bond, expiry_date, K, face,
                                           FinOptionTypes.AMERICAN_PUT)

        v_ap = americanPutBondOption.value(settlement_date, discount_curve,
                                           hwModel)

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

        testCases.print(period, num_steps, v_ec, v_ac, v_ep, v_ap)

        vec_ec.append(v_ec)
        vec_ac.append(v_ac)
        vec_ep.append(v_ep)
        vec_ap.append(v_ap)

    if plotGraphs:
        plt.figure()
        plt.plot(num_stepsVector, vec_ac, label="American Call")
        plt.legend()

        plt.figure()
        plt.plot(num_stepsVector, vec_ap, label="American Put")
        plt.legend()
示例#29
0
def test_BondOptionEuropeanConvergence():

    # CONVERGENCE TESTS
    # COMPARE AMERICAN TREE VERSUS JAMSHIDIAN IN EUROPEAN LIMIT TO CHECK THAT
    # TREE HAS BEEN CORRECTLY CONSTRUCTED. FIND VERY GOOD AGREEMENT.

    # Build discount curve
    settlement_date = Date(1, 12, 2019)
    discount_curve = DiscountCurveFlat(settlement_date, 0.05,
                                       FrequencyTypes.CONTINUOUS)

    # Bond details
    issue_date = Date(1, 12, 2015)
    maturity_date = Date(1, 12, 2020)
    coupon = 0.05
    freq_type = FrequencyTypes.ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    # Option Details - put expiry in the middle of a coupon period
    expiry_date = Date(1, 3, 2020)
    strikePrice = 100.0
    face = 100.0

    timeSteps = range(100, 400, 100)
    strikePrice = 100.0

    testCases.header("TIME", "N", "PUT_JAM", "PUT_TREE", "CALL_JAM",
                     "CALL_TREE")

    for numTimeSteps in timeSteps:

        sigma = 0.05
        a = 0.1

        start = time.time()
        optionType = FinOptionTypes.EUROPEAN_PUT

        bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)
        model1 = FinModelRatesHW(sigma, a, numTimeSteps)
        v1put = bondOption1.value(settlement_date, discount_curve, model1)

        bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)

        model2 = FinModelRatesHW(sigma, a, numTimeSteps,
                                 FinHWEuropeanCalcType.EXPIRY_ONLY)
        v2put = bondOption2.value(settlement_date, discount_curve, model2)

        optionType = FinOptionTypes.EUROPEAN_CALL

        bondOption1 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)

        model1 = FinModelRatesHW(sigma, a, numTimeSteps)
        v1call = bondOption1.value(settlement_date, discount_curve, model1)

        bondOption2 = BondOption(bond, expiry_date, strikePrice, face,
                                 optionType)

        model2 = FinModelRatesHW(sigma, a, numTimeSteps,
                                 FinHWEuropeanCalcType.EXPIRY_TREE)
        v2call = bondOption2.value(settlement_date, discount_curve, model2)

        end = time.time()
        period = end - start
        testCases.print(period, numTimeSteps, v1put, v2put, v1call, v2call)
示例#30
0
def test_FinEquityLookBackOption():
    valuation_date = Date(1, 1, 2015)
    expiry_date = Date(1, 1, 2016)
    stock_price = 100.0
    volatility = 0.3
    interestRate = 0.05
    dividendYield = 0.01
    num_pathsRange = [10000]
    stock_priceRange = range(90, 110, 10)
    num_steps_per_year = 252

    discount_curve = DiscountCurveFlat(valuation_date, interestRate)
    dividendCurve = DiscountCurveFlat(valuation_date, dividendYield)

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

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "SMIN",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_CALL
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFloatLookbackOption(expiry_date, optionType)
            stockMin = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                stockMin,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "SMIN",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_CALL
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFloatLookbackOption(expiry_date, optionType)
            stockMin = stock_price - 10
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                stockMin,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "SMAX",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_PUT
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFloatLookbackOption(expiry_date, optionType)
            stockMax = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                stockMax,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "SMAX",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_PUT
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFloatLookbackOption(expiry_date, optionType)
            stockMax = stock_price + 10
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                stockMax,
                value,
                valueMC,
                diff,
                timeElapsed)

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

    stock_priceRange = range(90, 110, 10)
    num_steps_per_year = 252

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMAX",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_CALL
    k = 95.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMax = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMax,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMAX",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_CALL
    k = 100.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMax = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMax,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMAX",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_CALL
    k = 105.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMax = stock_price + 10.0
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMax,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMax,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMIN",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_PUT
    k = 95.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMin = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMin,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMIN",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_PUT
    k = 100.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMin = stock_price
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMin,
                value,
                valueMC,
                diff,
                timeElapsed)

    testCases.header(
        "NUMPATHS",
        "OPTION_TYPE",
        "S",
        "K",
        "SMIN",
        "VALUE",
        "VALUE_MC",
        "DIFF",
        "TIME")

    optionType = FinOptionTypes.EUROPEAN_PUT
    k = 105.0
    for stock_price in stock_priceRange:
        for num_paths in num_pathsRange:
            option = FinEquityFixedLookbackOption(expiry_date, optionType, k)
            stockMin = stock_price - 10.0
            value = option.value(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin)
            start = time.time()
            valueMC = option.valueMC(
                valuation_date,
                stock_price,
                discount_curve,
                dividendCurve,
                volatility,
                stockMin,
                num_paths,
                num_steps_per_year)
            end = time.time()
            timeElapsed = round(end - start, 3)
            diff = valueMC - value
            testCases.print(
                num_paths,
                optionType,
                stock_price,
                k,
                stockMin,
                value,
                valueMC,
                diff,
                timeElapsed)