Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

6 Question 6 6.1 Up to now, all the functions we have written are stand-alone fu

ID: 3885614 • Letter: 6

Question

6 Question 6 6.1 Up to now, all the functions we have written are stand-alone funins, Hence both the functions price.from yieldd...) and yield.from-price... carry cumbersome baggage, in the sense of input arguments (F.c,n) for the face, coupon and number of coupons, respectively. The valaes of these parameters are not relevant to a bisection algorithm, and do not change during iteration. Nevertheless, they must be passed as inputs to yield from price(...), sothat they can be passed to price.from.yield(...) to value the bond 6.2 This suggests the use of object-oriented programming. We can encapsulate the values of (Fe,) in "Bond" object. The functions price-from-yield( ) and yield-from-Price ( ) can be methods of that Bond class. We shall also support bonds which are notnewly issued, so to 0 6.3 Let us design a simple Bond class. What are its internal data members? Clearly we must have the face. We also need the maturity. (In real life the maturity would be a date, but here we store it as a double, measured in years.) To make things more interesting, let us consider a bond with variable coupons G, paid on dates (ti nes) t., i = 1.2 ,n. Both c' and t, are of type double. Hence our data members are: 1. double face; 2. double maturity 3. std; : vector coupon ; You can also include a data member of type int to store the namber of coupons, if you wish 6.4 Because the coupons are variable, and also to 0, the fornmula for the bond price B in terms of the yield y is more complicated: Here T is the maturity date. In all test examples of coupon bearing bonds, the last coupon date n will be eual to T . Howerer, the Bond class must also work for a ZERO COUPON BOND The Bond class must function even if there are no coupons e·and dates t.. Hence we cannot assume T- t, because f might not exist.

Explanation / Answer

package org.jquantlib.samples;

import java.util.ArrayList;

import java.util.List;

import org.jquantlib.QL;

import org.jquantlib.Settings;

import org.jquantlib.cashflow.BlackIborCouponPricer;

import org.jquantlib.cashflow.IborCouponPricer;

import org.jquantlib.cashflow.PricerSetter;

import org.jquantlib.daycounters.Actual360;

import org.jquantlib.daycounters.Actual365Fixed;

import org.jquantlib.daycounters.ActualActual;

import org.jquantlib.daycounters.DayCounter;

import org.jquantlib.daycounters.Thirty360;

import org.jquantlib.daycounters.Thirty360.Convention;

import org.jquantlib.indexes.Euribor6M;

import org.jquantlib.indexes.IborIndex;

import org.jquantlib.indexes.ibor.USDLibor;

import org.jquantlib.instruments.bonds.FixedRateBond;

import org.jquantlib.instruments.bonds.FloatingRateBond;

import org.jquantlib.instruments.bonds.ZeroCouponBond;

import org.jquantlib.math.interpolations.factories.LogLinear;

import org.jquantlib.math.matrixutilities.Array;

import org.jquantlib.pricingengines.PricingEngine;

import org.jquantlib.pricingengines.bond.DiscountingBondEngine;

import org.jquantlib.quotes.Handle;

import org.jquantlib.quotes.Quote;

import org.jquantlib.quotes.RelinkableHandle;

import org.jquantlib.quotes.SimpleQuote;

import org.jquantlib.samples.util.StopClock;

import org.jquantlib.termstructures.Compounding;

import org.jquantlib.termstructures.IterativeBootstrap;

import org.jquantlib.termstructures.RateHelper;

import org.jquantlib.termstructures.YieldTermStructure;

import org.jquantlib.termstructures.volatilities.optionlet.ConstantOptionletVolatility;

import org.jquantlib.termstructures.volatilities.optionlet.OptionletVolatilityStructure;

import org.jquantlib.termstructures.yieldcurves.DepositRateHelper;

import org.jquantlib.termstructures.yieldcurves.Discount;

import org.jquantlib.termstructures.yieldcurves.FixedRateBondHelper;

import org.jquantlib.termstructures.yieldcurves.PiecewiseYieldCurve;

import org.jquantlib.termstructures.yieldcurves.SwapRateHelper;

import org.jquantlib.time.BusinessDayConvention;

import org.jquantlib.time.Calendar;

import org.jquantlib.time.Date;

import org.jquantlib.time.DateGeneration;

import org.jquantlib.time.Frequency;

import org.jquantlib.time.Month;

import org.jquantlib.time.Period;

import org.jquantlib.time.Schedule;

import org.jquantlib.time.TimeUnit;

import org.jquantlib.time.calendars.Target;

import org.jquantlib.time.calendars.UnitedStates;

/**

*

* @author Zahid Hussain

*

*/

public class Bonds { //implements Runnable {

public static void main(final String[] args) {

new Bonds().run();

}

public void run() {

QL.info("::::: " + this.getClass().getSimpleName() + " :::::");

final StopClock clock = new StopClock();

clock.startClock();

QL.info("Started calculation at: " + clock.getElapsedTime());

/*********************

*** MARKET DATA ***

*********************/

final Calendar calendar = new Target();

// FIXME: outdated...

Date settlementDate = new Date(18, Month.September, 2008);

// must be a business day

settlementDate = calendar.adjust(settlementDate);

final int fixingDays = 3;

final int settlementDays = 3;

final Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days);

new Settings().setEvaluationDate(todaysDate);

QL.info("Evaluation date: " + todaysDate.weekday() + ", " + todaysDate);

QL.info("Settlement date: " + settlementDate.weekday() + ", " + settlementDate);

// Building of the bonds discounting yield curve

/*********************

*** RATE HELPERS ***

*********************/

// RateHelpers are built from the above quotes together with

// other instrument dependent infos. Quotes are passed in

// relinkable handles which could be relinked to some other

// data source later.

  

// Common data

  

// ZC rates for the short end

final double zc3mQuote = 0.0096;

final double zc6mQuote = 0.0145;

final double zc1yQuote = 0.0194;

final Quote zc3mRate = new SimpleQuote(zc3mQuote);

final Quote zc6mRate = new SimpleQuote(zc6mQuote);

final Quote zc1yRate = new SimpleQuote(zc1yQuote);

final DayCounter zcBondsDayCounter = new Actual365Fixed();

final RateHelper zc3m = new DepositRateHelper(

new Handle<Quote>(zc3mRate), new Period(3, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter);

final RateHelper zc6m = new DepositRateHelper(

new Handle<Quote>(zc6mRate), new Period(6, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter);

final RateHelper zc1y = new DepositRateHelper(

new Handle<Quote>(zc1yRate), new Period(1, TimeUnit.Years),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter);

// setup bonds

final double redemption = 100.0;

final int numberOfBonds = 5;

final Date issueDates[] = {

new Date(15, Month.March, 2005),

new Date(15, Month.June, 2005),

new Date(30, Month.June, 2006),

new Date(15, Month.November, 2002),

new Date(15, Month.May, 1987) };

final Date maturities[] = {

new Date(31, Month.August, 2010),

new Date(31, Month.August, 2011),

new Date(31, Month.August, 2013),

new Date(15, Month.August, 2018),

new Date(15, Month.May, 2038) };

final double couponRates[] = { 0.02375,

0.04625,

0.03125,

0.04000,

0.04500

};

final double marketQuotes[] = { 100.390625,

106.21875,

100.59375,

101.6875,

102.140625

};

final List<SimpleQuote> quote = new ArrayList<SimpleQuote>(numberOfBonds);

final List<RelinkableHandle<Quote>> quoteHandle = new ArrayList<RelinkableHandle<Quote>>(numberOfBonds);

for (int i = 0; i < numberOfBonds; i++) {

final SimpleQuote sq = new SimpleQuote(marketQuotes[i]);

final RelinkableHandle<Quote> handle = new RelinkableHandle<Quote>(sq);

quote.add(sq);

quoteHandle.add(handle);   

}

// Definition of the rate helpers

// final List<FixedRateBondHelper<YieldTermStructure>> bondsHelpers = new ArrayList<FixedRateBondHelper<YieldTermStructure>>();

final List<FixedRateBondHelper> bondsHelpers = new ArrayList<FixedRateBondHelper>();

for (int i = 0; i < numberOfBonds; i++) {

final Schedule schedule = new Schedule(

issueDates[i], maturities[i],

new Period(Frequency.Semiannual),

new UnitedStates(UnitedStates.Market.GOVERNMENTBOND),

BusinessDayConvention.Unadjusted,

BusinessDayConvention.Unadjusted,

DateGeneration.Rule.Backward,

false);

final FixedRateBondHelper bondHelper = new FixedRateBondHelper(

quoteHandle.get(i),

settlementDays,

100.0,

schedule,

new double[]{ couponRates[i] },

new ActualActual(ActualActual.Convention.Bond),

BusinessDayConvention.Unadjusted,

redemption,

issueDates[i]);

bondsHelpers.add(bondHelper);

}

/*********************

** CURVE BUILDING **

*********************/

// Any DayCounter would be fine.

// ActualActual::ISDA ensures that 30 years is 30.0

final DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA);

final double tolerance = 1.0e-15;

// A depo-bond curve

final List<RateHelper> bondInstruments = new ArrayList<RateHelper>();

// Adding the ZC bonds to the curve for the short end

bondInstruments.add(zc3m);

bondInstruments.add(zc6m);

bondInstruments.add(zc1y);

// Adding the Fixed rate bonds to the curve for the long end

for (int i = 0; i < numberOfBonds; i++) {

bondInstruments.add(bondsHelpers.get(i));

}

final RateHelper[] instruments1 = new RateHelper[bondInstruments.size()];

bondInstruments.toArray(instruments1);

final Handle[] jumps1 = new Handle[0];

final Date[] jumpDates1 = new Date[0];

final double tolerance1 = 1.0e-15;

final LogLinear interpolator = null;

final IterativeBootstrap bootstrap = null;

  

final YieldTermStructure bondDiscountingTermStructur =

new PiecewiseYieldCurve<Discount,LogLinear,IterativeBootstrap>(

Discount.class, LogLinear.class, IterativeBootstrap.class,

settlementDate,

instruments1,

termStructureDayCounter,

jumps1,

jumpDates1,

tolerance1,

interpolator,

bootstrap){/* anonymous */};

// Building of the Libor forecasting curve

// deposits

final double d1wQuote = 0.043375;

final double d1mQuote = 0.031875;

final double d3mQuote = 0.0320375;

final double d6mQuote = 0.03385;

final double d9mQuote = 0.0338125;

final double d1yQuote = 0.0335125;

// swaps

final double s2yQuote = 0.0295;

final double s3yQuote = 0.0323;

final double s5yQuote = 0.0359;

final double s10yQuote = 0.0412;

final double s15yQuote = 0.0433;

/********************

*** QUOTES ***

********************/

// SimpleQuote stores a value which can be manually changed;

// other Quote subclasses could read the value from a database

// or some kind of data feed.

// deposits

final Quote d1wRate = (new SimpleQuote(d1wQuote));

final Quote d1mRate = (new SimpleQuote(d1mQuote));

final Quote d3mRate = (new SimpleQuote(d3mQuote));

final Quote d6mRate = (new SimpleQuote(d6mQuote));

final Quote d9mRate = (new SimpleQuote(d9mQuote));

final Quote d1yRate = (new SimpleQuote(d1yQuote));

// swaps

final Quote s2yRate = (new SimpleQuote(s2yQuote));

final Quote s3yRate = (new SimpleQuote(s3yQuote));

final Quote s5yRate = (new SimpleQuote(s5yQuote));

final Quote s10yRate = (new SimpleQuote(s10yQuote));

final Quote s15yRate = (new SimpleQuote(s15yQuote));

/*********************

*** RATE HELPERS ***

*********************/

// RateHelpers are built from the above quotes together with

// other instrument dependant infos. Quotes are passed in

// relinkable handles which could be relinked to some other

// data source later.

// deposits

final DayCounter depositDayCounter = new Actual360();

final RateHelper d1w = new DepositRateHelper(

new Handle<Quote>(d1wRate),

new Period(1, TimeUnit.Weeks),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

final RateHelper d1m = new DepositRateHelper(

new Handle<Quote>(d1mRate),

new Period(1, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

final RateHelper d3m = new DepositRateHelper(

new Handle<Quote>(d3mRate),

new Period(3, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

final RateHelper d6m = new DepositRateHelper(

new Handle<Quote>(d6mRate),

new Period(6, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

final RateHelper d9m = new DepositRateHelper(

new Handle<Quote>(d9mRate),

new Period(9, TimeUnit.Months),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

final RateHelper d1y = new DepositRateHelper(

new Handle<Quote>(d1yRate),

new Period(1, TimeUnit.Years),

fixingDays, calendar,

BusinessDayConvention.ModifiedFollowing,

true, depositDayCounter);

// setup swaps

final Frequency swFixedLegFrequency = Frequency.Annual;

final BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted;

final DayCounter swFixedLegDayCounter = new Thirty360(Convention.European);

final IborIndex swFloatingLegIndex = new Euribor6M(new Handle<YieldTermStructure>());

// TODO and FIXME: not sure whether the class stuff works properly

// final IborIndex swFloatingLegIndex = Euribor.getEuribor6M(new Handle<YieldTermStructure>(YieldTermStructure.class)); //FIXME::RG::Handle

// final YieldTermStructure nullYieldTermStructure = new AbstractYieldTermStructure() {

// @Override

// protected double discountImpl(final double t) {

// throw new UnsupportedOperationException();

// }

// @Override

// public Date maxDate() {

// throw new UnsupportedOperationException();

// }

// };

// final IborIndex swFloatingLegIndex = new Euribor6M(new Handle<YieldTermStructure>(nullYieldTermStructure));

final Period forwardStart = new Period(1, TimeUnit.Days);

  

final RateHelper s2y = new SwapRateHelper(

new Handle<Quote>(s2yRate),

new Period(2, TimeUnit.Years),

calendar,

swFixedLegFrequency,

swFixedLegConvention,

swFixedLegDayCounter,

swFloatingLegIndex,

new Handle<Quote>(),

forwardStart);

final RateHelper s3y = new SwapRateHelper(

new Handle<Quote>(s3yRate),

new Period(3, TimeUnit.Years),

calendar,

swFixedLegFrequency,

swFixedLegConvention,

swFixedLegDayCounter,

swFloatingLegIndex,

new Handle<Quote>(),

forwardStart);

final RateHelper s5y = new SwapRateHelper(

new Handle<Quote>(s5yRate),

new Period(5, TimeUnit.Years),

calendar,

swFixedLegFrequency,

swFixedLegConvention,

swFixedLegDayCounter,

swFloatingLegIndex,

new Handle<Quote>(),

forwardStart);

final RateHelper s10y = new SwapRateHelper(

new Handle<Quote>(s10yRate),

new Period(10, TimeUnit.Years),

calendar,

swFixedLegFrequency,

swFixedLegConvention,

swFixedLegDayCounter,

swFloatingLegIndex,

new Handle<Quote>(),

forwardStart);

final RateHelper s15y = new SwapRateHelper(

new Handle<Quote>(s15yRate),

new Period(15, TimeUnit.Years),

calendar,

swFixedLegFrequency,

swFixedLegConvention,

swFixedLegDayCounter,

swFloatingLegIndex,

new Handle<Quote>(),

forwardStart);

/*********************

** CURVE BUILDING **

*********************/

  

// Any DayCounter would be fine.

// ActualActual::ISDA ensures that 30 years is 30.0

  

// A depo-swap curve

final List<RateHelper> depoSwapInstruments = new ArrayList<RateHelper>();

depoSwapInstruments.add(d1w);

depoSwapInstruments.add(d1m);

depoSwapInstruments.add(d3m);

depoSwapInstruments.add(d6m);

depoSwapInstruments.add(d9m);

depoSwapInstruments.add(d1y);

depoSwapInstruments.add(s2y);

depoSwapInstruments.add(s3y);

depoSwapInstruments.add(s5y);

depoSwapInstruments.add(s10y);

depoSwapInstruments.add(s15y);

final RateHelper[] instruments = new RateHelper[depoSwapInstruments.size()];

depoSwapInstruments.toArray(instruments);

final Handle[] jumps= new Handle[0];//]<Quote>[]) new ArrayList<Handle<Quote>>().toArray();

final Date[] jumpDates = new Date[0];// new ArrayList<Date>().toArray();

final YieldTermStructure depoSwapTermStructure =

new PiecewiseYieldCurve<Discount,LogLinear,IterativeBootstrap>(

Discount.class, LogLinear.class, IterativeBootstrap.class,

settlementDate,

instruments,

termStructureDayCounter,

jumps,

jumpDates,

tolerance,

interpolator,/*Hack*/

bootstrap /*Hack*/){/* anonymous */};

// Term structures that will be used for pricing:

// the one used for discounting cash flows

final RelinkableHandle<YieldTermStructure> discountingTermStructure = new RelinkableHandle<YieldTermStructure>();

// the one used for forward rate forecasting

final RelinkableHandle<YieldTermStructure> forecastingTermStructure = new RelinkableHandle<YieldTermStructure>();

  

/*********************

* BONDS TO BE PRICED *

**********************/

  

// Common data

final double faceAmount = 100;

  

// Pricing engine

final PricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure);

  

// Zero coupon bond

final ZeroCouponBond zeroCouponBond = new ZeroCouponBond(

settlementDays,

new UnitedStates(UnitedStates.Market.GOVERNMENTBOND),

faceAmount,

new Date(15,Month.August,2013),

BusinessDayConvention.Following,

116.92,

new Date(15,Month.August,2003));

  

zeroCouponBond.setPricingEngine(bondEngine);

  

// Fixed 4.5% US Treasury Note

final Schedule fixedBondSchedule = new Schedule(

new Date(15, Month.May, 2007),

new Date(15,Month.May,2017),

new Period(Frequency.Semiannual),

new UnitedStates(UnitedStates.Market.GOVERNMENTBOND),

BusinessDayConvention.Unadjusted,

BusinessDayConvention.Unadjusted,

DateGeneration.Rule.Backward, false);

  

final FixedRateBond fixedRateBond = new FixedRateBond(

settlementDays,

faceAmount,

fixedBondSchedule,

new double[]{0.045},

new ActualActual(ActualActual.Convention.Bond),

BusinessDayConvention.ModifiedFollowing,

100.0,

new Date(15, Month.May, 2007));

  

fixedRateBond.setPricingEngine(bondEngine);

  

// Floating rate bond (3M USD Libor + 0.1%)

// Should and will be priced on another curve later...

  

final RelinkableHandle<YieldTermStructure> liborTermStructure = new RelinkableHandle<YieldTermStructure>();

final IborIndex libor3m = new USDLibor(new Period(3, TimeUnit.Months), liborTermStructure);

libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625);

  

final Schedule floatingBondSchedule = new Schedule(

new Date(21, Month.October, 2005),

new Date(21, Month.October, 2010), new Period(Frequency.Quarterly),

new UnitedStates(UnitedStates.Market.NYSE),

BusinessDayConvention.Unadjusted,

BusinessDayConvention.Unadjusted,

DateGeneration.Rule.Backward, true);

  

final FloatingRateBond floatingRateBond = new FloatingRateBond(

settlementDays,

faceAmount,

floatingBondSchedule,

libor3m,

new Actual360(),

BusinessDayConvention.ModifiedFollowing,

2,

new Array(1).fill(1.0), //Gearings

new Array(1).fill(0.001),//Spreads

new Array(0), // Caps

new Array(0), // Floors

true, // Fixing in arrears

100.0,

new Date(21, Month.October, 2005));

  

floatingRateBond.setPricingEngine(bondEngine);

// optionLet volatilities

final double volatility = 0.0;

final Handle<OptionletVolatilityStructure> vol =

new Handle<OptionletVolatilityStructure>(

new ConstantOptionletVolatility(

settlementDays,

calendar,

BusinessDayConvention.ModifiedFollowing,

volatility,

new Actual365Fixed()));

  

// Coupon pricers

final IborCouponPricer pricer = new BlackIborCouponPricer(vol);

PricerSetter.setCouponPricer(floatingRateBond.cashflows(),pricer);

  

// Yield curve bootstrapping

forecastingTermStructure.linkTo(depoSwapTermStructure);

discountingTermStructure.linkTo(bondDiscountingTermStructur);

  

// We are using the depo & swap curve to estimate the future Libor

// rates

liborTermStructure.linkTo(depoSwapTermStructure);

  

/***************

* BOND PRICING *

****************/

  

QL.info("Results:");

  

System.out.println(" "

+ " " + "ZC"

+ " " + "Fixed"

+ " " + "Floating"

);

  

System.out.println( "Net present value"

+ " " + zeroCouponBond.NPV()

+ " " + fixedRateBond.NPV()

+ " " + floatingRateBond.NPV());

  

System.out.println("Clean Price "

+ " " +zeroCouponBond.cleanPrice()

+ " " +fixedRateBond.cleanPrice()

+ " " + floatingRateBond.cleanPrice()

);

  

System.out.println("Dirty price "

+ " " + zeroCouponBond.dirtyPrice()

+ " " + fixedRateBond.dirtyPrice()

+ " " + floatingRateBond.dirtyPrice()

);

  

System.out.println( "Accrued coupon "

+ " " + zeroCouponBond.accruedAmount()

+ " " + fixedRateBond.accruedAmount()

+ " " + floatingRateBond.accruedAmount()

);

System.out.println( "Previous coupon "

+ " " + "N/A" //zeroCouponBond

+ " " + fixedRateBond.previousCoupon()

+ " " + floatingRateBond.previousCoupon()

);

System.out.println( "Next coupon "

+ " " + "N/A" //zeroCouponBond

+ " " + fixedRateBond.nextCoupon()

+ " " + floatingRateBond.nextCoupon()

);

System.out.println( "Yield "

+ " " + zeroCouponBond.yield(new Actual360(),Compounding.Compounded, Frequency.Annual)

+ " " + fixedRateBond.yield(new Actual360(),Compounding.Compounded, Frequency.Annual)

+ " " + floatingRateBond.yield(new Actual360(),Compounding.Compounded, Frequency.Annual)

);

// Other computations

System.out.println("Sample indirect computations (for the floating rate bond): " );

System.out.println( "Yield to Clean Price: " +

floatingRateBond.cleanPrice(floatingRateBond.yield(new Actual360(),Compounding.Compounded,Frequency.Annual),new Actual360(),Compounding.Compounded,Frequency.Annual,settlementDate)

);

  

System.out.println("Clean Price to Yield: " +

floatingRateBond.yield(floatingRateBond.cleanPrice(),new Actual360(),Compounding.Compounded,Frequency.Annual,settlementDate)

);

  

/* "Yield to Price"

"Price to Yield"

*/

clock.stopClock();

clock.log();

}

}

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote