Esempio n. 1
0
def test_FinFXForward():

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

    valuation_date = Date(13, 2, 2018)
    expiry_date = valuation_date.addMonths(12)
    # Forward is on EURUSD which is expressed as number of USD per EUR
    # ccy1 = EUR and ccy2 = USD
    forName = "EUR"
    domName = "USD"
    currencyPair = forName + domName  # Always ccy1ccy2
    spotFXRate = 1.300  # USD per EUR
    strikeFXRate = 1.365  # USD per EUR
    ccy1InterestRate = 0.02  # USD Rates
    ccy2InterestRate = 0.05  # EUR rates

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

    spotDays = 0
    settlement_date = valuation_date.addWeekDays(spotDays)
    maturity_date = settlement_date.addMonths(12)
    notional = 100.0
    calendar_type = CalendarTypes.TARGET

    depos = []
    fras = []
    swaps = []
    deposit_rate = ccy1InterestRate
    depo = FinIborDeposit(settlement_date, maturity_date, deposit_rate,
                          DayCountTypes.ACT_360, notional, calendar_type)
    depos.append(depo)
    forDiscountCurve = IborSingleCurve(valuation_date, depos, fras, swaps)

    depos = []
    fras = []
    swaps = []
    deposit_rate = ccy2InterestRate
    depo = FinIborDeposit(settlement_date, maturity_date, deposit_rate,
                          DayCountTypes.ACT_360, notional, calendar_type)
    depos.append(depo)
    domDiscountCurve = IborSingleCurve(valuation_date, depos, fras, swaps)

    notional = 100.0
    notionalCurrency = forName

    fxForward = FinFXForward(expiry_date, strikeFXRate, currencyPair, notional,
                             notionalCurrency)

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

    fwdValue = fxForward.value(valuation_date, spotFXRate, domDiscountCurve,
                               forDiscountCurve)

    fwdFXRate = fxForward.forward(valuation_date, spotFXRate, domDiscountCurve,
                                  forDiscountCurve)

    testCases.print(spotFXRate, fwdFXRate, fwdValue)
Esempio n. 2
0
def test_DateAddMonths():

    startDate = Date(1, 1, 2010)

    months = [1, 3, 6, 9, 12, 24, 36, 48, 60]

    dates = startDate.addMonths(months)

    for dt in dates:
        print("DATE", dt)
Esempio n. 3
0
def test_FinDateAddMonths():

    start_date = Date(1, 1, 2010)

    testCases.header("Months", "Dates")

    months = [1, 3, 6, 9, 12, 24, 36, 48, 60]

    dates = start_date.addMonths(months)

    testCases.header("DATES", "DATE")

    for dt in dates:
        testCases.print("DATE", dt)
Esempio n. 4
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)
Esempio n. 5
0
def test_IssuerCurveBuild():
    """ Test issuer curve build with simple libor curve to isolate cds
    curve building time cost. """

    valuation_date = Date(20, 6, 2018)

    times = np.linspace(0.0, 10.0, 11)
    r = 0.05
    discount_factors = np.power((1.0 + r), -times)
    dates = valuation_date.addYears(times)
    libor_curve = DiscountCurve(valuation_date, dates, discount_factors,
                                FinInterpTypes.FLAT_FWD_RATES)
    recovery_rate = 0.40

    cds_contracts = []

    cdsCoupon = 0.005  # 50 bps
    maturity_date = valuation_date.addMonths(12)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    cdsCoupon = 0.0055
    maturity_date = valuation_date.addMonths(24)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    cdsCoupon = 0.0060
    maturity_date = valuation_date.addMonths(36)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    cdsCoupon = 0.0065
    maturity_date = valuation_date.addMonths(60)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    cdsCoupon = 0.0070
    maturity_date = valuation_date.addMonths(84)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    cdsCoupon = 0.0073
    maturity_date = valuation_date.addMonths(120)
    cds = FinCDS(valuation_date, maturity_date, cdsCoupon)
    cds_contracts.append(cds)

    issuer_curve = FinCDSCurve(valuation_date, cds_contracts, libor_curve,
                               recovery_rate)

    return cds_contracts, issuer_curve
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)
Esempio n. 7
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)
Esempio n. 8
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)
Esempio n. 9
0
def buildFullIssuerCurve2(mktSpreadBump, irBump):

    # https://www.markit.com/markit.jsp?jsppage=pv.jsp
    # YIELD CURVE 20 August 2020 SNAP AT 1600

    m = 1.0

    valuation_date = Date(24, 8, 2020)
    settlement_date = Date(24, 8, 2020)
    dcType = DayCountTypes.ACT_360
    depos = []

    maturity_date = settlement_date.addMonths(1)
    depo1 = FinIborDeposit(settlement_date, maturity_date, m * 0.001709,
                           dcType)

    maturity_date = settlement_date.addMonths(2)
    depo2 = FinIborDeposit(settlement_date, maturity_date, m * 0.002123,
                           dcType)

    maturity_date = settlement_date.addMonths(3)
    depo3 = FinIborDeposit(settlement_date, maturity_date, m * 0.002469,
                           dcType)

    maturity_date = settlement_date.addMonths(6)
    depo4 = FinIborDeposit(settlement_date, maturity_date, m * 0.003045,
                           dcType)

    maturity_date = settlement_date.addMonths(12)
    depo5 = FinIborDeposit(settlement_date, maturity_date, m * 0.004449,
                           dcType)

    depos.append(depo1)
    depos.append(depo2)
    depos.append(depo3)
    depos.append(depo4)
    depos.append(depo5)

    swaps = []
    dcType = DayCountTypes.THIRTY_E_360_ISDA
    fixedFreq = FrequencyTypes.SEMI_ANNUAL

    maturity_date = settlement_date.addMonths(24)
    swap1 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY,
                        m * 0.002155 + irBump, fixedFreq, dcType)
    swaps.append(swap1)

    maturity_date = settlement_date.addMonths(36)
    swap2 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY,
                        m * 0.002305 + irBump, fixedFreq, dcType)
    swaps.append(swap2)

    maturity_date = settlement_date.addMonths(48)
    swap3 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY,
                        m * 0.002665 + irBump, fixedFreq, dcType)
    swaps.append(swap3)

    maturity_date = settlement_date.addMonths(60)
    swap4 = FinIborSwap(settlement_date, maturity_date, FinSwapTypes.PAY,
                        m * 0.003290 + irBump, fixedFreq, dcType)
    swaps.append(swap4)

    libor_curve = IborSingleCurve(valuation_date, depos, [], swaps)

    cdsCoupon = 0.01 + mktSpreadBump

    cdsMarketContracts = []
    effective_date = Date(21, 8, 2020)
    cds = FinCDS(effective_date, "6M", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "1Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "2Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "3Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "4Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "5Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "7Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    cds = FinCDS(effective_date, "10Y", cdsCoupon)
    cdsMarketContracts.append(cds)

    recovery_rate = 0.40

    issuer_curve = FinCDSCurve(settlement_date, cdsMarketContracts,
                               libor_curve, recovery_rate)

    testCases.header("DATE", "DISCOUNT_FACTOR", "SURV_PROB")
    years = np.linspace(0.0, 10.0, 20)
    dates = settlement_date.addYears(years)
    for dt in dates:
        df = libor_curve.df(dt)
        q = issuer_curve.survProb(dt)
        testCases.print("%16s" % dt, "%12.8f" % df, "%12.8f" % q)

    return libor_curve, issuer_curve
Esempio n. 10
0
def test_FinCDSCurve():

    curveDate = Date(20, 12, 2018)

    swaps = []
    depos = []
    fras = []

    fixedDCC = DayCountTypes.ACT_365F
    fixedFreq = FrequencyTypes.SEMI_ANNUAL
    fixedCoupon = 0.05

    for i in range(1, 11):

        maturity_date = curveDate.addMonths(12 * i)
        swap = FinIborSwap(curveDate, maturity_date, FinSwapTypes.PAY,
                           fixedCoupon, fixedFreq, fixedDCC)
        swaps.append(swap)

    libor_curve = IborSingleCurve(curveDate, depos, fras, swaps)

    cds_contracts = []

    for i in range(1, 11):
        maturity_date = curveDate.addMonths(12 * i)
        cds = FinCDS(curveDate, maturity_date, 0.005 + 0.001 * (i - 1))
        cds_contracts.append(cds)

    issuer_curve = FinCDSCurve(curveDate,
                               cds_contracts,
                               libor_curve,
                               recovery_rate=0.40,
                               useCache=False)

    testCases.header("T", "Q")
    n = len(issuer_curve._times)
    for i in range(0, n):
        testCases.print(issuer_curve._times[i], issuer_curve._values[i])

    testCases.header("CONTRACT", "VALUE")
    for i in range(1, 11):
        maturity_date = curveDate.addMonths(12 * i)
        cds = FinCDS(curveDate, maturity_date, 0.005 + 0.001 * (i - 1))
        v = cds.value(curveDate, issuer_curve)
        testCases.print(i, v)

    if 1 == 0:
        x = [0.0, 1.2, 1.6, 1.7, 10.0]
        qs = issuer_curve.survProb(x)
        print("===>", qs)

        x = [0.3, 1.2, 1.6, 1.7, 10.0]
        xx = np.array(x)
        qs = issuer_curve.survProb(xx)
        print("===>", qs)

        x = [0.3, 1.2, 1.6, 1.7, 10.0]
        dfs = issuer_curve.df(x)
        print("===>", dfs)

        x = [0.3, 1.2, 1.6, 1.7, 10.0]
        xx = np.array(x)
        dfs = issuer_curve.df(xx)
        print("===>", dfs)
Esempio n. 11
0
def test_FinInflationBondStack():

    ##########################################################################
    # https://stackoverflow.com/questions/57676724/failing-to-obtain-correct-accrued-interest-with-quantlib-inflation-bond-pricer-i
    ##########################################################################

    testCases.banner("=============================")
    testCases.banner("QUANT FINANCE US TIPS EXAMPLE")
    testCases.banner("=============================")
    settlement_date = Date(23, 8, 2019)
    issue_date = Date(25, 9, 2013)
    maturity_date = Date(22, 3, 2068)
    coupon = 0.00125
    freq_type = FrequencyTypes.SEMI_ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    face = 100.0
    baseCPIValue = 249.70

    ###########################################################################
    # Discount curve
    discount_curve = DiscountCurveFlat(settlement_date, 0.01033692,
                                       FrequencyTypes.ANNUAL,
                                       DayCountTypes.ACT_ACT_ISDA)

    lag = 3
    fixingCPI = 244.65884
    fixingDate = settlement_date.addMonths(-lag)

    ###########################################################################
    # Create Index Curve
    months = range(0, 12, 1)
    fixingDates = Date(31, 8, 2018).addMonths(months)
    fixingRates = [
        284.2, 284.1, 284.5, 284.6, 285.6, 283.0, 285.0, 285.1, 288.2, 289.2,
        289.6, 289.5
    ]
    inflationIndex = FinInflationIndexCurve(fixingDates, fixingRates, lag)
    #    print(inflationIndex)
    ###########################################################################

    zciisData = [(Date(31, 7, 2020), 3.1500000000137085),
                 (Date(31, 7, 2021), 3.547500000013759),
                 (Date(31, 7, 2022), 3.675000000013573),
                 (Date(31, 7, 2023), 3.7250000000134342),
                 (Date(31, 7, 2024), 3.750000000013265),
                 (Date(31, 7, 2025), 3.7430000000129526),
                 (Date(31, 7, 2026), 3.741200000012679),
                 (Date(31, 7, 2027), 3.7337000000123632),
                 (Date(31, 7, 2028), 3.725000000011902),
                 (Date(31, 7, 2029), 3.720000000011603),
                 (Date(31, 7, 2030), 3.712517289063011),
                 (Date(31, 7, 2031), 3.7013000000108764),
                 (Date(31, 7, 2032), 3.686986039205209),
                 (Date(31, 7, 2033), 3.671102614032895),
                 (Date(31, 7, 2034), 3.655000000009778),
                 (Date(31, 7, 2035), 3.6394715951305834),
                 (Date(31, 7, 2036), 3.624362044800966),
                 (Date(31, 7, 2037), 3.6093619727979087),
                 (Date(31, 7, 2038), 3.59421438364369),
                 (Date(31, 7, 2039), 3.5787000000081948),
                 (Date(31, 7, 2040), 3.5626192748395624),
                 (Date(31, 7, 2041), 3.545765016376823),
                 (Date(31, 7, 2042), 3.527943521613608),
                 (Date(31, 7, 2043), 3.508977137925462),
                 (Date(31, 7, 2044), 3.48870000000685),
                 (Date(31, 7, 2045), 3.467083068721011),
                 (Date(31, 7, 2046), 3.4445738220594935),
                 (Date(31, 7, 2047), 3.4216470902302065),
                 (Date(31, 7, 2048), 3.3986861494999188),
                 (Date(31, 7, 2049), 3.376000000005752),
                 (Date(31, 7, 2050), 3.3538412080641233),
                 (Date(31, 7, 2051), 3.3324275806807746),
                 (Date(31, 7, 2052), 3.311938788306623),
                 (Date(31, 7, 2053), 3.2925208131865835),
                 (Date(31, 7, 2054), 3.274293040759302),
                 (Date(31, 7, 2055), 3.2573541974782794),
                 (Date(31, 7, 2056), 3.241787355503245),
                 (Date(31, 7, 2057), 3.227664186159851),
                 (Date(31, 7, 2058), 3.2150486140060774),
                 (Date(31, 7, 2059), 3.204000000004159),
                 (Date(31, 7, 2060), 3.1945334946674064),
                 (Date(31, 7, 2061), 3.1865047145143377),
                 (Date(31, 7, 2062), 3.179753073456304),
                 (Date(31, 7, 2063), 3.1741427790361154),
                 (Date(31, 7, 2064), 3.1695593261025223),
                 (Date(31, 7, 2065), 3.1659065919088736),
                 (Date(31, 7, 2066), 3.163104428386987),
                 (Date(31, 7, 2067), 3.1610866681252903),
                 (Date(31, 7, 2068), 3.1597994770515836),
                 (Date(31, 7, 2069), 3.159200000003204),
                 (Date(31, 7, 2070), 3.159242349440139),
                 (Date(31, 7, 2071), 3.1598400898057433),
                 (Date(31, 7, 2072), 3.16090721831932),
                 (Date(31, 7, 2073), 3.162369676612098),
                 (Date(31, 7, 2074), 3.1641636543027207)]

    zcDates = []
    zcRates = []
    for i in range(0, len(zciisData)):
        zcDates.append(zciisData[i][0])
        zcRates.append(zciisData[i][1] / 100.0)

    inflationZeroCurve = DiscountCurveZeros(settlement_date, zcDates, zcRates,
                                            FrequencyTypes.ANNUAL,
                                            DayCountTypes.ACT_ACT_ISDA)

    #    print(inflationZeroCurve)

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

    bond = FinInflationBond(issue_date, maturity_date, coupon, freq_type,
                            accrual_type, face, baseCPIValue)

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

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

    return

    ###########################################################################
    # Inherited functions that just calculate real yield without CPI adjustments
    ###########################################################################

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.UK_DMO)

    testCases.print("UK DMO REAL Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_STREET)

    testCases.print("US STREET REAL Yield To Maturity = ", ytm)

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 FinYTMCalcType.US_TREASURY)

    testCases.print("US TREASURY REAL Yield To Maturity = ", ytm)

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

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

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

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

    ###########################################################################
    # Inflation functions that calculate nominal yield with CPI adjustment
    ###########################################################################

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

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

    inflationAccd = bond.calcInflationAccruedInterest(settlement_date,
                                                      refCPIValue)

    testCases.print("Inflation Accrued = ", inflationAccd)

    lastCpnCPIValue = 244.61839

    clean_price = bond.flatPriceFromYieldToMaturity(settlement_date, ytm,
                                                    lastCpnCPIValue,
                                                    FinYTMCalcType.US_TREASURY)

    testCases.print("Flat Price from Real YTM = ", clean_price)

    principal = bond.inflationPrincipal(settlement_date, ytm, refCPIValue,
                                        FinYTMCalcType.US_TREASURY)

    testCases.print("Inflation Principal = ", principal)

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

    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)
Esempio n. 12
0
def test_BondEmbeddedOptionMATLAB():
    # https://fr.mathworks.com/help/fininst/optembndbybk.html
    # I FIND THAT THE PRICE CONVERGES TO 102.365 WHICH IS CLOSE TO 102.382
    # FOUND BY MATLAB ALTHOUGH THEY DO NOT EXAMINE THE ASYMPTOTIC PRICE
    # WHICH MIGHT BE A BETTER MATCH - ALSO THEY DO NOT USE A REALISTIC VOL

    valuation_date = Date(1, 1, 2007)
    settlement_date = valuation_date

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

    fixed_legType = FinSwapTypes.PAY
    dcType = DayCountTypes.THIRTY_E_360
    fixedFreq = FrequencyTypes.ANNUAL
    swap1 = FinIborSwap(settlement_date, "1Y", fixed_legType, 0.0350,
                        fixedFreq, dcType)
    swap2 = FinIborSwap(settlement_date, "2Y", fixed_legType, 0.0400,
                        fixedFreq, dcType)
    swap3 = FinIborSwap(settlement_date, "3Y", fixed_legType, 0.0450,
                        fixedFreq, dcType)
    swaps = [swap1, swap2, swap3]
    discount_curve = IborSingleCurve(valuation_date, [], [], swaps)

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

    issue_date = Date(1, 1, 2005)
    maturity_date = Date(1, 1, 2010)
    coupon = 0.0525
    freq_type = FrequencyTypes.ANNUAL
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    call_dates = []
    call_prices = []
    put_dates = []
    put_prices = []

    putDate = Date(1, 1, 2008)
    for _ in range(0, 24):
        put_dates.append(putDate)
        put_prices.append(100)
        putDate = putDate.addMonths(1)

    testCases.header("BOND PRICE", "PRICE")
    v = bond.clean_price_from_discount_curve(settlement_date, discount_curve)
    testCases.print("Bond Pure Price:", v)

    sigma = 0.01  # This volatility is very small for a BK process
    a = 0.1

    puttableBond = BondEmbeddedOption(issue_date, maturity_date, coupon,
                                      freq_type, accrual_type, call_dates,
                                      call_prices, put_dates, put_prices)

    testCases.header("TIME", "NumTimeSteps", "BondWithOption", "BondPure")

    timeSteps = range(100, 200, 10)  # 1000, 10)
    values = []
    for numTimeSteps in timeSteps:
        model = FinModelRatesBK(sigma, a, numTimeSteps)
        start = time.time()
        v = puttableBond.value(settlement_date, discount_curve, model)
        end = time.time()
        period = end - start
        testCases.print(period, numTimeSteps, v['bondwithoption'],
                        v['bondpure'])

        values.append(v['bondwithoption'])

    if plotGraphs:
        plt.figure()
        plt.plot(timeSteps, values)
Esempio n. 13
0
def test_BondEmbeddedOptionQUANTLIB():

    # Based on example at the nice blog on Quantlib at
    # http://gouthamanbalaraman.com/blog/callable-bond-quantlib-python.html
    # I get a price of 68.97 for 1000 time steps which is higher than the
    # 68.38 found in blog article. But this is for 40 grid points.
    # Note also that a basis point vol of 0.120 is 12% which is VERY HIGH!

    valuation_date = Date(16, 8, 2016)
    settlement_date = valuation_date.addWeekDays(3)

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

    discount_curve = DiscountCurveFlat(valuation_date, 0.035,
                                       FrequencyTypes.SEMI_ANNUAL)

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

    issue_date = Date(15, 9, 2010)
    maturity_date = Date(15, 9, 2022)
    coupon = 0.025
    freq_type = FrequencyTypes.QUARTERLY
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    bond = Bond(issue_date, maturity_date, coupon, freq_type, accrual_type)

    ###########################################################################
    # Set up the call and put times and prices
    ###########################################################################

    nextCallDate = Date(15, 9, 2016)
    call_dates = [nextCallDate]
    call_prices = [100.0]

    for _ in range(1, 24):
        nextCallDate = nextCallDate.addMonths(3)
        call_dates.append(nextCallDate)
        call_prices.append(100.0)

    put_dates = []
    put_prices = []

    # the value used in blog of 12% bp vol is unrealistic
    sigma = 0.12 / 0.035  # basis point volatility
    a = 0.03

    puttableBond = BondEmbeddedOption(issue_date, maturity_date, coupon,
                                      freq_type, accrual_type, call_dates,
                                      call_prices, put_dates, put_prices)

    testCases.header("BOND PRICE", "PRICE")
    v = bond.clean_price_from_discount_curve(settlement_date, discount_curve)
    testCases.print("Bond Pure Price:", v)

    testCases.header("TIME", "NumTimeSteps", "BondWithOption", "BondPure")
    timeSteps = range(100, 200, 20)  # 1000, 10)
    values = []
    for numTimeSteps in timeSteps:
        model = FinModelRatesBK(sigma, a, numTimeSteps)
        start = time.time()
        v = puttableBond.value(settlement_date, discount_curve, model)
        end = time.time()
        period = end - start
        testCases.print(period, numTimeSteps, v['bondwithoption'],
                        v['bondpure'])
        values.append(v['bondwithoption'])

    if plotGraphs:
        plt.figure()
        plt.title("Puttable Bond Price Convergence")
        plt.plot(timeSteps, values)