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
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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)
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)
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)
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