示例#1
0
def test_bloomberg_us_treasury_example():

    # https://data.bloomberglp.com/bat/sites/3/2017/07/SF-2017_Paul-Fjeldsted.pdf

    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)

    clean_price = 99.7808417

    yld = bond.current_yield(clean_price)
    assert round(yld, 4) == 0.0238

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.UK_DMO)
    assert round(ytm, 4) == 0.0240

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.US_STREET)
    assert round(ytm, 4) == 0.0240

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.US_TREASURY)
    assert round(ytm, 4) == 0.0240

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    assert round(full_price, 4) == 100.2149

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    assert round(clean_price, 4) == 99.7825

    accrued_interest = bond._accrued_interest
    assert round(accrued_interest, 4) == 0.4324

    accddays = bond._accrued_days
    assert round(accddays, 4) == 67.0

    duration = bond.dollar_duration(settlement_date, ytm)
    assert round(duration, 4) == 869.0934

    modified_duration = bond.modified_duration(settlement_date, ytm)
    assert round(modified_duration, 4) == 8.6723

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    assert round(macauley_duration, 4) == 8.7764

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    assert round(conv, 4) == 0.8517
示例#2
0
def test_bloomberg_apple_corp_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)

    clean_price = 101.581564

    yld = bond.current_yield(clean_price)
    assert round(yld, 4) == 0.0266

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.UK_DMO)
    assert round(ytm, 4) == 0.0235

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.US_STREET)
    assert round(ytm, 4) == 0.0235

    ytm = bond.yield_to_maturity(settlement_date, clean_price,
                                 YTMCalcType.US_TREASURY)
    assert round(ytm, 4) == 0.0235

    full_price = bond.full_price_from_ytm(settlement_date, ytm)
    assert round(full_price, 4) == 102.0932

    clean_price = bond.clean_price_from_ytm(settlement_date, ytm)
    assert round(clean_price, 4) == 101.5832

    accddays = bond._accrued_days
    assert accddays == 68

    accrued_interest = bond._accrued_interest
    assert round(accrued_interest, 4) == 0.51

    duration = bond.dollar_duration(settlement_date, ytm)
    assert round(duration, 4) == 456.5778

    modified_duration = bond.modified_duration(settlement_date, ytm)
    assert round(modified_duration, 4) == 4.4722

    macauley_duration = bond.macauley_duration(settlement_date, ytm)
    assert round(macauley_duration, 4) == 4.5247

    conv = bond.convexity_from_ytm(settlement_date, ytm)
    assert round(conv, 4) == 0.2302
示例#3
0
def test_BondPortfolio():

    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
    accrual_type = DayCountTypes.ACT_ACT_ICMA

    settlement = Date(19, 9, 2012)

    testCases.header("DCTYPE", "MATDATE", "CPN", "PRICE", "ACCD", "YTM")

    for accrual_type in DayCountTypes:

        for _, bond in bondDataFrame.iterrows():

            date_string = bond['maturity']
            matDatetime = dt.datetime.strptime(date_string, '%d-%b-%y')
            maturityDt = from_datetime(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)

            ytm = bond.yield_to_maturity(settlement, clean_price)
            accrued_interest = bond._accrued_interest

            testCases.print(accrual_type, maturityDt, coupon*100.0,
                            clean_price, accrued_interest, ytm*100.0)
示例#4
0
def test_8():
    accrual_type = DayCountTypes.ACT_365F
    maturityDt = Date(7, 12, 2015)
    coupon = 0.0800000000
    clean_price = 124.47000000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 2.2795
    assert round(ytm * 100, 4) == 0.3405
示例#5
0
def test_7():
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    maturityDt = Date(7, 9, 2015)
    coupon = 0.0475000000
    clean_price = 112.98000000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.1575
    assert round(ytm * 100, 4) == 0.3485
示例#6
0
def test_9():
    accrual_type = DayCountTypes.ACT_360
    maturityDt = Date(22, 1, 2016)
    coupon = 0.0200000000
    clean_price = 104.98000000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.3278
    assert round(ytm * 100, 4) == 0.4930
示例#7
0
def test_10():
    accrual_type = DayCountTypes.ACT_365L
    maturityDt = Date(7, 9, 2016)
    coupon = 0.0400000000
    clean_price = 113.49500000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.1315
    assert round(ytm * 100, 4) == 0.5559
示例#8
0
def test_11():
    accrual_type = DayCountTypes.SIMPLE
    maturityDt = Date(25, 8, 2017)
    coupon = 0.0875000000
    clean_price = 138.57000000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.5993
    assert round(ytm * 100, 4) == 0.7652
示例#9
0
def test_5():
    accrual_type = DayCountTypes.THIRTY_E_PLUS_360
    maturityDt = Date(7, 9, 2014)
    coupon = 0.0500000000
    clean_price = 109.35500000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.1667
    assert round(ytm * 100, 4) == 0.2297
示例#10
0
def test_6():
    accrual_type = DayCountTypes.ACT_ACT_ISDA
    maturityDt = Date(22, 1, 2015)
    coupon = 0.0275000000
    clean_price = 105.62500000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.4433
    assert round(ytm * 100, 4) == 0.3334
示例#11
0
def test_4():
    accrual_type = DayCountTypes.THIRTY_E_360_ISDA
    maturityDt = Date(7, 3, 2014)
    coupon = 0.022500
    clean_price = 102.9750

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.0750
    assert round(ytm * 100, 4) == 0.2172
示例#12
0
def test_3():
    accrual_type = DayCountTypes.THIRTY_E_360
    maturityDt = Date(27, 9, 2013)
    coupon = 0.080000
    clean_price = 107.92000000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 3.8222
    assert round(ytm * 100, 4) == 0.2380
示例#13
0
def test_2():
    accrual_type = DayCountTypes.THIRTY_360_BOND
    maturityDt = Date(7, 3, 2013)
    coupon = 0.045
    clean_price = 101.99500000

    issueDt = Date(maturityDt._d, maturityDt._m, 2000)
    freq_type = FrequencyTypes.SEMI_ANNUAL
    bond = Bond(issueDt, maturityDt, coupon, freq_type, accrual_type)

    ytm = bond.yield_to_maturity(settlement, clean_price)
    assert round(bond._accrued_interest, 4) == 0.1500
    assert round(ytm * 100, 4) == 0.2203
示例#14
0
def test_bondtutor_example():
    #  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)

    full_price = bond.full_price_from_ytm(settlement_date, y)
    assert round(full_price, 4) == 108.7696
    clean_price = bond.clean_price_from_ytm(settlement_date, y)
    assert round(clean_price, 4) == 106.5625
    accrued_interest = bond._accrued_interest
    assert round(accrued_interest, 4) == 22071.8232
    ytm = bond.yield_to_maturity(settlement_date, clean_price)
    assert round(ytm, 4) == 0.0622

    bump = 1e-4
    priceBumpedUp = bond.full_price_from_ytm(settlement_date, y + bump)
    assert round(priceBumpedUp, 4) == 108.7395

    priceBumpedDn = bond.full_price_from_ytm(settlement_date, y - bump)
    assert round(priceBumpedDn, 4) == 108.7998

    durationByBump = -(priceBumpedUp - full_price) / bump
    assert round(durationByBump, 4) == 301.1932

    duration = bond.dollar_duration(settlement_date, y)
    assert round(duration, 4) == 301.2458
    assert round(duration - durationByBump, 4) == 0.0526

    modified_duration = bond.modified_duration(settlement_date, y)
    assert round(modified_duration, 4) == 2.7696

    macauley_duration = bond.macauley_duration(settlement_date, y)
    assert round(macauley_duration, 4) == 2.8558

    conv = bond.convexity_from_ytm(settlement_date, y)
    assert round(conv, 4) == 0.0967
示例#15
0
def test_bond_future_2():
    bond = Bond(issue_date, Date(15, 8, 2027), 0.0225, freq, basis)
    assert bond._maturity_date == Date(15, 8, 2027)

    settlement_date = Date(10, 10, 2017)
    price = 99 + 1 / 32

    yld = bond.yield_to_maturity(settlement_date, price)

    assert round(yld, 4) == 0.0236

    first_delivery_date = Date(1, 12, 2017)
    last_delivery_date = Date(28, 12, 2017)

    contract_size = 100000
    contractCoupon = 0.06
    bondFutureContract = BondFuture("TYZ7",
                                    first_delivery_date,
                                    last_delivery_date,
                                    contract_size,
                                    contractCoupon)

    cf = bondFutureContract.conversion_factor(bond)

    assert round(cf, 4) == 74.2122

    futures_price = 125.265625

    pip = bondFutureContract.principal_invoice_price(bond, futures_price)

    assert round(pip, 4) == 9296237.6200

    tia = bondFutureContract.total_invoice_amount(
            settlement_date, bond, futures_price)

    assert round(tia, 4) == 9296580.0100
示例#16
0
def test_BondFuture():

    # Example taken from Martellini and Priaulet page 360
    freq = FrequencyTypes.SEMI_ANNUAL
    basis = DayCountTypes.ACT_ACT_ICMA
    issue_date = Date(15, 2, 2004)

    bond1 = Bond(issue_date, Date(15, 8, 2011), 0.0500, freq, basis)
    bond2 = Bond(issue_date, Date(15, 2, 2011), 0.0500, freq, basis)
    bond3 = Bond(issue_date, Date(15, 8, 2010), 0.0575, freq, basis)
    bond4 = Bond(issue_date, Date(15, 2, 2010), 0.0650, freq, basis)
    bond5 = Bond(issue_date, Date(15, 8, 2009), 0.0600, freq, basis)
    bond6 = Bond(issue_date, Date(15, 5, 2009), 0.0550, freq, basis)
    bond7 = Bond(issue_date, Date(15, 11, 2008), 0.0475, freq, basis)

    bonds = []
    bonds.append(bond1)
    bonds.append(bond2)
    bonds.append(bond3)
    bonds.append(bond4)
    bonds.append(bond5)
    bonds.append(bond6)
    bonds.append(bond7)

    first_delivery_date = Date(1, 3, 2002)
    last_delivery_date = Date(28, 3, 2002)
    contract_size = 100000
    contractCoupon = 0.06

    bondFutureContract = BondFuture("TYH2", first_delivery_date,
                                    last_delivery_date, contract_size,
                                    contractCoupon)

    settlement_date = Date(10, 12, 2001)

    # Get the Conversion Factors
    testCases.header("Bond Maturity", "Coupon", "Conversion Factor")
    for bond in bonds:
        cf = bondFutureContract.conversion_factor(bond)
        testCases.print(bond._maturity_date, bond._coupon * 100, cf)

    # Example from
    # https://www.cmegroup.com/education/files/understanding-treasury-futures.pdf

    testCases.banner("EXAMPLE FROM CME")
    testCases.banner("================")
    settlement_date = Date(10, 10, 2017)

    bonds = []
    prices = []
    bond = Bond(issue_date, Date(15, 8, 2027), 0.0225, freq, basis)
    bonds.append(bond)
    prices.append(99 + 1 / 32)
    bond = Bond(issue_date, Date(15, 5, 2027), 0.02375, freq, basis)
    bonds.append(bond)
    prices.append(100 + 5 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 2, 2027), 0.0225, freq, basis)
    bonds.append(bond)
    prices.append(99 + 5 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 11, 2026), 0.02, freq, basis)
    bonds.append(bond)
    prices.append(97 + 7 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 8, 2026), 0.015, freq, basis)
    bonds.append(bond)
    prices.append(93 + 14 / 32)
    bond = Bond(issue_date, Date(15, 5, 2026), 0.01625, freq, basis)
    bonds.append(bond)
    prices.append(94 + 21 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 2, 2026), 0.01625, freq, basis)
    bonds.append(bond)
    prices.append(94 + 29 / 32)
    bond = Bond(issue_date, Date(15, 11, 2025), 0.0225, freq, basis)
    bonds.append(bond)
    prices.append(99 + 25 / 32)
    bond = Bond(issue_date, Date(15, 8, 2025), 0.02, freq, basis)
    bonds.append(bond)
    prices.append(98 + 3 / 32)
    bond = Bond(issue_date, Date(15, 5, 2025), 0.02125, freq, basis)
    bonds.append(bond)
    prices.append(99 + 5 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 2, 2025), 0.02, freq, basis)
    bonds.append(bond)
    prices.append(98 + 14 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 11, 2024), 0.0225, freq, basis)
    bonds.append(bond)
    prices.append(100 + 9 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 8, 2024), 0.02375, freq, basis)
    bonds.append(bond)
    prices.append(101 + 7 / 32 + 1 / 64)
    bond = Bond(issue_date, Date(15, 8, 2024), 0.01875, freq, basis)
    bonds.append(bond)
    # There may be an error in the document says 98-01+
    prices.append(98 + 1 / 32)

    testCases.header("BOND MATURITY", "YIELD")
    for bond, clean_price in zip(bonds, prices):
        yld = bond.yield_to_maturity(settlement_date, clean_price)
        testCases.print(str(bond._maturity_date), yld)

    first_delivery_date = Date(1, 12, 2017)
    last_delivery_date = Date(28, 12, 2017)

    contract_size = 100000
    contractCoupon = 0.06

    bondFutureContract = BondFuture("TYZ7", first_delivery_date,
                                    last_delivery_date, contract_size,
                                    contractCoupon)

    testCases.header("BOND MATURITY", "CF")
    for bond in bonds:
        cf = bondFutureContract.conversion_factor(bond)
        testCases.print(str(bond._maturity_date), cf)

    # Get the Invoice Prices
    futures_price = 125.265625

    testCases.header("BOND MATURITY", "PRINCIPAL INVOICE PRICE")
    for bond in bonds:
        pip = bondFutureContract.principal_invoice_price(bond, futures_price)
        testCases.print(str(bond._maturity_date), pip)

    testCases.header("BOND MATURITY", "TOTAL INVOICE AMOUNT")
    for bond in bonds:
        tia = bondFutureContract.total_invoice_amount(settlement_date, bond,
                                                      futures_price)
        testCases.print(str(bond._maturity_date), tia)

    ctd = bondFutureContract.cheapest_to_deliver(bonds, prices, futures_price)

    testCases.header("CTD MATURITY", "CTD COUPON")
    testCases.print(str(ctd._maturity_date), ctd._coupon)
示例#17
0
def test_BondYieldCurve():

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

    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
    accrual_type = DayCountTypes.ACT_ACT_ICMA
    settlement = Date(19, 9, 2012)

    bonds = []
    ylds = []

    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)
        yld = bond.yield_to_maturity(settlement, clean_price)
        bonds.append(bond)
        ylds.append(yld)

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

    curveFitMethod = CurveFitPolynomial()
    fittedCurve1 = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)
    #    fittedCurve1.display("GBP Yield Curve")

    curveFitMethod = CurveFitPolynomial(5)
    fittedCurve2 = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)
    #    fittedCurve2.display("GBP Yield Curve")

    curveFitMethod = CurveFitNelsonSiegel()
    fittedCurve3 = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)
    #    fittedCurve3.display("GBP Yield Curve")

    curveFitMethod = CurveFitNelsonSiegelSvensson()
    fittedCurve4 = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)
    #    fittedCurve4.display("GBP Yield Curve")

    curveFitMethod = CurveFitBSpline()
    fittedCurve5 = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)
    #    fittedCurve5.display("GBP Yield Curve")

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

    testCases.header("PARAMETER", "VALUE")
    testCases.print("beta1", fittedCurve3._curveFit._beta1)
    testCases.print("beta2", fittedCurve3._curveFit._beta2)
    testCases.print("beta3", fittedCurve3._curveFit._beta3)
    testCases.print("tau", fittedCurve3._curveFit._tau)

    testCases.header("PARAMETER", "VALUE")
    testCases.print("beta1", fittedCurve4._curveFit._beta1)
    testCases.print("beta2", fittedCurve4._curveFit._beta2)
    testCases.print("beta3", fittedCurve4._curveFit._beta3)
    testCases.print("beta4", fittedCurve4._curveFit._beta4)
    testCases.print("tau1", fittedCurve4._curveFit._tau1)
    testCases.print("tau2", fittedCurve4._curveFit._tau2)

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

    maturity_date = Date(19, 9, 2030)
    interpolatedYield = fittedCurve5.interpolatedYield(maturity_date)
    testCases.print(maturity_date, interpolatedYield)
示例#18
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)
示例#19
0
accrual_type = DayCountTypes.ACT_ACT_ICMA
settlement = Date(19, 9, 2012)

bonds = []
ylds = []

for _, bond in bondDataFrame.iterrows():

    date_string = bond['maturity']
    matDatetime = dt.datetime.strptime(date_string, '%d-%b-%y')
    maturityDt = from_datetime(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)
    yld = bond.yield_to_maturity(settlement, clean_price)
    bonds.append(bond)
    ylds.append(yld)


def test_poly():
    curveFitMethod = CurveFitPolynomial(5)
    fittedCurve = BondYieldCurve(settlement, bonds, ylds, curveFitMethod)

    coeffs = fittedCurve._curveFit._coeffs
    assert round(coeffs[0] * 1e9, 4) == -1.4477
    assert round(coeffs[1] * 1e7, 4) == 1.7840
    assert round(coeffs[2] * 1e6, 4) == -7.4147
    assert round(coeffs[3] * 1e5, 4) == 9.0622
    assert round(coeffs[4] * 1e3, 4) == 1.3536
    assert round(coeffs[5] * 1e7, 4) == 4.1514