import junit.framework.TestCase; // Copied/Translated from http://www.quantlib.org/reference/a00728.html public class TestSwapValuation extends TestCase { public void testIt() { try { System.loadLibrary("QuantlibCppWrapper"); } catch (Throwable t) { t.printStackTrace(); fail(); } try { Calendar calendar = new TARGET(); Date settlementDate = new Date(25, Month.May, 2005); settlementDate = calendar.adjust(settlementDate); int fixingDays = 2; Date todaysDate = calendar.advance(settlementDate, -fixingDays, TimeUnit.Days); Settings.instance().setEvaluationDate(todaysDate); todaysDate = Settings.instance().evaluationDate(); System.out.println("Today: " + todaysDate.weekday() + ", " + todaysDate); System.out.println("Settlement date: " + todaysDate.weekday() + ", " + settlementDate); // deposits double d1wQuote=0.0382; double d1mQuote=0.0372; double d3mQuote=0.0363; double d6mQuote=0.0353; double d9mQuote=0.0348; double d1yQuote=0.0345; // FRAs double fra3x6Quote=0.037125; double fra6x9Quote=0.037125; double fra6x12Quote=0.037125; // futures double fut1Quote=96.2875; double fut2Quote=96.7875; double fut3Quote=96.9875; double fut4Quote=96.6875; double fut5Quote=96.4875; double fut6Quote=96.3875; double fut7Quote=96.2875; double fut8Quote=96.0875; // swaps double s2yQuote=0.037125; double s3yQuote=0.0398; double s5yQuote=0.0443; double s10yQuote=0.05165; double s15yQuote=0.055175; /******************** *** 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 SimpleQuote d1wRate = new SimpleQuote(d1wQuote); SimpleQuote d1mRate = new SimpleQuote(d1mQuote); SimpleQuote d3mRate = new SimpleQuote(d3mQuote); SimpleQuote d6mRate = new SimpleQuote(d6mQuote); SimpleQuote d9mRate = new SimpleQuote(d9mQuote); SimpleQuote d1yRate = new SimpleQuote(d1yQuote); // FRAs SimpleQuote fra3x6Rate = new SimpleQuote(fra3x6Quote); SimpleQuote fra6x9Rate = new SimpleQuote(fra6x9Quote); SimpleQuote fra6x12Rate = new SimpleQuote(fra6x12Quote); // futures SimpleQuote fut1Price = new SimpleQuote(fut1Quote); SimpleQuote fut2Price = new SimpleQuote(fut2Quote); SimpleQuote fut3Price = new SimpleQuote(fut3Quote); SimpleQuote fut4Price = new SimpleQuote(fut4Quote); SimpleQuote fut5Price = new SimpleQuote(fut5Quote); SimpleQuote fut6Price = new SimpleQuote(fut6Quote); SimpleQuote fut7Price = new SimpleQuote(fut7Quote); SimpleQuote fut8Price = new SimpleQuote(fut8Quote); // swaps SimpleQuote s2yRate = new SimpleQuote(s2yQuote); SimpleQuote s3yRate = new SimpleQuote(s3yQuote); SimpleQuote s5yRate = new SimpleQuote(s5yQuote); SimpleQuote s10yRate = new SimpleQuote(s10yQuote); SimpleQuote 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 DayCounter depositDayCounter = new Actual360(); DepositRateHelper d1w = new DepositRateHelper(new QuoteHandle(d1wRate), 1, TimeUnit.Weeks, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); DepositRateHelper d1m = new DepositRateHelper(new QuoteHandle(d1mRate), 1, TimeUnit.Months, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); DepositRateHelper d3m = new DepositRateHelper(new QuoteHandle(d3mRate), 3, TimeUnit.Months, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); DepositRateHelper d6m = new DepositRateHelper(new QuoteHandle(d6mRate), 6, TimeUnit.Months, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); DepositRateHelper d9m = new DepositRateHelper(new QuoteHandle(d9mRate), 9, TimeUnit.Months, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); DepositRateHelper d1y = new DepositRateHelper(new QuoteHandle(d1yRate), 1, TimeUnit.Years, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); // setup FRAs RateHelper fra3x6 = new FraRateHelper(new QuoteHandle(fra3x6Rate), 3, 6, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); RateHelper fra6x9 = new FraRateHelper(new QuoteHandle(fra6x9Rate), 6, 9, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); RateHelper fra6x12 = new FraRateHelper(new QuoteHandle(fra6x12Rate), 6, 12, fixingDays, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); // setup futures int futMonths = 3; Date imm = Date.nextIMMdate(settlementDate); RateHelper fut1 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut2 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut3 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut4 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut5 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut6 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut7 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); imm = Date.nextIMMdate(imm.plusDays(1)); RateHelper fut8 = new FuturesRateHelper( new QuoteHandle(fut1Price), imm, futMonths, calendar, BusinessDayConvention.ModifiedFollowing, depositDayCounter); // setup swaps Frequency swFixedLegFrequency = Frequency.Annual; BusinessDayConvention swFixedLegConvention = BusinessDayConvention.Unadjusted; DayCounter swFixedLegDayCounter = new Thirty360(Thirty360.Convention.European); Frequency swFloatingLegFrequency = Frequency.Semiannual; RateHelper s2y = new SwapRateHelper( new QuoteHandle(s2yRate), 2, TimeUnit.Years, fixingDays, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegFrequency, BusinessDayConvention.ModifiedFollowing); RateHelper s3y = new SwapRateHelper( new QuoteHandle(s3yRate), 3, TimeUnit.Years, fixingDays, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegFrequency, BusinessDayConvention.ModifiedFollowing); RateHelper s5y = new SwapRateHelper( new QuoteHandle(s5yRate), 5, TimeUnit.Years, fixingDays, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegFrequency, BusinessDayConvention.ModifiedFollowing); RateHelper s10y = new SwapRateHelper( new QuoteHandle(s10yRate), 10, TimeUnit.Years, fixingDays, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegFrequency, BusinessDayConvention.ModifiedFollowing); RateHelper s15y = new SwapRateHelper( new QuoteHandle(s15yRate), 15, TimeUnit.Years, fixingDays, calendar, swFixedLegFrequency, swFixedLegConvention, swFixedLegDayCounter, swFloatingLegFrequency, BusinessDayConvention.ModifiedFollowing); /********************* ** 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-swap curve RateHelperVector depoSwapInstruments = new RateHelperVector(); depoSwapInstruments.add(d1w); // should use push_back !!! 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, tolerance); // A depo-futures-swap curve RateHelperVector depoFutSwapInstruments = new RateHelperVector(); depoFutSwapInstruments.add(d1w); depoFutSwapInstruments.add(d1m); depoFutSwapInstruments.add(fut1); depoFutSwapInstruments.add(fut2); depoFutSwapInstruments.add(fut3); depoFutSwapInstruments.add(fut4); depoFutSwapInstruments.add(fut5); depoFutSwapInstruments.add(fut6); depoFutSwapInstruments.add(fut7); depoFutSwapInstruments.add(fut8); depoFutSwapInstruments.add(s3y); depoFutSwapInstruments.add(s5y); depoFutSwapInstruments.add(s10y); depoFutSwapInstruments.add(s15y); YieldTermStructure depoFutSwapTermStructure = new PiecewiseFlatForward(settlementDate, depoFutSwapInstruments, termStructureDayCounter, tolerance); // System.out.println("" + depoFutSwapTermStructure.discount(new Date(1, Month.January, 2007))); // A depo-FRA-swap curve RateHelperVector depoFRASwapInstruments = new RateHelperVector(); depoFRASwapInstruments.add(d1w); depoFRASwapInstruments.add(d1m); depoFRASwapInstruments.add(d3m); depoFRASwapInstruments.add(fra3x6); depoFRASwapInstruments.add(fra6x9); depoFRASwapInstruments.add(fra6x12); depoFRASwapInstruments.add(s2y); depoFRASwapInstruments.add(s3y); depoFRASwapInstruments.add(s5y); depoFRASwapInstruments.add(s10y); depoFRASwapInstruments.add(s15y); YieldTermStructure depoFRASwapTermStructure = new PiecewiseFlatForward(settlementDate, depoFRASwapInstruments, termStructureDayCounter, tolerance); System.out.println("Discount 1/1/2007 = " + depoFutSwapTermStructure.discount(new Date(1, Month.January, 2007))); // Term structures that will be used for pricing: // the one used for discounting cash flows YieldTermStructureHandle discountingTermStructure = new YieldTermStructureHandle(); YieldTermStructureHandle forecastingTermStructure = new YieldTermStructureHandle(); /********************* * SWAPS TO BE PRICED * **********************/ // constant nominal 1,000,000 Euro double nominal = 1000000.0; // fixed leg Frequency fixedLegFrequency = Frequency.Annual; BusinessDayConvention fixedLegConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention floatingLegConvention = BusinessDayConvention.ModifiedFollowing; DayCounter fixedLegDayCounter = new Thirty360(Thirty360.Convention.European); double fixedRate = 0.04; // floating leg Frequency floatingLegFrequency = Frequency.Semiannual; Xibor euriborIndex = new Euribor(6, TimeUnit.Months, forecastingTermStructure); // using the forecasting curve double spread = 0.0; int lenghtInYears = 5; boolean payFixedRate = true; Date maturity = calendar.advance(settlementDate, lenghtInYears, TimeUnit.Years, floatingLegConvention); Schedule fixedSchedule = new Schedule(calendar, settlementDate, maturity, fixedLegFrequency, fixedLegConvention); Schedule floatSchedule = new Schedule(calendar, settlementDate, maturity, floatingLegFrequency, floatingLegConvention); SimpleSwap spot5YearSwap = new SimpleSwap( payFixedRate, nominal, fixedSchedule, fixedRate, fixedLegDayCounter, floatSchedule, euriborIndex, fixingDays, spread, discountingTermStructure); Date fwdStart = calendar.advance(settlementDate, 1, TimeUnit.Years); Date fwdMaturity = calendar.advance(fwdStart, lenghtInYears, TimeUnit.Years, floatingLegConvention); Schedule fwdFixedSchedule = new Schedule(calendar, fwdStart, fwdMaturity, fixedLegFrequency, fixedLegConvention); Schedule fwdFloatSchedule = new Schedule(calendar, fwdStart, fwdMaturity, floatingLegFrequency, floatingLegConvention); SimpleSwap oneYearForward5YearSwap = new SimpleSwap( payFixedRate, nominal, fwdFixedSchedule, fixedRate, fixedLegDayCounter, fwdFloatSchedule, euriborIndex, fixingDays, spread, discountingTermStructure); double NPV = spot5YearSwap.NPV(); System.out.println(NPV); } catch (Throwable t) { t.printStackTrace(); } } }