package examples; import java.util.ArrayList; import org.quantlib.Actual360; import org.quantlib.Actual365Fixed; import org.quantlib.ActualActual; import org.quantlib.BlackIborCouponPricer; import org.quantlib.BusinessDayConvention; import org.quantlib.Calendar; import org.quantlib.ConstantOptionletVolatility; import org.quantlib.Date; import org.quantlib.DateGeneration; import org.quantlib.DayCounter; import org.quantlib.DepositRateHelper; import org.quantlib.DiscountingBondEngine; import org.quantlib.DoubleVector; import org.quantlib.Euribor6M; import org.quantlib.FixedRateBond; import org.quantlib.FixedRateBondHelper; import org.quantlib.FloatingRateBond; import org.quantlib.FloatingRateCouponPricer; import org.quantlib.Frequency; import org.quantlib.IborCouponPricer; import org.quantlib.IborIndex; import org.quantlib.Month; import org.quantlib.OptionletVolatilityStructureHandle; import org.quantlib.Period; import org.quantlib.PiecewiseFlatForward; import org.quantlib.PricingEngine; import org.quantlib.QuantLib; import org.quantlib.QuantLibJNI; import org.quantlib.QuoteHandle; import org.quantlib.QuoteVector; import org.quantlib.RateHelper; import org.quantlib.RateHelperVector; import org.quantlib.RelinkableQuoteHandleVector; import org.quantlib.RelinkableYieldTermStructureHandle; import org.quantlib.Schedule; import org.quantlib.SimpleQuote; import org.quantlib.SwapRateHelper; import org.quantlib.TARGET; import org.quantlib.Thirty360; import org.quantlib.TimeUnit; import org.quantlib.USDLibor; import org.quantlib.UnitedStates; import org.quantlib.YieldTermStructure; import org.quantlib.ZeroCouponBond; public class Bonds { static { try { System.loadLibrary("QuantLibJNI"); } catch (RuntimeException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { // MARKET DATA Calendar cal = new TARGET(); Date settlementDate = new Date(18, Month.September, 2008); //must be a business day settlementDate = cal.adjust(settlementDate); int fixingDays = 3; int settlementdays = 3; Period period = new Period(-fixingDays, TimeUnit.Days); Date todayDate = cal.advance(settlementDate, period); System.out.println("Today: " + todayDate.weekday() + ", " + todayDate); System.out.println("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 dependant 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 QuoteHandle zc3mRate = new QuoteHandle(new SimpleQuote(0.0096)); QuoteHandle zc6mRate = new QuoteHandle(new SimpleQuote(0.0145)); QuoteHandle zc1yRate = new QuoteHandle(new SimpleQuote(0.0194)); //QuoteHandle rate, Period tenor, long fixingDays, Calendar calendar, //BusinessDayConvention convention, boolean endOfMonth, DayCounter dayCounter DayCounter zcBondsDayCounter = new Actual365Fixed(); Period tenor = new Period(3, TimeUnit.Months); DepositRateHelper zc3m = new DepositRateHelper(zc3mRate, tenor, fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); DepositRateHelper zc6m = new DepositRateHelper(zc6mRate, tenor, fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); DepositRateHelper zc1y = new DepositRateHelper(zc1yRate, tenor, fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, zcBondsDayCounter); // setup bonds double redemption = 100.0; final int numberOfBonds = 5; 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), }; 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), }; double couponRates[] = { 0.02375, 0.04625, 0.03125, 0.04000, 0.04500 }; double marketQuotes[] = { 100.390625, 106.21875, 100.59375, 101.6875, 102.140625 }; QuoteVector quote = new QuoteVector(); for (int i=0; i<numberOfBonds; i++){ quote.add(new SimpleQuote(marketQuotes[i])); } RelinkableQuoteHandleVector quoteHandle = new RelinkableQuoteHandleVector(numberOfBonds); for (int i=0; i<numberOfBonds; i++){ quoteHandle.get(i).linkTo(quote.get(i)); } DoubleVector couponsVector = new DoubleVector(); for (int i=0; i<numberOfBonds; i++){ couponsVector.add(couponRates[i]);; } ArrayList<FixedRateBondHelper> bondHelpers = new ArrayList<FixedRateBondHelper>(); // Definition of the rate helpers for (int i=0; i<numberOfBonds;i++){ 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); //QuoteHandle cleanPrice, long settlementDays, double faceAmount, //Schedule schedule, DoubleVector coupons, DayCounter paymentDayCounter, //BusinessDayConvention paymentConvention, double redemption, Date issueDate DayCounter dayCountConvBond = new ActualActual(ActualActual.Convention.Bond); FixedRateBondHelper bondHelper = new FixedRateBondHelper(quoteHandle.get(i), settlementdays, 100.0, schedule, couponsVector, dayCountConvBond, BusinessDayConvention.Unadjusted, redemption, issueDates[i]); bondHelpers.add(bondHelper); } // CURVE BUILDING // Any DayCounter would be fine // ActualActual::ISDA ensures that 30 years is 30.0 DayCounter termStructureDayCounter = new ActualActual(ActualActual.Convention.ISDA); //double tolerance = 1.0e-15; // A depo-bond curve RateHelperVector bondInstruments = new RateHelperVector(); // 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(bondHelpers.get(i)); } //Date referenceDate, RateHelperVector instruments, //DayCounter dayCounter YieldTermStructure bondDiscountingTermStructure = new PiecewiseFlatForward(settlementDate,bondInstruments, termStructureDayCounter); // Building of the Libor forecasting curve //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 QuoteHandle d1wQuoteHandle = new QuoteHandle(new SimpleQuote(0.043375)); QuoteHandle d1mQuoteHandle = new QuoteHandle(new SimpleQuote(0.031875)); QuoteHandle d3mQuoteHandle = new QuoteHandle(new SimpleQuote(0.0320375)); QuoteHandle d6mQuoteHandle = new QuoteHandle(new SimpleQuote(0.03385)); QuoteHandle d9mQuoteHandle = new QuoteHandle(new SimpleQuote(0.0338125)); QuoteHandle d1yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0335125)); //swaps QuoteHandle s2yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0295)); QuoteHandle s3yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0323)); QuoteHandle s5yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0359)); QuoteHandle s10yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0412)); QuoteHandle s15yQuoteHandle = new QuoteHandle(new SimpleQuote(0.0433)); // 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 DayCounter depositDayCounter = new Actual360(); //QuoteHandle rate, Period tenor, long fixingDays, Calendar calendar, //BusinessDayConvention convention, boolean endOfMonth, //DayCounter dayCounter RateHelper d1w = new DepositRateHelper(d1wQuoteHandle, new Period(1, TimeUnit.Weeks), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1m = new DepositRateHelper(d1mQuoteHandle, new Period(3, TimeUnit.Months), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d3m = new DepositRateHelper(d3mQuoteHandle, new Period(3, TimeUnit.Months), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d6m = new DepositRateHelper(d6mQuoteHandle, new Period(6, TimeUnit.Months), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d9m = new DepositRateHelper(d9mQuoteHandle, new Period(9, TimeUnit.Months), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); RateHelper d1y = new DepositRateHelper(d1yQuoteHandle, new Period(1, TimeUnit.Years), fixingDays, cal, BusinessDayConvention.ModifiedFollowing, true, depositDayCounter); // setup swaps Frequency swFixedLegFrequency = Frequency.Annual; BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Convention.European); IborIndex swFloatingLegIndex = new Euribor6M(); Period forwardStart = new Period(1, TimeUnit.Days); //QuoteHandle rate, Period tenor, Calendar calendar, //Frequency fixedFrequency, BusinessDayConvention fixedConvention, //DayCounter fixedDayCount, IborIndex index, QuoteHandle spread, Period fwdStart QuoteHandle spread = new QuoteHandle(); RateHelper s2y = new SwapRateHelper(s2yQuoteHandle,new Period(2, TimeUnit.Years), cal, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, spread, forwardStart); RateHelper s3y = new SwapRateHelper(s3yQuoteHandle,new Period(3, TimeUnit.Years), cal, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, spread, forwardStart); RateHelper s5y = new SwapRateHelper(s5yQuoteHandle,new Period(5, TimeUnit.Years), cal, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, spread, forwardStart); RateHelper s10y = new SwapRateHelper(s10yQuoteHandle,new Period(10, TimeUnit.Years), cal, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, spread, forwardStart); RateHelper s15y = new SwapRateHelper(s15yQuoteHandle,new Period(15, TimeUnit.Years), cal, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegIndex, spread, forwardStart); // CURVE BUILDING // Any DayCounter would be fine. // ActualActual/ISDA ensures that 30 years is 30.0 // A depo-swap curve RateHelperVector depoSwapInstruments = new RateHelperVector(); 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); YieldTermStructure depoSwapTermStructure = new PiecewiseFlatForward( settlementDate,depoSwapInstruments, termStructureDayCounter); // Term structures that will be used for pricing // the one used for discounting cash flows RelinkableYieldTermStructureHandle discountingTermStructure = new RelinkableYieldTermStructureHandle(); RelinkableYieldTermStructureHandle forecastingTermStructure = new RelinkableYieldTermStructureHandle(); // BONDS TO BE PRICED // Common data double faceAmount = 100.0; // Price engine PricingEngine bondEngine = new DiscountingBondEngine(discountingTermStructure); // Zero coupon bond //long settlementDays, Calendar calendar, double faceAmount, Date maturityDate, //BusinessDayConvention paymentConvention, double redemption, Date issueDate 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 Schedule fixedRateBondSchedule = 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); DoubleVector rateVector = new DoubleVector(); rateVector.add(1); rateVector.add(0.045); //int settlementDays, double faceAmount, Schedule schedule, // DoubleVector coupons, DayCounter paymentDayCounter, //BusinessDayConvention paymentConvention, double redemption, Date issueDate FixedRateBond fixedRateBond = new FixedRateBond( settlementdays, faceAmount, fixedRateBondSchedule, rateVector, new ActualActual(ActualActual.Convention.Bond), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(15, Month.May, 2007)); fixedRateBond.setPricingEngine(bondEngine); RelinkableYieldTermStructureHandle liborTermStructure = new RelinkableYieldTermStructureHandle(); IborIndex libor3m = new USDLibor( new Period(3, TimeUnit.Months), liborTermStructure); libor3m.addFixing(new Date(17, Month.July, 2008), 0.0278625); 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); //long settlementDays, double faceAmount, Schedule schedule, IborIndex index, //DayCounter paymentDayCounter, BusinessDayConvention paymentConvention, //long fixingDays, DoubleVector gearings, DoubleVector spreads, //DoubleVector caps, DoubleVector floors, boolean inArrears, double redemption, //Date issueDate DoubleVector gearings = new DoubleVector(); gearings.add(1); gearings.add(1.0); DoubleVector spreads = new DoubleVector(); spreads.add(1); spreads.add(0.001); DoubleVector caps = new DoubleVector(); DoubleVector floors = new DoubleVector(); FloatingRateBond floatingRateBond = new FloatingRateBond( settlementdays, faceAmount, floatingBondSchedule, libor3m, new Actual360(), BusinessDayConvention.ModifiedFollowing, 2, gearings, spreads, caps, floors, true, 100.0, new Date(21, Month.October, 2005)); floatingRateBond.setPricingEngine(bondEngine); IborCouponPricer pricer = new BlackIborCouponPricer(); OptionletVolatilityStructureHandle volatility = new OptionletVolatilityStructureHandle(new ConstantOptionletVolatility( settlementdays, cal, BusinessDayConvention.ModifiedFollowing, 0.0, new Actual365Fixed() )); pricer.setCapletVolatility(volatility); QuantLib.setCouponPricer(floatingRateBond.cashflows(), pricer); //Yield curve bootstrapping discountingTermStructure.linkTo(bondDiscountingTermStructure); forecastingTermStructure.linkTo(depoSwapTermStructure); // We are using the depo & swap curve to esitmate the future Libor rates liborTermStructure.linkTo(depoSwapTermStructure); //System.out.println("NPV: " + zeroCouponBond.NPV()); System.out.println("ZC Dirty Price: " + zeroCouponBond.dirtyPrice()); System.out.println("ZC Clean Price: " + zeroCouponBond.cleanPrice()); System.out.println("Fixed Rate Bond Dirty Price: " + fixedRateBond.dirtyPrice()); System.out.println("Fixed Rate Bond Clean Price: " + fixedRateBond.cleanPrice()); System.out.println("Floating Rate Bond Dirty Price: " + floatingRateBond.dirtyPrice()); System.out.println("Floating Rate Bond Clean Price: " + floatingRateBond.cleanPrice()); System.out.println("End"); } }