public void testCachedValue() { //"Testing swaption value against cached value..."); CommonVars vars = new CommonVars(); vars.today = new Date(13, 3, 2002); vars.settlement = new Date(15, 3, 2002); Settings.setEvaluationDate( vars.today); vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.05, new Actual365Fixed())); Date exerciseDate = vars.calendar.advance(vars.settlement, new Period(5,TimeUnit.Years)); Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays,TimeUnit.Days); VanillaSwap swap = new MakeVanillaSwap(new Period(10,TimeUnit.Years), vars.index, 0.06) .withEffectiveDate(startDate); Swaption swaption = vars.makeSwaption(swap, exerciseDate, 0.20); //#if QL_USE_INDEXED_COUPON double cachedNPV = 0.036418158579; //#else // double cachedNPV = 0.036421429684; //#endif // FLOATING_POINT_EXCEPTION if (Math.Abs(swaption.NPV()-cachedNPV) > 1.0e-12) Assert.Fail ("failed to reproduce cached swaption value:\n" + //QL_FIXED + std::setprecision(12) + "\ncalculated: " + swaption.NPV() + "\nexpected: " + cachedNPV); }
public void testFlatInterpolationLeft() { // Testing flat interpolation before the first spreaded date... CommonVars vars = new CommonVars(); List<Handle<Quote>> spreads = new List<Handle<Quote>>(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.03); spreads.Add(new Handle<Quote>(spread1)); spreads.Add(new Handle<Quote>(spread2)); List<Date> spreadDates = new List<Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 8, TimeUnit.Months)); spreadDates.Add(vars.calendar.advance(vars.today, 15, TimeUnit.Months)); Date interpolationDate = vars.calendar.advance(vars.today, 6, TimeUnit.Months); ZeroYieldStructure spreadedTermStructure = new PiecewiseZeroSpreadedTermStructure( new Handle<YieldTermStructure>(vars.termStructure), spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + spread1.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) Assert.Fail("unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); }
public void testFairRate() { //("Testing vanilla-swap calculation of fair fixed rate..."); CommonVars vars = new CommonVars(); int[] lengths = new int[] { 1, 2, 5, 10, 20 }; double[] spreads = new double[] { -0.001, -0.01, 0.0, 0.01, 0.001 }; for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < spreads.Length; j++) { VanillaSwap swap = vars.makeSwap(lengths[i], 0.0, spreads[j]); swap = vars.makeSwap(lengths[i], swap.fairRate(), spreads[j]); if (Math.Abs(swap.NPV()) > 1.0e-10) { Assert.Fail("recalculating with implied rate:\n" + " length: " + lengths[i] + " years\n" + " floating spread: " + spreads[j] + "\n" + " swap value: " + swap.NPV()); } } } }
public void testCachedValue() { // Testing Black yoy inflation cap/floor price against cached values... CommonVars vars = new CommonVars(); int whichPricer = 0; // black double K = 0.0295; // one centi-point is fair rate error i.e. < 1 cp int j = 2; List<CashFlow> leg = vars.makeYoYLeg(vars.evaluationDate,j); Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); // close to atm prices double cachedCapNPVblack = 219.452; double cachedFloorNPVblack = 314.641; // N.B. notionals are 10e6. Assert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVblack)<0.02,"yoy cap cached NPV wrong " +cap.NPV()+" should be "+cachedCapNPVblack+" Black pricer" +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVblack))); Assert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVblack)<0.02,"yoy floor cached NPV wrong " +floor.NPV()+" should be "+cachedFloorNPVblack+" Black pricer" +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVblack))); whichPricer = 1; // dd cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); // close to atm prices double cachedCapNPVdd = 9114.61; double cachedFloorNPVdd = 9209.8; // N.B. notionals are 10e6. Assert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVdd)<0.22,"yoy cap cached NPV wrong " +cap.NPV()+" should be "+cachedCapNPVdd+" dd Black pricer" +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVdd))); Assert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVdd)<0.22,"yoy floor cached NPV wrong " +floor.NPV()+" should be "+cachedFloorNPVdd+" dd Black pricer" +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVdd))); whichPricer = 2; // bachelier cap = vars.makeYoYCapFloor(CapFloorType.Cap,leg, K, 0.01, whichPricer); floor = vars.makeYoYCapFloor(CapFloorType.Floor,leg, K, 0.01, whichPricer); // close to atm prices double cachedCapNPVbac = 8852.4; double cachedFloorNPVbac = 8947.59; // N.B. notionals are 10e6. Assert.IsTrue(Math.Abs(cap.NPV()-cachedCapNPVbac)<0.22,"yoy cap cached NPV wrong " +cap.NPV()+" should be "+cachedCapNPVbac+" bac Black pricer" +" diff was "+(Math.Abs(cap.NPV()-cachedCapNPVbac))); Assert.IsTrue(Math.Abs(floor.NPV()-cachedFloorNPVbac)<0.22,"yoy floor cached NPV wrong " +floor.NPV()+" should be "+cachedFloorNPVbac+" bac Black pricer" +" diff was "+(Math.Abs(floor.NPV()-cachedFloorNPVbac))); // remove circular refernce vars.hy.linkTo(new YoYInflationTermStructure()); }
public void testATMRate() { CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; Date startDate = vars.termStructure.link.referenceDate(); for (int i = 0; i < lengths.Length; i++) { List<CashFlow> leg = vars.makeLeg(startDate, lengths[i]); Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); Schedule schedule = new Schedule(startDate, maturity, new Period(vars.frequency), vars.calendar, vars.convention, vars.convention, DateGeneration.Rule.Forward, false); for (int j = 0; j < strikes.Length; j++) { for (int k = 0; k < vols.Length; k++) { CapFloor cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); CapFloor floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); double capATMRate = cap.atmRate(vars.termStructure); double floorATMRate = floor.atmRate(vars.termStructure); if (!checkAbsError(floorATMRate, capATMRate, 1.0e-10)) Assert.Fail( "Cap ATM Rate and floor ATM Rate should be equal :\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[k] + "\n" + " strike: " + strikes[j] + "\n" + " cap ATM rate: " + capATMRate + "\n" + " floor ATM rate:" + floorATMRate + "\n" + " relative Error:" + Utilities.relativeError(capATMRate, floorATMRate, capATMRate) * 100 + "%"); VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], schedule, floorATMRate, vars.index.dayCounter(), schedule, vars.index, 0.0, vars.index.dayCounter()); swap.setPricingEngine((IPricingEngine)( new DiscountingSwapEngine(vars.termStructure))); double swapNPV = swap.NPV(); if (!checkAbsError(swapNPV, 0, 1.0e-10)) Assert.Fail( "the NPV of a Swap struck at ATM rate " + "should be equal to 0:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[k] + "\n" + " ATM rate: " + floorATMRate + "\n" + " swap NPV: " + swapNPV); } } } }
public void testLinearZeroConsistency() { // "Testing consistency of piecewise-linear zero-yield curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ZeroYield, Linear, IterativeBootstrapForYield>(vars); testBMACurveConsistency <ZeroYield, Linear, IterativeBootstrapForYield>(vars); }
public void testLinearDiscountConsistency() { // "Testing consistency of piecewise-linear discount curve..." CommonVars vars = new CommonVars(); testCurveConsistency <Discount, Linear, IterativeBootstrapForYield>(vars); testBMACurveConsistency <Discount, Linear, IterativeBootstrapForYield>(vars); }
public void testLocalBootstrapConsistency() { //"Testing consistency of local-bootstrap algorithm..."); CommonVars vars = new CommonVars(); testCurveConsistency <ForwardRate, ConvexMonotone, LocalBootstrapForYield>(vars, new ConvexMonotone(), 1.0e-7); testBMACurveConsistency <ForwardRate, ConvexMonotone, LocalBootstrapForYield>(vars, new ConvexMonotone(), 1.0e-9); }
public void testConvexMonotoneForwardConsistency() { //"Testing consistency of convex monotone forward-rate curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ForwardRate, ConvexMonotone, IterativeBootstrapForYield>(vars); testBMACurveConsistency <ForwardRate, ConvexMonotone, IterativeBootstrapForYield>(vars); }
public void testFlatForwardConsistency() { //"Testing consistency of piecewise-flat forward-rate curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ForwardRate, BackwardFlat, IterativeBootstrapForYield>(vars); testBMACurveConsistency <ForwardRate, BackwardFlat, IterativeBootstrapForYield>(vars); }
public void testSwaptionVolMatrixCoherence() { // Set evaluation date Settings.Instance.setEvaluationDate(Date.Today); // Testing swaption volatility matrix CommonVars vars = new CommonVars(); SwaptionVolatilityMatrix vol; string description; //floating reference date, floating market data description = "floating reference date, floating market data"; vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); //fixed reference date, floating market data description = "fixed reference date, floating market data"; vol = new SwaptionVolatilityMatrix(Settings.Instance.evaluationDate(), vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); // floating reference date, fixed market data description = "floating reference date, fixed market data"; vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); // fixed reference date, fixed market data description = "fixed reference date, fixed market data"; vol = new SwaptionVolatilityMatrix(Settings.Instance.evaluationDate(), vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); }
public void testLinearForwardConsistency() { // "Testing consistency of piecewise-linear forward-rate curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ForwardRate, Linear, IterativeBootstrapForYield>(vars); testBMACurveConsistency <ForwardRate, Linear, IterativeBootstrapForYield>(vars); }
public void zciisconsistency() { CommonVars common = new CommonVars(); ZeroCouponInflationSwap.Type ztype = ZeroCouponInflationSwap.Type.Payer; double nominal = 1000000.0; Date startDate = new Date(common.evaluationDate); Date endDate = new Date(25, Month.November, 2059); Calendar cal = new UnitedKingdom(); BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing; DayCounter dummyDC = null, dc = new ActualActual(); Period observationLag = new Period(2, TimeUnit.Months); double quote = 0.03714; ZeroCouponInflationSwap zciis = new ZeroCouponInflationSwap(ztype, nominal, startDate, endDate, cal, paymentConvention, dc, quote, common.ii, observationLag); // simple structure so simple pricing engine - most work done by index DiscountingSwapEngine dse = new DiscountingSwapEngine(common.nominalUK); zciis.setPricingEngine(dse); QAssert.IsTrue(Math.Abs(zciis.NPV()) < 1e-3, "zciis does not reprice to zero"); List <Date> oneDate = new List <Date>(); oneDate.Add(endDate); Schedule schOneDate = new Schedule(oneDate, cal, paymentConvention); CPISwap.Type stype = CPISwap.Type.Payer; double inflationNominal = nominal; double floatNominal = inflationNominal * Math.Pow(1.0 + quote, 50); bool subtractInflationNominal = true; double dummySpread = 0.0, dummyFixedRate = 0.0; int fixingDays = 0; Date baseDate = startDate - observationLag; double baseCPI = common.ii.fixing(baseDate); IborIndex dummyFloatIndex = new IborIndex(); CPISwap cS = new CPISwap(stype, floatNominal, subtractInflationNominal, dummySpread, dummyDC, schOneDate, paymentConvention, fixingDays, dummyFloatIndex, dummyFixedRate, baseCPI, dummyDC, schOneDate, paymentConvention, observationLag, common.ii, InterpolationType.AsIndex, inflationNominal); cS.setPricingEngine(dse); QAssert.IsTrue(Math.Abs(cS.NPV()) < 1e-3, "CPISwap as ZCIIS does not reprice to zero"); for (int i = 0; i < 2; i++) { double cs = cS.legNPV(i).GetValueOrDefault(); double z = zciis.legNPV(i).GetValueOrDefault(); QAssert.IsTrue(Math.Abs(cs - z) < 1e-3, "zciis leg does not equal CPISwap leg"); } // remove circular refernce common.hcpi.linkTo(null); }
public void testFlatTermVolatilityStripping1() { // Testing forward/forward vol stripping from flat term vol // surface using OptionletStripper1 class... CommonVars vars = new CommonVars(); Settings.setEvaluationDate(new Date(28, Month.October, 2013)); vars.setFlatTermVolSurface(); IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); OptionletStripper optionletStripper1 = new OptionletStripper1(vars.flatTermVolSurface, iborIndex, null, vars.accuracy); StrippedOptionletAdapter strippedOptionletAdapter = new StrippedOptionletAdapter(optionletStripper1); Handle <OptionletVolatilityStructure> vol = new Handle <OptionletVolatilityStructure>(strippedOptionletAdapter); vol.link.enableExtrapolation(); BlackCapFloorEngine strippedVolEngine = new BlackCapFloorEngine(vars.yieldTermStructure, vol); CapFloor cap; for (int tenorIndex = 0; tenorIndex < vars.optionTenors.Count; ++tenorIndex) { for (int strikeIndex = 0; strikeIndex < vars.strikes.Count; ++strikeIndex) { cap = new MakeCapFloor(CapFloorType.Cap, vars.optionTenors[tenorIndex], iborIndex, vars.strikes[strikeIndex], new Period(0, TimeUnit.Days)) .withPricingEngine(strippedVolEngine); double priceFromStrippedVolatility = cap.NPV(); IPricingEngine blackCapFloorEngineConstantVolatility = new BlackCapFloorEngine(vars.yieldTermStructure, vars.termV[tenorIndex, strikeIndex]); cap.setPricingEngine(blackCapFloorEngineConstantVolatility); double priceFromConstantVolatility = cap.NPV(); double error = Math.Abs(priceFromStrippedVolatility - priceFromConstantVolatility); if (error > vars.tolerance) { QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + "\nstrike: " + vars.strikes[strikeIndex] + "\nstripped vol price: " + priceFromStrippedVolatility + "\nconstant vol price: " + priceFromConstantVolatility + "\nerror: " + error + "\ntolerance: " + vars.tolerance); } } } }
public void testVega() { CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 30 }; double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; double[] strikes = { 0.01, 0.02, 0.03, 0.04, 0.05, 0.06, 0.07, 0.08, 0.09 }; CapFloorType[] types = { CapFloorType.Cap, CapFloorType.Floor }; Date startDate = vars.termStructure.link.referenceDate(); double shift = 1e-8; double tolerance = 0.005; for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < vols.Length; j++) { for (int k = 0; k < strikes.Length; k++) { for (int h = 0; h < types.Length; h++) { List <CashFlow> leg = vars.makeLeg(startDate, lengths[i]); CapFloor capFloor = vars.makeCapFloor(types[h], leg, strikes[k], vols[j]); CapFloor shiftedCapFloor2 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] + shift); CapFloor shiftedCapFloor1 = vars.makeCapFloor(types[h], leg, strikes[k], vols[j] - shift); double value1 = shiftedCapFloor1.NPV(); double value2 = shiftedCapFloor2.NPV(); double numericalVega = (value2 - value1) / (2 * shift); if (numericalVega > 1.0e-4) { double analyticalVega = (double)capFloor.result("vega"); double discrepancy = Math.Abs(numericalVega - analyticalVega); discrepancy /= numericalVega; if (discrepancy > tolerance) { QAssert.Fail( "failed to compute cap/floor vega:" + "\n lengths: " + new Period(lengths[j], TimeUnit.Years) + "\n strike: " + strikes[k] + "\n types: " + types[h] + "\n calculated: " + analyticalVega + "\n expected: " + numericalVega + "\n discrepancy: " + discrepancy + "\n tolerance: " + tolerance); } } } } } } }
public void testSwaptionVolMatrixCoherence() { //"Testing swaption volatility matrix..."); CommonVars vars = new CommonVars(); SwaptionVolatilityMatrix vol; string description; //floating reference date, floating market data description = "floating reference date, floating market data"; vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); //fixed reference date, floating market data description = "fixed reference date, floating market data"; vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); // floating reference date, fixed market data description = "floating reference date, fixed market data"; vol = new SwaptionVolatilityMatrix(vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); // fixed reference date, fixed market data description = "fixed reference date, fixed market data"; vol = new SwaptionVolatilityMatrix(Settings.evaluationDate(), vars.conventions.calendar, vars.conventions.optionBdc, vars.atm.tenors.options, vars.atm.tenors.swaps, vars.atm.volsHandle, vars.conventions.dayCounter); vars.makeCoherenceTest(description, vol); }
public void cpicapfloorpricesurface() { // check inflation leg vs calculation directly from inflation TS CommonVars common = new CommonVars(); double nominal = 1.0; InterpolatedCPICapFloorTermPriceSurface <Bilinear> cpiSurf = new InterpolatedCPICapFloorTermPriceSurface <Bilinear>( nominal, common.baseZeroRate, common.observationLag, common.calendar, common.convention, common.dcZCIIS, common.hii, common.nominalUK, common.cStrikesUK, common.fStrikesUK, common.cfMaturitiesUK, common.cPriceUK, common.fPriceUK); // test code - note order of indices for (int i = 0; i < common.fStrikesUK.Count; i++) { double qK = common.fStrikesUK[i]; int nMat = common.cfMaturitiesUK.Count; for (int j = 0; j < nMat; j++) { Period t = common.cfMaturitiesUK[j]; double a = common.fPriceUK[i, j]; double b = cpiSurf.floorPrice(t, qK); Utils.QL_REQUIRE(Math.Abs(a - b) < 1e-7, () => "cannot reproduce cpi floor data from surface: " + a + " vs constructed = " + b); } } for (int i = 0; i < common.cStrikesUK.Count; i++) { double qK = common.cStrikesUK[i]; int nMat = common.cfMaturitiesUK.Count; for (int j = 0; j < nMat; j++) { Period t = common.cfMaturitiesUK[j]; double a = common.cPriceUK[i, j]; double b = cpiSurf.capPrice(t, qK); QAssert.IsTrue(Math.Abs(a - b) < 1e-7, "cannot reproduce cpi cap data from surface: " + a + " vs constructed = " + b); } } // remove circular refernce common.hcpi.linkTo(null); }
private static bool pReadQuiltCSVFile(ref CommonVars commonVars, string fileName) { bool reading = false; try { using (StreamReader sr = new(fileName)) { reading = true; char[] csvSeparators = { ',' }; // Read in non-CSV data first // Pattern line string check = sr.ReadLine(); // ReSharper disable once PossibleNullReferenceException if (!check.StartsWith("Quilt")) { return(false); } // Now we have the meat of the data we need. string tempString = sr.ReadLine(); string[] parsedString = tempString.Split(csvSeparators); if (parsedString.Length >= 6) { // We have 6 values to extract from this line. // X-offset, Y-offset, X pitch, Y pitch, rows, cols // Convert from um to nm in the process. // Take the second result of the split which is the numeric value. Convert it to double, multiply by 1000 to convert units. Make int. commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colOffset, Convert.ToDouble(parsedString[0])); commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowOffset, Convert.ToDouble(parsedString[1])); commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.colPitch, Convert.ToDouble(parsedString[2])); commonVars.getSimulationSettings().getDOESettings().setDouble(DOESettings.properties_d.rowPitch, Convert.ToDouble(parsedString[3])); commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.rows, Convert.ToInt32(parsedString[4])); commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.cols, Convert.ToInt32(parsedString[5])); } else { // We need to break here. ErrorReporter.showMessage_OK("CSV file doesn't match expectations.", "Aborting."); return(false); } } reading = false; } catch (Exception) { return(reading); } commonVars.getSimulationSettings().getDOESettings().setBool(DOESettings.properties_b.quilt, true); commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.uTileList, 0); commonVars.getSimulationSettings().getDOESettings().setInt(DOESettings.properties_i.sTile, 0); return(reading); }
public void testSetInterpolationFactory() { // Testing factory constructor with additional parameters... CommonVars vars = new CommonVars(); List <Handle <Quote> > spreads = new List <Handle <Quote> >(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.03); SimpleQuote spread3 = new SimpleQuote(0.01); spreads.Add(new Handle <Quote>(spread1)); spreads.Add(new Handle <Quote>(spread2)); spreads.Add(new Handle <Quote>(spread3)); List <Date> spreadDates = new List <Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 8, TimeUnit.Months)); spreadDates.Add(vars.calendar.advance(vars.today, 15, TimeUnit.Months)); spreadDates.Add(vars.calendar.advance(vars.today, 25, TimeUnit.Months)); Date interpolationDate = vars.calendar.advance(vars.today, 11, TimeUnit.Months); ZeroYieldStructure spreadedTermStructure; Frequency freq = Frequency.NoFrequency; Cubic factory = new Cubic(CubicInterpolation.DerivativeApprox.Spline, false, CubicInterpolation.BoundaryCondition.SecondDerivative, 0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0); spreadedTermStructure = new InterpolatedPiecewiseZeroSpreadedTermStructure <Cubic>( new Handle <YieldTermStructure>(vars.termStructure), spreads, spreadDates, vars.compounding, freq, vars.dayCount, factory); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + 0.026065770863; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) { QAssert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); } }
public void testTermVolatilityStripping2() { // Testing forward/forward vol stripping from non-flat term vol " // surface using OptionletStripper2 class..."); CommonVars vars = new CommonVars(); Settings.setEvaluationDate(Date.Today); vars.setCapFloorTermVolCurve(); vars.setCapFloorTermVolSurface(); IborIndex iborIndex = new Euribor6M(vars.yieldTermStructure); // optionletstripper1 OptionletStripper1 optionletStripper1 = new OptionletStripper1(vars.capFloorVolSurface, iborIndex, null, vars.accuracy); StrippedOptionletAdapter strippedOptionletAdapter1 = new StrippedOptionletAdapter(optionletStripper1); Handle <OptionletVolatilityStructure> vol1 = new Handle <OptionletVolatilityStructure>(strippedOptionletAdapter1); vol1.link.enableExtrapolation(); // optionletstripper2 OptionletStripper optionletStripper2 = new OptionletStripper2(optionletStripper1, vars.capFloorVolCurve); StrippedOptionletAdapter strippedOptionletAdapter2 = new StrippedOptionletAdapter(optionletStripper2); Handle <OptionletVolatilityStructure> vol2 = new Handle <OptionletVolatilityStructure>(strippedOptionletAdapter2); vol2.link.enableExtrapolation(); // consistency check: diff(stripped vol1-stripped vol2) for (int strikeIndex = 0; strikeIndex < vars.strikes.Count; ++strikeIndex) { for (int tenorIndex = 0; tenorIndex < vars.optionTenors.Count; ++tenorIndex) { double strippedVol1 = vol1.link.volatility(vars.optionTenors[tenorIndex], vars.strikes[strikeIndex], true); double strippedVol2 = vol2.link.volatility(vars.optionTenors[tenorIndex], vars.strikes[strikeIndex], true); // vol from flat vol surface (for comparison only) double flatVol = vars.capFloorVolSurface.volatility(vars.optionTenors[tenorIndex], vars.strikes[strikeIndex], true); double error = Math.Abs(strippedVol1 - strippedVol2); if (error > vars.tolerance) { QAssert.Fail("\noption tenor: " + vars.optionTenors[tenorIndex] + "\nstrike: " + (vars.strikes[strikeIndex]) + "\nstripped vol1: " + (strippedVol1) + "\nstripped vol2: " + (strippedVol2) + "\nflat vol: " + (flatVol) + "\nerror: " + (error) + "\ntolerance: " + (vars.tolerance)); } } } }
private void init(int number, bool previewMode, bool doPASearch, ref CommonVars commonVars) { dimensions = ChaosSettings.getDimensions(); _commonVars = commonVars; if (_commonVars.getSimulationSettings().getValue(EntropySettings.properties_i.linkCDU) == 1) { dimensions -= 3; } sampleCount = number; pMode = previewMode; paSearch = doPASearch; }
public void testQuoteChanging() { // Testing quote update... CommonVars vars = new CommonVars(); List <Handle <Quote> > spreads = new List <Handle <Quote> >(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.03); spreads.Add(new Handle <Quote>(spread1)); spreads.Add(new Handle <Quote>(spread2)); List <Date> spreadDates = new List <Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 100, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 150, TimeUnit.Days)); Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = new InterpolatedPiecewiseZeroSpreadedTermStructure <BackwardFlat>( new Handle <YieldTermStructure>(vars.termStructure), spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.settlementDate, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + 0.03; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) { QAssert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); } spread2.setValue(0.025); interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + 0.025; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) { QAssert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); } }
//[TestMethod()] public void testLogCubicDiscountConsistency() { // "Testing consistency of piecewise-log-cubic discount curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <Discount, LogCubic, IterativeBootstrapForYield>(vars, new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency <Discount, LogCubic, IterativeBootstrapForYield>(vars, new LogCubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); }
private void core(VarianceContext _varianceContext) { varianceContext = _varianceContext; commonVars = new CommonVars(varianceContext); varianceContext.emailPwd = varianceContext.aes.EncryptToString(varianceContext.emailPwd); entropyControl = new Entropy(ref varianceContext, commonVars); commonVars.getNonSimulationSettings().emailOnCompletion = varianceContext.completion; commonVars.getNonSimulationSettings().emailPerJob = varianceContext.perJob; commonVars.getNonSimulationSettings().emailAddress = varianceContext.emailAddress; commonVars.getNonSimulationSettings().emailPwd = varianceContext.emailPwd; commonVars.getNonSimulationSettings().host = varianceContext.host; commonVars.getNonSimulationSettings().ssl = varianceContext.ssl; commonVars.getNonSimulationSettings().port = varianceContext.port; commonVars.storage.setLayerSettings = setLayerSettings; }
public void testLinearInterpolationMultipleSpreads() { // Testing linear interpolation with more than two spreaded dates... CommonVars vars = new CommonVars(); List <Handle <Quote> > spreads = new List <Handle <Quote> >(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.02); SimpleQuote spread3 = new SimpleQuote(0.035); SimpleQuote spread4 = new SimpleQuote(0.04); spreads.Add(new Handle <Quote>(spread1)); spreads.Add(new Handle <Quote>(spread2)); spreads.Add(new Handle <Quote>(spread3)); spreads.Add(new Handle <Quote>(spread4)); List <Date> spreadDates = new List <Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 90, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 150, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 30, TimeUnit.Months)); spreadDates.Add(vars.calendar.advance(vars.today, 40, TimeUnit.Months)); Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = new PiecewiseZeroSpreadedTermStructure( new Handle <YieldTermStructure>(vars.termStructure), spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + spread1.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) { QAssert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); } }
public void testSplineZeroConsistency() { //"Testing consistency of piecewise-cubic zero-yield curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ZeroYield, Cubic, IterativeBootstrap>( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency <ZeroYield, Cubic, IterativeBootstrap>( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); }
//[TestMethod()] public void testSplineForwardConsistency() { //"Testing consistency of piecewise-cubic forward-rate curve..."); CommonVars vars = new CommonVars(); testCurveConsistency <ForwardRate, Cubic, IterativeBootstrapForYield>( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); testBMACurveConsistency <ForwardRate, Cubic, IterativeBootstrapForYield>( vars, new Cubic(CubicInterpolation.DerivativeApprox.Spline, true, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0, CubicInterpolation.BoundaryCondition.SecondDerivative, 0.0)); }
public void testLogLinearZeroConsistency() { // "Testing consistency of piecewise-log-linear zero-yield curve..."); // if rates can be negative it makes no sense to interpolate loglinearly if (Utils.is_QL_NEGATIVE_RATES()) { return; } else { CommonVars vars = new CommonVars(); testCurveConsistency <ZeroYield, LogLinear, IterativeBootstrapForYield>(vars); testBMACurveConsistency <ZeroYield, LogLinear, IterativeBootstrapForYield>(vars); } }
public void testConsistency() { CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; double[] cap_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] floor_rates = { 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; Date startDate = vars.termStructure.link.referenceDate(); for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < cap_rates.Length; j++) { for (int k = 0; k < floor_rates.Length; k++) { for (int l = 0; l < vols.Length; l++) { List <CashFlow> leg = vars.makeLeg(startDate, lengths[i]); Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, cap_rates[j], vols[l]); Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, floor_rates[k], vols[l]); Collar collar = new Collar(leg, new InitializedList <double>(1, cap_rates[j]), new InitializedList <double>(1, floor_rates[k])); collar.setPricingEngine(vars.makeEngine(vols[l])); if (Math.Abs((cap.NPV() - floor.NPV()) - collar.NPV()) > 1e-10) { QAssert.Fail( "inconsistency between cap, floor and collar:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[l] + "\n" + " cap value: " + cap.NPV() + " at strike: " + cap_rates[j] + "\n" + " floor value: " + floor.NPV() + " at strike: " + floor_rates[k] + "\n" + " collar value: " + collar.NPV()); } } } } } }
public void testParity() { CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; double[] strikes = { 0.0, 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] vols = { 0.01, 0.05, 0.10, 0.15, 0.20 }; Date startDate = vars.termStructure.link.referenceDate(); for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < strikes.Length; j++) { for (int k = 0; k < vols.Length; k++) { List <CashFlow> leg = vars.makeLeg(startDate, lengths[i]); Instrument cap = vars.makeCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k]); Instrument floor = vars.makeCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k]); Date maturity = vars.calendar.advance(startDate, lengths[i], TimeUnit.Years, vars.convention); Schedule schedule = new Schedule(startDate, maturity, new Period(vars.frequency), vars.calendar, vars.convention, vars.convention, DateGeneration.Rule.Forward, false); VanillaSwap swap = new VanillaSwap(VanillaSwap.Type.Payer, vars.nominals[0], schedule, strikes[j], vars.index.dayCounter(), schedule, vars.index, 0.0, vars.index.dayCounter()); swap.setPricingEngine((IPricingEngine) new DiscountingSwapEngine(vars.termStructure)); // FLOATING_POINT_EXCEPTION if (Math.Abs((cap.NPV() - floor.NPV()) - swap.NPV()) > 1.0e-10) { QAssert.Fail( "put/call parity violated:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[k] + "\n" + " strike: " + strikes[j] + "\n" + " cap value: " + cap.NPV() + "\n" + " floor value: " + floor.NPV() + "\n" + " swap value: " + swap.NPV()); } } } } }
public void testLinearInterpolation() { // Testing linear interpolation between two dates... CommonVars vars = new CommonVars(); List <Handle <Quote> > spreads = new List <Handle <Quote> >(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.03); spreads.Add(new Handle <Quote>(spread1)); spreads.Add(new Handle <Quote>(spread2)); List <Date> spreadDates = new List <Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 100, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 150, TimeUnit.Days)); Date interpolationDate = vars.calendar.advance(vars.today, 120, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = new InterpolatedPiecewiseZeroSpreadedTermStructure <Linear>( new Handle <YieldTermStructure>(vars.termStructure), spreads, spreadDates); Date d0 = vars.calendar.advance(vars.today, 100, TimeUnit.Days); Date d1 = vars.calendar.advance(vars.today, 150, TimeUnit.Days); Date d2 = vars.calendar.advance(vars.today, 120, TimeUnit.Days); double m = (0.03 - 0.02) / vars.dayCount.yearFraction(d0, d1); double expectedRate = m * vars.dayCount.yearFraction(d0, d2) + 0.054; double t = vars.dayCount.yearFraction(vars.settlementDate, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) { QAssert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); } }
public void testCurveCopy <T, I>(CommonVars vars, I interpolator) where T : ITraits <YieldTermStructure>, new() where I : IInterpolationFactory, new() { PiecewiseYieldCurve <T, I> curve = new PiecewiseYieldCurve <T, I>(vars.settlement, vars.instruments, new Actual360(), new List <Handle <Quote> >(), new List <Date>(), 1.0e-12, interpolator); // necessary to trigger bootstrap curve.recalculate(); PiecewiseYieldCurve copiedCurve = curve.Clone() as PiecewiseYieldCurve; // the two curves should be the same. double t = 2.718; var r1 = curve.zeroRate(t, Compounding.Continuous).value(); var r2 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); if (!Utils.close(r1, r2)) { QAssert.Fail("failed to link original and copied curve"); } for (int i = 0; i < vars.rates.Count; ++i) { vars.rates[i].setValue(vars.rates[i].value() + 0.001); } // now the original curve should have changed; the copied // curve should not. double r3 = curve.zeroRate(t, Compounding.Continuous).value(); double r4 = copiedCurve.zeroRate(t, Compounding.Continuous).value(); if (Utils.close(r1, r3)) { QAssert.Fail("failed to modify original curve"); } if (!Utils.close(r2, r4)) { QAssert.Fail("failed to break link between original and copied curve"); } }
public void testSmile() { // Testing swaption volatility cube (smile) CommonVars vars = new CommonVars(); SwaptionVolCube2 volCube = new SwaptionVolCube2(vars.atmVolMatrix, vars.cube.tenors.options, vars.cube.tenors.swaps, vars.cube.strikeSpreads, vars.cube.volSpreadsHandle, vars.swapIndexBase, vars.shortSwapIndexBase, vars.vegaWeighedSmileFit); double tolerance = 1.0e-16; vars.makeVolSpreadsTest(volCube, tolerance); }
public void testForwardRateDayCounter() { CommonVars vars = new CommonVars(); DayCounter d = new ActualActual(); DayCounter d1 = new Actual360(); vars.termStructure = new PiecewiseYieldCurve <Discount, LogLinear>(vars.settlementDays, vars.calendar, vars.instruments, d); InterestRate ir = vars.termStructure.forwardRate(vars.settlement, vars.settlement + 30, d1, Compounding.Simple); if (ir.dayCounter().name() != d1.name()) { QAssert.Fail("PiecewiseYieldCurve forwardRate dayCounter error" + " Actual daycounter : " + vars.termStructure.dayCounter().name() + " Expetced DayCounter : " + d1.name()); } }
public void testImpliedObs() { // Testing observability of implied term structure CommonVars vars = new CommonVars(); Date today = Settings.evaluationDate(); Date newToday = today + new Period(3, TimeUnit.Years); Date newSettlement = vars.calendar.advance(newToday, vars.settlementDays, TimeUnit.Days); RelinkableHandle <YieldTermStructure> h = new RelinkableHandle <YieldTermStructure>(); YieldTermStructure implied = new ImpliedTermStructure(h, newSettlement); Flag flag = new Flag(); implied.registerWith(flag.update); h.linkTo(vars.termStructure); if (!flag.isUp()) { QAssert.Fail("Observer was not notified of term structure change"); } }
public void testLargeRates() { // Testing degenerate collared coupon CommonVars vars = new CommonVars(); /* A vanilla floating leg and a capped floating leg with strike * equal to 100 and floor equal to 0 must have (about) the same NPV * (depending on variance: option expiry and volatility) */ List <double?> caps = new InitializedList <double?>(vars.length, 100.0); List <double?> floors = new InitializedList <double?>(vars.length, 0.0); double tolerance = 1e-10; // fixed leg with zero rate List <CashFlow> fixedLeg = vars.makeFixedLeg(vars.startDate, vars.length); List <CashFlow> floatLeg = vars.makeFloatingLeg(vars.startDate, vars.length); List <CashFlow> collaredLeg = vars.makeCapFlooredLeg(vars.startDate, vars.length, caps, floors, vars.volatility); IPricingEngine engine = new DiscountingSwapEngine(vars.termStructure); Swap vanillaLeg = new Swap(fixedLeg, floatLeg); Swap collarLeg = new Swap(fixedLeg, collaredLeg); vanillaLeg.setPricingEngine(engine); collarLeg.setPricingEngine(engine); double npvVanilla = vanillaLeg.NPV(); double npvCollar = collarLeg.NPV(); if (Math.Abs(npvVanilla - npvCollar) > tolerance) { QAssert.Fail("Lenght: " + vars.length + " y" + "\n" + "Volatility: " + vars.volatility * 100 + "%\n" + "Notional: " + vars.nominal + "\n" + "Vanilla floating leg NPV: " + vanillaLeg.NPV() + "\n" + "Collared floating leg NPV (strikes 0 and 100): " + collarLeg.NPV() + "\n" + "Diff: " + Math.Abs(vanillaLeg.NPV() - collarLeg.NPV())); } }
public void testFSpreadedObs() { // ("Testing observability of forward-spreaded term structure..."); CommonVars vars = new CommonVars(); SimpleQuote me = new SimpleQuote(0.01); Handle<Quote> mh = new Handle<Quote>(me); RelinkableHandle<YieldTermStructure> h = new RelinkableHandle<YieldTermStructure>(); //(vars.dummyTermStructure); YieldTermStructure spreaded = new ForwardSpreadedTermStructure(h, mh); Flag flag = new Flag(); spreaded.registerWith(flag.update); h.linkTo(vars.termStructure); if (!flag.isUp()) Console.WriteLine("Observer was not notified of term structure change"); flag.lower(); me.setValue(0.005); if (!flag.isUp()) Console.WriteLine("Observer was not notified of spread change"); }
public void testBackwardFlatInterpolation() { // Testing backward flat interpolation between two dates... CommonVars vars = new CommonVars(); List<Handle<Quote>> spreads = new List<Handle<Quote>>(); SimpleQuote spread1 = new SimpleQuote(0.02); SimpleQuote spread2 = new SimpleQuote(0.03); SimpleQuote spread3 = new SimpleQuote(0.04); spreads.Add(new Handle<Quote>(spread1)); spreads.Add(new Handle<Quote>(spread2)); spreads.Add(new Handle<Quote>(spread3)); List<Date> spreadDates = new List<Date>(); spreadDates.Add(vars.calendar.advance(vars.today, 100, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 200, TimeUnit.Days)); spreadDates.Add(vars.calendar.advance(vars.today, 300, TimeUnit.Days)); Date interpolationDate = vars.calendar.advance(vars.today, 110, TimeUnit.Days); ZeroYieldStructure spreadedTermStructure = new InterpolatedPiecewiseZeroSpreadedTermStructure<BackwardFlat>( new Handle<YieldTermStructure>(vars.termStructure), spreads, spreadDates); double t = vars.dayCount.yearFraction(vars.today, interpolationDate); double interpolatedZeroRate = spreadedTermStructure.zeroRate(t, vars.compounding).value(); double tolerance = 1e-9; double expectedRate = vars.termStructure.zeroRate(t, vars.compounding).value() + spread2.value(); if (Math.Abs(interpolatedZeroRate - expectedRate) > tolerance) Assert.Fail( "unable to reproduce interpolated rate\n" + " calculated: " + interpolatedZeroRate + "\n" + " expected: " + expectedRate); }
public void testFSpreaded() { //("Testing consistency of forward-spreaded term structure..."); CommonVars vars = new CommonVars(); double tolerance = 1.0e-10; Quote me = new SimpleQuote(0.01); Handle<Quote> mh = new Handle<Quote>(me); YieldTermStructure spreaded = new ForwardSpreadedTermStructure(new Handle<YieldTermStructure>(vars.termStructure), mh); Date testDate = vars.termStructure.referenceDate() + new Period(5, TimeUnit.Years); DayCounter tsdc = vars.termStructure.dayCounter(); DayCounter sprdc = spreaded.dayCounter(); double forward = vars.termStructure.forwardRate(testDate, testDate, tsdc, Compounding.Continuous, Frequency.NoFrequency).rate(); double spreadedForward = spreaded.forwardRate(testDate, testDate, sprdc, Compounding.Continuous, Frequency.NoFrequency).rate(); if (Math.Abs(forward - (spreadedForward - me.value())) > tolerance) Console.WriteLine("unable to reproduce forward from spreaded curve\n" + " calculated: " + (spreadedForward - me.value()) + "\n" + " expected: " + forward); }
public void testCachedValue() { //("Testing vanilla-swap calculation against cached value..."); CommonVars vars = new CommonVars(); vars.today = new Date(17, Month.June, 2002); Settings.setEvaluationDate(vars.today); vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.05, new Actual365Fixed())); VanillaSwap swap = vars.makeSwap(10, 0.06, 0.001); #if QL_USE_INDEXED_COUPON double cachedNPV = -5.872342992212; #else double cachedNPV = -5.872863313209; #endif if (Math.Abs(swap.NPV() - cachedNPV) > 1.0e-11) Assert.Fail("failed to reproduce cached swap value:\n" + " calculated: " + swap.NPV() + "\n" + " expected: " + cachedNPV); }
public void testMASWWithGenericBond() { // Testing market asset swap against par asset swap with generic bond... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool payFixedRate = true; bool parAssetSwap = true; bool mktAssetSwap = false; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Date fixedBondStartDate1 = new Date(4,Month.January,2005); Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, fixedBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount(); AssetSwap fixedBondParAssetSwap1= new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap1.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread(); AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap1.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread(); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondMktAssetSwapSpread1- 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1); if (error1>tolerance) Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread1 + "\n par asset swap spread: " + fixedBondParAssetSwapSpread1 + "\n error: " + error1 + "\n tolerance: " + tolerance); // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Date fixedBondStartDate2 = new Date(5,Month.February,2005); Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); Schedule fixedBondSchedule2 = new Schedule(fixedBondStartDate2, fixedBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount(); AssetSwap fixedBondParAssetSwap2= new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap2.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread(); AssetSwap fixedBondMktAssetSwap2= new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap2.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread(); double error2 = Math.Abs(fixedBondMktAssetSwapSpread2- 100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2); if (error2>tolerance) Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market asset swap spread: " + fixedBondMktAssetSwapSpread2 + "\n par asset swap spread: " + fixedBondParAssetSwapSpread2 + "\n error: " + error2 + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Date floatingBondStartDate1 = new Date(29,Month.September,2003); Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, floatingBondMaturityDate1, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0056) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); // market price observed on 7th June 2007 double floatingBondMktPrice1 = 101.64 ; double floatingBondMktFullPrice1 = floatingBondMktPrice1+floatingBond1.accruedAmount(); AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap1.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread(); AssetSwap floatingBondMktAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap1.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread(); double error3 = Math.Abs(floatingBondMktAssetSwapSpread1- 100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1); if (error3>tolerance) Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread1 + "\n par asset swap spread: " + floatingBondParAssetSwapSpread1 + "\n error: " + error3 + "\n tolerance: " + tolerance); // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Date floatingBondStartDate2 = new Date(24,Month.September,2004); Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, floatingBondMaturityDate2, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) .withFixingDays(fixingDays) .withSpreads(0.0025) .inArrears(inArrears) .withPaymentDayCounter(new Actual360()) .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); // market price observed on 7th June 2007 double floatingBondMktPrice2 = 101.248 ; double floatingBondMktFullPrice2 = floatingBondMktPrice2+floatingBond2.accruedAmount(); AssetSwap floatingBondParAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap2.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread(); AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap2.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread(); double error4 = Math.Abs(floatingBondMktAssetSwapSpread2- 100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2); if (error4>tolerance) Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market asset swap spread: " + floatingBondMktAssetSwapSpread2 + "\n par asset swap spread: " + floatingBondParAssetSwapSpread2 + "\n error: " + error4 + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Date cmsBondStartDate1 = new Date(22,Month.August,2005); Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, cmsBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withCaps(0.055) .withFloors(0.025) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount(); AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap1.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread(); AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap1.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread(); double error5 = Math.Abs(cmsBondMktAssetSwapSpread1- 100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1); if (error5>tolerance) Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread1 + "\n par asset swap spread: " + cmsBondParAssetSwapSpread1 + "\n error: " + error5 + "\n tolerance: " + tolerance); // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Date cmsBondStartDate2 = new Date(06,Month.May,2005); Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, cmsBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withGearings(0.84) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount(); AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap2.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread(); AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap2.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread(); double error6 = Math.Abs(cmsBondMktAssetSwapSpread2- 100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2); if (error6>tolerance) Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market asset swap spread: " + cmsBondMktAssetSwapSpread2 + "\n par asset swap spread: " + cmsBondParAssetSwapSpread2 + "\n error: " + error6 + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // market price observed on 12th June 2007 double zeroCpnBondMktPrice1 = 70.436 ; double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread(); double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1- 100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1); if (error7>tolerance) Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread1 + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread1 + "\n error: " + error7 + "\n tolerance: " + tolerance); // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); // market price observed on 12th June 2007 double zeroCpnBondMktPrice2 = 35.160 ; double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread(); double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2- 100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2); if (error8>tolerance) Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market asset swap spread: " + zeroCpnBondMktAssetSwapSpread2 + "\n par asset swap spread: " + zeroCpnBondParAssetSwapSpread2 + "\n error: " + error8 + "\n tolerance: " + tolerance); }
public void testParity() { // Testing yoy inflation cap/floor parity... CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; // vol is low ... double[] strikes = { 0.0, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; // yoy inflation vol is generally very low double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; // cap-floor-swap parity is model-independent for (int whichPricer = 0; whichPricer < 3; whichPricer++) { for (int i=0; i<lengths.Length; i++) { for (int j=0; j<strikes.Length; j++) { for (int k=0; k<vols.Length; k++) { List<CashFlow> leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]); Instrument cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, strikes[j], vols[k], whichPricer); Instrument floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, strikes[j], vols[k], whichPricer); Date from = vars.nominalTS.link.referenceDate(); Date to = from+new Period(lengths[i],TimeUnit.Years); Schedule yoySchedule = new MakeSchedule().from(from).to(to) .withTenor(new Period(1,TimeUnit.Years)) .withConvention(BusinessDayConvention.Unadjusted) .withCalendar(new UnitedKingdom()).backwards().value(); YearOnYearInflationSwap swap = new YearOnYearInflationSwap (YearOnYearInflationSwap.Type.Payer, 1000000.0, yoySchedule,//fixed schedule, but same as yoy strikes[j], vars.dc, yoySchedule, vars.iir, vars.observationLag, 0.0, //spread on index vars.dc, new UnitedKingdom()); Handle<YieldTermStructure> hTS = new Handle<YieldTermStructure>(vars.nominalTS); IPricingEngine sppe = new DiscountingSwapEngine(hTS); swap.setPricingEngine(sppe); // N.B. nominals are 10e6 if (Math.Abs((cap.NPV()-floor.NPV()) - swap.NPV()) > 1.0e-6) { Assert.Fail( "put/call parity violated:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[k] + "\n" + " strike: " + strikes[j] + "\n" + " cap value: " + cap.NPV() + "\n" + " floor value: " + floor.NPV() + "\n" + " swap value: " + swap.NPV()); } } } } } // remove circular refernce vars.hy.linkTo(new YoYInflationTermStructure()); }
public void testConsistency() { // Testing consistency between yoy inflation cap,floor and collar... CommonVars vars = new CommonVars(); int[] lengths = { 1, 2, 3, 5, 7, 10, 15, 20 }; double[] cap_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; double[] floor_rates = { 0.01, 0.025, 0.029, 0.03, 0.031, 0.035, 0.07 }; double[] vols = { 0.001, 0.005, 0.010, 0.015, 0.020 }; for (int whichPricer = 0; whichPricer < 3; whichPricer++) { for (int i=0; i<lengths.Length; i++) { for (int j=0; j<cap_rates.Length; j++) { for (int k=0; k<floor_rates.Length; k++) { for (int l=0; l<vols.Length; l++) { List<CashFlow> leg = vars.makeYoYLeg(vars.evaluationDate,lengths[i]); YoYInflationCapFloor cap = vars.makeYoYCapFloor(CapFloorType.Cap, leg, cap_rates[j], vols[l], whichPricer); YoYInflationCapFloor floor = vars.makeYoYCapFloor(CapFloorType.Floor, leg, floor_rates[k], vols[l], whichPricer); YoYInflationCollar collar = new YoYInflationCollar(leg,new List<double>(){cap_rates[j]}, new List<double>(){floor_rates[k]}); collar.setPricingEngine(vars.makeEngine(vols[l], whichPricer)); if (Math.Abs((cap.NPV()-floor.NPV())-collar.NPV()) > 1e-6) { Assert.Fail( "inconsistency between cap, floor and collar:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + "\n" + " cap value: " + cap.NPV() + " at strike: " + "\n" + " floor value: " + floor.NPV() + " at strike: " + "\n" + " collar value: " + collar.NPV()); } // test re-composition by optionlets, N.B. ONE per year double capletsNPV = 0.0; List<YoYInflationCapFloor> caplets = new List<YoYInflationCapFloor>(); for (int m=0; m<lengths[i]*1; m++) { caplets.Add(cap.optionlet(m)); caplets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); capletsNPV += caplets[m].NPV(); } if (Math.Abs(cap.NPV() - capletsNPV) > 1e-6) { Assert.Fail( "sum of caplet NPVs does not equal cap NPV:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + "\n" + " cap value: " + cap.NPV() + " at strike: " + "\n" + " sum of caplets value: " + capletsNPV + " at strike (first): " + caplets[0].capRates()[0] + "\n" ); } double floorletsNPV = 0.0; List<YoYInflationCapFloor> floorlets = new List<YoYInflationCapFloor>(); for (int m=0; m<lengths[i]*1; m++) { floorlets.Add(floor.optionlet(m)); floorlets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); floorletsNPV += floorlets[m].NPV(); } if (Math.Abs(floor.NPV() - floorletsNPV) > 1e-6) { Assert.Fail( "sum of floorlet NPVs does not equal floor NPV:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + "\n" + " cap value: " + floor.NPV() + " at strike: " + floor_rates[j] + "\n" + " sum of floorlets value: " + floorletsNPV + " at strike (first): " + floorlets[0].floorRates()[0] + "\n" ); } double collarletsNPV = 0.0; List<YoYInflationCapFloor> collarlets = new List<YoYInflationCapFloor>(); for (int m=0; m<lengths[i]*1; m++) { collarlets.Add(collar.optionlet(m)); collarlets[m].setPricingEngine(vars.makeEngine(vols[l], whichPricer)); collarletsNPV += collarlets[m].NPV(); } if (Math.Abs(collar.NPV() - collarletsNPV) > 1e-6) { Assert.Fail( "sum of collarlet NPVs does not equal floor NPV:\n" + " length: " + lengths[i] + " years\n" + " volatility: " + vols[l] + "\n" + " cap value: " + collar.NPV() + " at strike floor: " + floor_rates[j] + " at strike cap: " + cap_rates[j] + "\n" + " sum of collarlets value: " + collarletsNPV + " at strike floor (first): " + collarlets[0].floorRates()[0] + " at strike cap (first): " + collarlets[0].capRates()[0] + "\n" ); } } } } } } // pricer loop // remove circular refernce vars.hy.linkTo(new YoYInflationTermStructure()); }
public void testSpreadTreatment() { //"Testing swaption treatment of spread..."; CommonVars vars = new CommonVars(); double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; for (int i=0; i<exercises.Length; i++) { for (int j=0; j<lengths.Length ; j++) { for (int k=0; k<type.Length ; k++) { Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays,TimeUnit.Days); for (int l=0; l<spreads.Length ; l++) { VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, 0.06) .withEffectiveDate(startDate) .withFloatingLegSpread(spreads[l]) .withType(type[k]); // FLOATING_POINT_EXCEPTION double correction = spreads[l] * swap.floatingLegBPS() / swap.fixedLegBPS(); VanillaSwap equivalentSwap = new MakeVanillaSwap(lengths[j], vars.index, 0.06+correction) .withEffectiveDate(startDate) .withFloatingLegSpread(0.0) .withType(type[k]); Swaption swaption1 = vars.makeSwaption(swap,exerciseDate,0.20); Swaption swaption2 = vars.makeSwaption(equivalentSwap,exerciseDate,0.20); Swaption swaption1_cash = vars.makeSwaption(swap,exerciseDate,0.20, Settlement.Type.Cash); Swaption swaption2_cash = vars.makeSwaption(equivalentSwap,exerciseDate,0.20, Settlement.Type.Cash); if (Math.Abs(swaption1.NPV()-swaption2.NPV()) > 1.0e-6) Assert.Fail("wrong spread treatment:" + "\nexercise: " + exerciseDate + "\nlength: " + lengths[j] + "\ntype " + type[k] + "\nspread: " + spreads[l] + "\noriginal swaption value: " + swaption1.NPV() + "\nequivalent swaption value: " + swaption2.NPV()); if (Math.Abs(swaption1_cash.NPV()-swaption2_cash.NPV()) > 1.0e-6) Assert.Fail("wrong spread treatment:" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + //"\npay " + (type[k] ? "fixed" : "floating") + "\nspread: " + spreads[l] + "\nvalue of original swaption: " + swaption1_cash.NPV() + "\nvalue of equivalent swaption: " + swaption2_cash.NPV()); } } } } }
public void testMarketASWSpread() { // Testing relationship between market asset swap and par asset swap... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool payFixedRate = true; bool parAssetSwap = true; bool mktAssetSwap = false; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Schedule fixedBondSchedule1 = new Schedule(new Date(4,Month.January,2005), new Date(4,Month.January,2037), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, new List<double>{0.04}, new ActualActual(ActualActual.Convention.ISDA),BusinessDayConvention.Following, 100.0, new Date(4,Month.January,2005)); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondMktPrice1 = 89.22 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice1=fixedBondMktPrice1+fixedBond1.accruedAmount(); AssetSwap fixedBondParAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap1.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread1 = fixedBondParAssetSwap1.fairSpread(); AssetSwap fixedBondMktAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap1.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread1 = fixedBondMktAssetSwap1.fairSpread(); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondMktAssetSwapSpread1- 100*fixedBondParAssetSwapSpread1/fixedBondMktFullPrice1); if (error1>tolerance) { Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market ASW spread: " + fixedBondMktAssetSwapSpread1 + "\n par ASW spread: " + fixedBondParAssetSwapSpread1 + "\n error: " + error1 + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Schedule fixedBondSchedule2 = new Schedule(new Date(5,Month.February,2005), new Date(5,Month.February,2019), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, new List<double>{ 0.05}, new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, 100.0, new Date(5,Month.February,2005)); fixedBond2.setPricingEngine(bondEngine); double fixedBondMktPrice2 = 99.98 ; // market price observed on 7th June 2007 double fixedBondMktFullPrice2=fixedBondMktPrice2+fixedBond2.accruedAmount(); AssetSwap fixedBondParAssetSwap2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondParAssetSwap2.setPricingEngine(swapEngine); double fixedBondParAssetSwapSpread2 = fixedBondParAssetSwap2.fairSpread(); AssetSwap fixedBondMktAssetSwap2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); fixedBondMktAssetSwap2.setPricingEngine(swapEngine); double fixedBondMktAssetSwapSpread2 = fixedBondMktAssetSwap2.fairSpread(); double error2 = Math.Abs(fixedBondMktAssetSwapSpread2- 100*fixedBondParAssetSwapSpread2/fixedBondMktFullPrice2); if (error2>tolerance) { Assert.Fail("wrong asset swap spreads for fixed bond:" + "\n market ASW spread: " + fixedBondMktAssetSwapSpread2 + "\n par ASW spread: " + fixedBondParAssetSwapSpread2 + "\n error: " + error2 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003), new Date(29,Month.September,2013), new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule1, vars.iborIndex, new Actual360(), BusinessDayConvention.Following, fixingDays, new List<double>{1}, new List<double>{0.0056}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(29,Month.September,2003)); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); // market price observed on 7th June 2007 double floatingBondMktPrice1 = 101.64 ; double floatingBondMktFullPrice1 = floatingBondMktPrice1+floatingBond1.accruedAmount(); AssetSwap floatingBondParAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap1.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread1 = floatingBondParAssetSwap1.fairSpread(); AssetSwap floatingBondMktAssetSwap1= new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap1.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread1 = floatingBondMktAssetSwap1.fairSpread(); double error3 = Math.Abs(floatingBondMktAssetSwapSpread1- 100*floatingBondParAssetSwapSpread1/floatingBondMktFullPrice1); if (error3>tolerance) { Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market ASW spread: " + floatingBondMktAssetSwapSpread1 + "\n par ASW spread: " + floatingBondParAssetSwapSpread1 + "\n error: " + error3 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004), new Date(24,Month.September,2018), new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); Bond floatingBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule2, vars.iborIndex, new Actual360(), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>{1}, new List<double>{0.0025}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(24,Month.September,2004)); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); // market price observed on 7th June 2007 double floatingBondMktPrice2 = 101.248 ; double floatingBondMktFullPrice2 = floatingBondMktPrice2+floatingBond2.accruedAmount(); AssetSwap floatingBondParAssetSwap2= new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondParAssetSwap2.setPricingEngine(swapEngine); double floatingBondParAssetSwapSpread2 = floatingBondParAssetSwap2.fairSpread(); AssetSwap floatingBondMktAssetSwap2 = new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); floatingBondMktAssetSwap2.setPricingEngine(swapEngine); double floatingBondMktAssetSwapSpread2 = floatingBondMktAssetSwap2.fairSpread(); double error4 = Math.Abs(floatingBondMktAssetSwapSpread2- 100*floatingBondParAssetSwapSpread2/floatingBondMktFullPrice2); if (error4>tolerance) { Assert.Fail("wrong asset swap spreads for floating bond:" + "\n market ASW spread: " + floatingBondMktAssetSwapSpread2 + "\n par ASW spread: " + floatingBondParAssetSwapSpread2 + "\n error: " + error4 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005), new Date(22,Month.August,2020), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>{1.0}, new List<double>{0.0}, new List<double>{0.055}, new List<double>{0.025}, inArrears, 100.0, new Date(22,Month.August,2005)); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondMktPrice1 = 88.45 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice1 = cmsBondMktPrice1+cmsBond1.accruedAmount(); AssetSwap cmsBondParAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap1.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread1 = cmsBondParAssetSwap1.fairSpread(); AssetSwap cmsBondMktAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap1.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread1 = cmsBondMktAssetSwap1.fairSpread(); double error5 = Math.Abs(cmsBondMktAssetSwapSpread1- 100*cmsBondParAssetSwapSpread1/cmsBondMktFullPrice1); if (error5>tolerance) { Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market ASW spread: " + cmsBondMktAssetSwapSpread1 + "\n par ASW spread: " + cmsBondParAssetSwapSpread1 + "\n error: " + error5 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Schedule cmsBondSchedule2 = new Schedule(new Date(06,Month.May,2005), new Date(06,Month.May,2015), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>{0.84}, new List<double>{0.0}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(06,Month.May,2005)); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondMktPrice2 = 94.08 ; // market price observed on 7th June 2007 double cmsBondMktFullPrice2 = cmsBondMktPrice2+cmsBond2.accruedAmount(); AssetSwap cmsBondParAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondParAssetSwap2.setPricingEngine(swapEngine); double cmsBondParAssetSwapSpread2 = cmsBondParAssetSwap2.fairSpread(); AssetSwap cmsBondMktAssetSwap2 = new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); cmsBondMktAssetSwap2.setPricingEngine(swapEngine); double cmsBondMktAssetSwapSpread2 = cmsBondMktAssetSwap2.fairSpread(); double error6 = Math.Abs(cmsBondMktAssetSwapSpread2- 100*cmsBondParAssetSwapSpread2/cmsBondMktFullPrice2); if (error6>tolerance) { Assert.Fail("wrong asset swap spreads for cms bond:" + "\n market ASW spread: " + cmsBondMktAssetSwapSpread2 + "\n par ASW spread: " + cmsBondParAssetSwapSpread2 + "\n error: " + error6 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(20,Month.December,2015), BusinessDayConvention.Following, 100.0, new Date(19,Month.December,1985)); zeroCpnBond1.setPricingEngine(bondEngine); // market price observed on 12th June 2007 double zeroCpnBondMktPrice1 = 70.436 ; double zeroCpnBondMktFullPrice1 = zeroCpnBondMktPrice1+zeroCpnBond1.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread1 = zeroCpnBondParAssetSwap1.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread1 = zeroCpnBondMktAssetSwap1.fairSpread(); double error7 = Math.Abs(zeroCpnBondMktAssetSwapSpread1- 100*zeroCpnBondParAssetSwapSpread1/zeroCpnBondMktFullPrice1); if (error7>tolerance) { Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread1 + "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread1 + "\n error: " + error7 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(17,Month.February,2028), BusinessDayConvention.Following, 100.0, new Date(17,Month.February,1998)); zeroCpnBond2.setPricingEngine(bondEngine); // Real zeroCpnBondPrice2 = zeroCpnBond2->cleanPrice(); // market price observed on 12th June 2007 double zeroCpnBondMktPrice2 = 35.160 ; double zeroCpnBondMktFullPrice2 = zeroCpnBondMktPrice2+zeroCpnBond2.accruedAmount(); AssetSwap zeroCpnBondParAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondParAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondParAssetSwapSpread2 = zeroCpnBondParAssetSwap2.fairSpread(); AssetSwap zeroCpnBondMktAssetSwap2 = new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), mktAssetSwap); zeroCpnBondMktAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondMktAssetSwapSpread2 = zeroCpnBondMktAssetSwap2.fairSpread(); double error8 = Math.Abs(zeroCpnBondMktAssetSwapSpread2- 100*zeroCpnBondParAssetSwapSpread2/zeroCpnBondMktFullPrice2); if (error8>tolerance) { Assert.Fail("wrong asset swap spreads for zero cpn bond:" + "\n market ASW spread: " + zeroCpnBondMktAssetSwapSpread2 + "\n par ASW spread: " + zeroCpnBondParAssetSwapSpread2 + "\n error: " + error8 + "\n tolerance: " + tolerance); } }
public void testConsistency() { // Testing consistency between fair price and fair spread..."); CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Schedule bondSchedule = new Schedule(new Date(4, Month.January, 2005), new Date(4, Month.January, 2037), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond bond = new FixedRateBond(settlementDays, vars.faceAmount, bondSchedule, new List<double>() { 0.04 }, new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, 100.0, new Date(4, Month.January, 2005)); bool payFixedRate = true; double bondPrice = 95.0; bool isPar = true; AssetSwap parAssetSwap = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), Settings.evaluationDate()); parAssetSwap.setPricingEngine(swapEngine); double fairCleanPrice = parAssetSwap.fairCleanPrice(); double fairSpread = parAssetSwap.fairSpread(); double tolerance = 1.0e-13; AssetSwap assetSwap2 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap2.setPricingEngine(swapEngine); if (Math.Abs(assetSwap2.NPV()) > tolerance) { Assert.Fail("npar asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap2.fairCleanPrice() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap2.fairSpread() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } AssetSwap assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap3.setPricingEngine(swapEngine); if (Math.Abs(assetSwap3.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap3.fairCleanPrice() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap3.fairSpread() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } // let's change the npv date swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), bond.settlementDate()); parAssetSwap.setPricingEngine(swapEngine); // fair clean price and fair spread should not change if (Math.Abs(parAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price changed with NpvDate:" + "\n expected clean price: " + fairCleanPrice + "\n fair clean price: " + parAssetSwap.fairCleanPrice() + "\n tolerance: " + tolerance); } if (Math.Abs(parAssetSwap.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread changed with NpvDate:" + "\n expected spread: " + fairSpread + "\n fair spread: " + parAssetSwap.fairSpread() + "\n tolerance: " + tolerance); } assetSwap2 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap2.setPricingEngine(swapEngine); if (Math.Abs(assetSwap2.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap2.fairCleanPrice() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap2.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap2.fairSpread() + "\n NPV: " + assetSwap2.NPV() + "\n tolerance: " + tolerance); } assetSwap3 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap3.setPricingEngine(swapEngine); if (Math.Abs(assetSwap3.NPV()) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\npar asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap3.fairCleanPrice() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap3.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\npar asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap3.fairSpread() + "\n NPV: " + assetSwap3.NPV() + "\n tolerance: " + tolerance); } // now market asset swap isPar = false; AssetSwap mktAssetSwap = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), Settings.evaluationDate()); mktAssetSwap.setPricingEngine(swapEngine); fairCleanPrice = mktAssetSwap.fairCleanPrice(); fairSpread = mktAssetSwap.fairSpread(); AssetSwap assetSwap4 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap4.setPricingEngine(swapEngine); if (Math.Abs(assetSwap4.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap4.fairCleanPrice() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap4.fairSpread() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } AssetSwap assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap5.setPricingEngine(swapEngine); if (Math.Abs(assetSwap5.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap5.fairCleanPrice() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap5.fairSpread() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } // let's change the npv date swapEngine = new DiscountingSwapEngine(vars.termStructure, true, bond.settlementDate(), bond.settlementDate()); mktAssetSwap.setPricingEngine(swapEngine); // fair clean price and fair spread should not change if (Math.Abs(mktAssetSwap.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price changed with NpvDate:" + "\n expected clean price: " + fairCleanPrice + "\n fair clean price: " + mktAssetSwap.fairCleanPrice() + "\n tolerance: " + tolerance); } if (Math.Abs(mktAssetSwap.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread changed with NpvDate:" + "\n expected spread: " + fairSpread + "\n fair spread: " + mktAssetSwap.fairSpread() + "\n tolerance: " + tolerance); } assetSwap4 = new AssetSwap(payFixedRate, bond, fairCleanPrice, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), isPar); assetSwap4.setPricingEngine(swapEngine); if (Math.Abs(assetSwap4.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't zero the NPV: " + "\n clean price: " + bondPrice + "\n fair clean price: " + fairCleanPrice + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairCleanPrice() - fairCleanPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + fairCleanPrice + "\n fair clean price: " + assetSwap4.fairCleanPrice() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap4.fairSpread() - vars.spread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + vars.spread + "\n fair spread: " + assetSwap4.fairSpread() + "\n NPV: " + assetSwap4.NPV() + "\n tolerance: " + tolerance); } assetSwap5 = new AssetSwap(payFixedRate, bond, bondPrice, vars.iborIndex, fairSpread, null, vars.iborIndex.dayCounter(), isPar); assetSwap5.setPricingEngine(swapEngine); if (Math.Abs(assetSwap5.NPV()) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't zero the NPV: " + "\n spread: " + vars.spread + "\n fair spread: " + fairSpread + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairCleanPrice() - bondPrice) > tolerance) { Assert.Fail("\nmarket asset swap fair clean price doesn't equal input clean price at zero NPV: " + "\n input clean price: " + bondPrice + "\n fair clean price: " + assetSwap5.fairCleanPrice() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } if (Math.Abs(assetSwap5.fairSpread() - fairSpread) > tolerance) { Assert.Fail("\nmarket asset swap fair spread doesn't equal input spread at zero NPV: " + "\n input spread: " + fairSpread + "\n fair spread: " + assetSwap5.fairSpread() + "\n NPV: " + assetSwap5.NPV() + "\n tolerance: " + tolerance); } }
public void testSpecializedBondVsGenericBondUsingAsw() { // Testing asset-swap prices and spreads for specialized bond against equivalent generic bond... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool payFixedRate = true; bool parAssetSwap = true; bool inArrears = false; // Fixed bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Date fixedBondStartDate1 = new Date(4,Month.January,2005); Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); Schedule fixedBondSchedule1 = new Schedule(fixedBondStartDate1, fixedBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); // generic bond Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, new List<double>{0.04}, new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, 100.0, new Date(4,Month.January,2005)); fixedSpecializedBond1.setPricingEngine(bondEngine); double fixedBondPrice1 = fixedBond1.cleanPrice(); double fixedSpecializedBondPrice1 = fixedSpecializedBond1.cleanPrice(); AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondAssetSwap1.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondAssetSwap1 = new AssetSwap(payFixedRate, fixedSpecializedBond1, fixedSpecializedBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice(); double fixedSpecializedBondAssetSwapPrice1 = fixedSpecializedBondAssetSwap1.fairCleanPrice(); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondAssetSwapPrice1-fixedSpecializedBondAssetSwapPrice1); if (error1>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n generic fixed rate bond's clean price: " + fixedBondAssetSwapPrice1 + "\n equivalent specialized bond's clean price: " + fixedSpecializedBondAssetSwapPrice1 + "\n error: " + error1 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double fixedBondMktPrice1= 91.832; AssetSwap fixedBondASW1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondASW1.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondASW1 = new AssetSwap(payFixedRate, fixedSpecializedBond1, fixedBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedSpecializedBondASW1.setPricingEngine(swapEngine); double fixedBondASWSpread1 = fixedBondASW1.fairSpread(); double fixedSpecializedBondASWSpread1 = fixedSpecializedBondASW1.fairSpread(); double error2 = Math.Abs(fixedBondASWSpread1-fixedSpecializedBondASWSpread1); if (error2>tolerance) { Assert.Fail("wrong asw spread for fixed bond:" + "\n generic fixed rate bond's asw spread: " + fixedBondASWSpread1 + "\n equivalent specialized bond's asw spread: " + fixedSpecializedBondASWSpread1 + "\n error: " + error2 + "\n tolerance: " + tolerance); } //Fixed bond (Isin: IT0006527060 IBRD 5 02/05/19) //maturity occurs on a business day Date fixedBondStartDate2 = new Date(5,Month.February,2005); Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, fixedBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); // generic bond Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); // equivalent specialized fixed rate bond Bond fixedSpecializedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, new List<double>{ 0.05}, new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, 100.0, new Date(5,Month.February,2005)); fixedSpecializedBond2.setPricingEngine(bondEngine); double fixedBondPrice2 = fixedBond2.cleanPrice(); double fixedSpecializedBondPrice2 = fixedSpecializedBond2.cleanPrice(); AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondAssetSwap2.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondAssetSwap2 = new AssetSwap(payFixedRate, fixedSpecializedBond2, fixedSpecializedBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice(); double fixedSpecializedBondAssetSwapPrice2 = fixedSpecializedBondAssetSwap2.fairCleanPrice(); double error3 = Math.Abs(fixedBondAssetSwapPrice2-fixedSpecializedBondAssetSwapPrice2); if (error3>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n generic fixed rate bond's clean price: " + fixedBondAssetSwapPrice2 + "\n equivalent specialized bond's clean price: " + fixedSpecializedBondAssetSwapPrice2 + "\n error: " + error3 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double fixedBondMktPrice2= 102.178; AssetSwap fixedBondASW2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondASW2.setPricingEngine(swapEngine); AssetSwap fixedSpecializedBondASW2 = new AssetSwap(payFixedRate, fixedSpecializedBond2, fixedBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedSpecializedBondASW2.setPricingEngine(swapEngine); double fixedBondASWSpread2 = fixedBondASW2.fairSpread(); double fixedSpecializedBondASWSpread2 = fixedSpecializedBondASW2.fairSpread(); double error4 = Math.Abs(fixedBondASWSpread2-fixedSpecializedBondASWSpread2); if (error4>tolerance) { Assert.Fail("wrong asw spread for fixed bond:" + "\n generic fixed rate bond's asw spread: " + fixedBondASWSpread2 + "\n equivalent specialized bond's asw spread: " + fixedSpecializedBondASWSpread2 + "\n error: " + error4 + "\n tolerance: " + tolerance); } //FRN bond (Isin: IT0003543847 ISPIM 0 09/29/13) //maturity doesn't occur on a business day Date floatingBondStartDate1 = new Date(29,Month.September,2003); Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, floatingBondMaturityDate1, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0056) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); // generic bond Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); // equivalent specialized floater Bond floatingSpecializedBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule1, vars.iborIndex, new Actual360(), BusinessDayConvention.Following, fixingDays, new List<double>{1}, new List<double>{0.0056}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(29,Month.September,2003)); floatingSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); double floatingBondPrice1 = floatingBond1.cleanPrice(); double floatingSpecializedBondPrice1= floatingSpecializedBond1.cleanPrice(); AssetSwap floatingBondAssetSwap1= new AssetSwap(payFixedRate, floatingBond1, floatingBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap1.setPricingEngine(swapEngine); AssetSwap floatingSpecializedBondAssetSwap1= new AssetSwap(payFixedRate, floatingSpecializedBond1, floatingSpecializedBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice(); double floatingSpecializedBondAssetSwapPrice1 = floatingSpecializedBondAssetSwap1.fairCleanPrice(); double error5 = Math.Abs(floatingBondAssetSwapPrice1-floatingSpecializedBondAssetSwapPrice1); if (error5>tolerance) { Assert.Fail("wrong clean price for frnbond:" + "\n generic frn rate bond's clean price: " + floatingBondAssetSwapPrice1 + "\n equivalent specialized bond's price: " + floatingSpecializedBondAssetSwapPrice1 + "\n error: " + error5 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double floatingBondMktPrice1= 101.33; AssetSwap floatingBondASW1= new AssetSwap(payFixedRate, floatingBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondASW1.setPricingEngine(swapEngine); AssetSwap floatingSpecializedBondASW1= new AssetSwap(payFixedRate, floatingSpecializedBond1, floatingBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingSpecializedBondASW1.setPricingEngine(swapEngine); double floatingBondASWSpread1 = floatingBondASW1.fairSpread(); double floatingSpecializedBondASWSpread1 = floatingSpecializedBondASW1.fairSpread(); double error6 = Math.Abs(floatingBondASWSpread1-floatingSpecializedBondASWSpread1); if (error6>tolerance) { Assert.Fail("wrong asw spread for fixed bond:" + "\n generic frn rate bond's asw spread: " + floatingBondASWSpread1 + "\n equivalent specialized bond's asw spread: " + floatingSpecializedBondASWSpread1 + "\n error: " + error6 + "\n tolerance: " + tolerance); } //FRN bond (Isin: XS0090566539 COE 0 09/24/18) //maturity occurs on a business day Date floatingBondStartDate2 = new Date(24,Month.September,2004); Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); Schedule floatingBondSchedule2= new Schedule(floatingBondStartDate2, floatingBondMaturityDate2, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0025) .inArrears(inArrears) .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); // generic bond Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, floatingBondStartDate2,floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); // equivalent specialized floater Bond floatingSpecializedBond2 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule2, vars.iborIndex, new Actual360(), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>{1}, new List<double>{0.0025}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(24,Month.September,2004)); floatingSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); Utils.setCouponPricer(floatingSpecializedBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); double floatingBondPrice2 = floatingBond2.cleanPrice(); double floatingSpecializedBondPrice2= floatingSpecializedBond2.cleanPrice(); AssetSwap floatingBondAssetSwap2= new AssetSwap(payFixedRate, floatingBond2, floatingBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap2.setPricingEngine(swapEngine); AssetSwap floatingSpecializedBondAssetSwap2= new AssetSwap(payFixedRate, floatingSpecializedBond2, floatingSpecializedBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice(); double floatingSpecializedBondAssetSwapPrice2 = floatingSpecializedBondAssetSwap2.fairCleanPrice(); double error7 = Math.Abs(floatingBondAssetSwapPrice2-floatingSpecializedBondAssetSwapPrice2); if (error7>tolerance) { Assert.Fail("wrong clean price for frnbond:" + "\n generic frn rate bond's clean price: " + floatingBondAssetSwapPrice2 + "\n equivalent specialized frn bond's price: " + floatingSpecializedBondAssetSwapPrice2 + "\n error: " + error7 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double floatingBondMktPrice2 = 101.26; AssetSwap floatingBondASW2= new AssetSwap(payFixedRate, floatingBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondASW2.setPricingEngine(swapEngine); AssetSwap floatingSpecializedBondASW2= new AssetSwap(payFixedRate, floatingSpecializedBond2, floatingBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingSpecializedBondASW2.setPricingEngine(swapEngine); double floatingBondASWSpread2 = floatingBondASW2.fairSpread(); double floatingSpecializedBondASWSpread2 = floatingSpecializedBondASW2.fairSpread(); double error8 = Math.Abs(floatingBondASWSpread2-floatingSpecializedBondASWSpread2); if (error8>tolerance) { Assert.Fail("wrong asw spread for frn bond:" + "\n generic frn rate bond's asw spread: " + floatingBondASWSpread2 + "\n equivalent specialized bond's asw spread: " + floatingSpecializedBondASWSpread2 + "\n error: " + error8 + "\n tolerance: " + tolerance); } // CMS bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Date cmsBondStartDate1 = new Date(22,Month.August,2005); Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, cmsBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withCaps(0.055) .withFloors(0.025) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); // generic cms bond Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>{1.0}, new List<double>{0.0}, new List<double>{0.055}, new List<double>{0.025}, inArrears, 100.0, new Date(22,Month.August,2005)); cmsSpecializedBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondPrice1 = cmsBond1.cleanPrice(); double cmsSpecializedBondPrice1 = cmsSpecializedBond1.cleanPrice(); AssetSwap cmsBondAssetSwap1= new AssetSwap(payFixedRate,cmsBond1, cmsBondPrice1, vars.iborIndex, vars.nonnullspread, null,vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap1.setPricingEngine(swapEngine); AssetSwap cmsSpecializedBondAssetSwap1= new AssetSwap(payFixedRate,cmsSpecializedBond1, cmsSpecializedBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice(); double cmsSpecializedBondAssetSwapPrice1 = cmsSpecializedBondAssetSwap1.fairCleanPrice(); double error9 = Math.Abs(cmsBondAssetSwapPrice1-cmsSpecializedBondAssetSwapPrice1); if (error9>tolerance) { Assert.Fail("wrong clean price for cmsbond:" + "\n generic bond's clean price: " + cmsBondAssetSwapPrice1 + "\n equivalent specialized cms rate bond's price: " + cmsSpecializedBondAssetSwapPrice1 + "\n error: " + error9 + "\n tolerance: " + tolerance); } double cmsBondMktPrice1 = 87.02;// market executable price as of 4th sept 2007 AssetSwap cmsBondASW1= new AssetSwap(payFixedRate, cmsBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondASW1.setPricingEngine(swapEngine); AssetSwap cmsSpecializedBondASW1= new AssetSwap(payFixedRate, cmsSpecializedBond1, cmsBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsSpecializedBondASW1.setPricingEngine(swapEngine); double cmsBondASWSpread1 = cmsBondASW1.fairSpread(); double cmsSpecializedBondASWSpread1 = cmsSpecializedBondASW1.fairSpread(); double error10 = Math.Abs(cmsBondASWSpread1-cmsSpecializedBondASWSpread1); if (error10>tolerance) { Assert.Fail("wrong asw spread for cm bond:" + "\n generic cms rate bond's asw spread: " + cmsBondASWSpread1 + "\n equivalent specialized bond's asw spread: " + cmsSpecializedBondASWSpread1 + "\n error: " + error10 + "\n tolerance: " + tolerance); } //CMS bond (Isin: XS0218766664 ISPIM 0 5/6/15) //maturity occurs on a business day Date cmsBondStartDate2 = new Date(06,Month.May,2005); Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, cmsBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withGearings(0.84) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); // generic bond Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); // equivalent specialized cms bond Bond cmsSpecializedBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>{0.84}, new List<double>{0.0}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(06,Month.May,2005)); cmsSpecializedBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); Utils.setCouponPricer(cmsSpecializedBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondPrice2 = cmsBond2.cleanPrice(); double cmsSpecializedBondPrice2 = cmsSpecializedBond2.cleanPrice(); AssetSwap cmsBondAssetSwap2= new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap2.setPricingEngine(swapEngine); AssetSwap cmsSpecializedBondAssetSwap2= new AssetSwap(payFixedRate,cmsSpecializedBond2, cmsSpecializedBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice(); double cmsSpecializedBondAssetSwapPrice2 = cmsSpecializedBondAssetSwap2.fairCleanPrice(); double error11 = Math.Abs(cmsBondAssetSwapPrice2-cmsSpecializedBondAssetSwapPrice2); if (error11>tolerance) { Assert.Fail("wrong clean price for cmsbond:" + "\n generic bond's clean price: " + cmsBondAssetSwapPrice2 + "\n equivalent specialized cms rate bond's price: " + cmsSpecializedBondAssetSwapPrice2 + "\n error: " + error11 + "\n tolerance: " + tolerance); } double cmsBondMktPrice2 = 94.35;// market executable price as of 4th sept 2007 AssetSwap cmsBondASW2= new AssetSwap(payFixedRate, cmsBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondASW2.setPricingEngine(swapEngine); AssetSwap cmsSpecializedBondASW2= new AssetSwap(payFixedRate, cmsSpecializedBond2, cmsBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsSpecializedBondASW2.setPricingEngine(swapEngine); double cmsBondASWSpread2 = cmsBondASW2.fairSpread(); double cmsSpecializedBondASWSpread2 = cmsSpecializedBondASW2.fairSpread(); double error12 = Math.Abs(cmsBondASWSpread2-cmsSpecializedBondASWSpread2); if (error12>tolerance) { Assert.Fail("wrong asw spread for cm bond:" + "\n generic cms rate bond's asw spread: " + cmsBondASWSpread2 + "\n equivalent specialized bond's asw spread: " + cmsSpecializedBondASWSpread2 + "\n error: " + error12 + "\n tolerance: " + tolerance); } // Zero-Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; // generic bond Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); // specialized zerocpn bond Bond zeroCpnSpecializedBond1= new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(20,Month.December,2015), BusinessDayConvention.Following, 100.0, new Date(19,Month.December,1985)); zeroCpnSpecializedBond1.setPricingEngine(bondEngine); double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice(); double zeroCpnSpecializedBondPrice1 = zeroCpnSpecializedBond1.cleanPrice(); AssetSwap zeroCpnBondAssetSwap1= new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondAssetSwap1.setPricingEngine(swapEngine); AssetSwap zeroCpnSpecializedBondAssetSwap1= new AssetSwap(payFixedRate, zeroCpnSpecializedBond1, zeroCpnSpecializedBondPrice1, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnSpecializedBondAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice1 = zeroCpnBondAssetSwap1.fairCleanPrice(); double zeroCpnSpecializedBondAssetSwapPrice1 = zeroCpnSpecializedBondAssetSwap1.fairCleanPrice(); double error13 = Math.Abs(zeroCpnBondAssetSwapPrice1-zeroCpnSpecializedBondAssetSwapPrice1); if (error13>tolerance) { Assert.Fail("wrong clean price for zerocpn bond:" + "\n generic zero cpn bond's clean price: " + zeroCpnBondAssetSwapPrice1 + "\n specialized equivalent bond's price: " + zeroCpnSpecializedBondAssetSwapPrice1 + "\n error: " + error13 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double zeroCpnBondMktPrice1 = 72.277; AssetSwap zeroCpnBondASW1= new AssetSwap(payFixedRate, zeroCpnBond1,zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondASW1.setPricingEngine(swapEngine); AssetSwap zeroCpnSpecializedBondASW1= new AssetSwap(payFixedRate, zeroCpnSpecializedBond1, zeroCpnBondMktPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnSpecializedBondASW1.setPricingEngine(swapEngine); double zeroCpnBondASWSpread1 = zeroCpnBondASW1.fairSpread(); double zeroCpnSpecializedBondASWSpread1 = zeroCpnSpecializedBondASW1.fairSpread(); double error14 = Math.Abs(zeroCpnBondASWSpread1-zeroCpnSpecializedBondASWSpread1); if (error14>tolerance) { Assert.Fail("wrong asw spread for zeroCpn bond:" + "\n generic zeroCpn bond's asw spread: " + zeroCpnBondASWSpread1 + "\n equivalent specialized bond's asw spread: " + zeroCpnSpecializedBondASWSpread1 + "\n error: " + error14 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity doesn't occur on a business day Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; // generic bond Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); // specialized zerocpn bond Bond zeroCpnSpecializedBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(17,Month.February,2028), BusinessDayConvention.Following, 100.0, new Date(17,Month.February,1998)); zeroCpnSpecializedBond2.setPricingEngine(bondEngine); double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); double zeroCpnSpecializedBondPrice2 = zeroCpnSpecializedBond2.cleanPrice(); AssetSwap zeroCpnBondAssetSwap2= new AssetSwap(payFixedRate,zeroCpnBond2, zeroCpnBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondAssetSwap2.setPricingEngine(swapEngine); AssetSwap zeroCpnSpecializedBondAssetSwap2= new AssetSwap(payFixedRate, zeroCpnSpecializedBond2, zeroCpnSpecializedBondPrice2, vars.iborIndex, vars.nonnullspread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnSpecializedBondAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice2 = zeroCpnBondAssetSwap2.fairCleanPrice(); double zeroCpnSpecializedBondAssetSwapPrice2 = zeroCpnSpecializedBondAssetSwap2.fairCleanPrice(); double error15 = Math.Abs(zeroCpnBondAssetSwapPrice2 -zeroCpnSpecializedBondAssetSwapPrice2); if (error15>tolerance) { Assert.Fail("wrong clean price for zerocpn bond:" + "\n generic zero cpn bond's clean price: " + zeroCpnBondAssetSwapPrice2 + "\n equivalent specialized bond's price: " + zeroCpnSpecializedBondAssetSwapPrice2 + "\n error: " + error15 + "\n tolerance: " + tolerance); } // market executable price as of 4th sept 2007 double zeroCpnBondMktPrice2 = 72.277; AssetSwap zeroCpnBondASW2= new AssetSwap(payFixedRate, zeroCpnBond2,zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnBondASW2.setPricingEngine(swapEngine); AssetSwap zeroCpnSpecializedBondASW2= new AssetSwap(payFixedRate, zeroCpnSpecializedBond2, zeroCpnBondMktPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnSpecializedBondASW2.setPricingEngine(swapEngine); double zeroCpnBondASWSpread2 = zeroCpnBondASW2.fairSpread(); double zeroCpnSpecializedBondASWSpread2 = zeroCpnSpecializedBondASW2.fairSpread(); double error16 = Math.Abs(zeroCpnBondASWSpread2-zeroCpnSpecializedBondASWSpread2); if (error16>tolerance) { Assert.Fail("wrong asw spread for zeroCpn bond:" + "\n generic zeroCpn bond's asw spread: " + zeroCpnBondASWSpread2 + "\n equivalent specialized bond's asw spread: " + zeroCpnSpecializedBondASWSpread2 + "\n error: " + error16 + "\n tolerance: " + tolerance); } }
public void testYield() { //"Testing consistency of bond price/yield calculation..."); CommonVars vars = new CommonVars(); double tolerance = 1.0e-7; int maxEvaluations = 100; int[] issueMonths = new int[] { -24, -18, -12, -6, 0, 6, 12, 18, 24 }; int[] lengths = new int[] { 3, 5, 10, 15, 20 }; int settlementDays = 3; double[] coupons = new double[] { 0.02, 0.05, 0.08 }; Frequency[] frequencies = new Frequency[] { Frequency.Semiannual, Frequency.Annual }; DayCounter bondDayCount = new Thirty360(); BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing; double redemption = 100.0; double[] yields = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; Compounding[] compounding = new Compounding[] { Compounding.Compounded, Compounding.Continuous }; for (int i = 0; i < issueMonths.Length; i++) { for (int j = 0; j < lengths.Length; j++) { for (int k = 0; k < coupons.Length; k++) { for (int l = 0; l < frequencies.Length; l++) { for (int n = 0; n < compounding.Length; n++) { Date dated = vars.calendar.advance(vars.today, issueMonths[i], TimeUnit.Months); Date issue = dated; Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years); Schedule sch = new Schedule(dated, maturity, new Period(frequencies[l]), vars.calendar, accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List<double>() { coupons[k] }, bondDayCount, paymentConvention, redemption, issue); for (int m = 0; m < yields.Length; m++) { double price = bond.cleanPrice(yields[m], bondDayCount, compounding[n], frequencies[l]); double calculated = bond.yield(price, bondDayCount, compounding[n], frequencies[l], null, tolerance, maxEvaluations); if (Math.Abs(yields[m] - calculated) > tolerance) { // the difference might not matter double price2 = bond.cleanPrice(calculated, bondDayCount, compounding[n], frequencies[l]); if (Math.Abs(price - price2) / price > tolerance) { Assert.Fail("yield recalculation failed:\n" + " issue: " + issue + "\n" + " maturity: " + maturity + "\n" + " coupon: " + coupons[k] + "\n" + " frequency: " + frequencies[l] + "\n\n" + " yield: " + yields[m] + " " + (compounding[n] == Compounding.Compounded ? "compounded" : "continuous") + "\n" + " price: " + price + "\n" + " yield': " + calculated + "\n" + " price': " + price2); } } } } } } } } }
public void testTheoretical() { // "Testing theoretical bond price/yield calculation..."); CommonVars vars = new CommonVars(); double tolerance = 1.0e-7; int maxEvaluations = 100; int[] lengths = new int[] { 3, 5, 10, 15, 20 }; int settlementDays = 3; double[] coupons = new double[] { 0.02, 0.05, 0.08 }; Frequency[] frequencies = new Frequency[] { Frequency.Semiannual, Frequency.Annual }; DayCounter bondDayCount = new Actual360(); BusinessDayConvention accrualConvention = BusinessDayConvention.Unadjusted; BusinessDayConvention paymentConvention = BusinessDayConvention.ModifiedFollowing; double redemption = 100.0; double[] yields = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; for (int j = 0; j < lengths.Length; j++) { for (int k = 0; k < coupons.Length; k++) { for (int l = 0; l < frequencies.Length; l++) { Date dated = vars.today; Date issue = dated; Date maturity = vars.calendar.advance(issue, lengths[j], TimeUnit.Years); SimpleQuote rate = new SimpleQuote(0.0); var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(vars.today, rate, bondDayCount)); Schedule sch = new Schedule(dated, maturity, new Period(frequencies[l]), vars.calendar, accrualConvention, accrualConvention, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List<double>() { coupons[k] }, bondDayCount, paymentConvention, redemption, issue); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond.setPricingEngine(bondEngine); for (int m = 0; m < yields.Length; m++) { rate.setValue(yields[m]); double price = bond.cleanPrice(yields[m], bondDayCount, Compounding.Continuous, frequencies[l]); double calculatedPrice = bond.cleanPrice(); if (Math.Abs(price - calculatedPrice) > tolerance) { Assert.Fail("price calculation failed:" + "\n issue: " + issue + "\n maturity: " + maturity + "\n coupon: " + coupons[k] + "\n frequency: " + frequencies[l] + "\n" + "\n yield: " + yields[m] + "\n expected: " + price + "\n calculated': " + calculatedPrice + "\n error': " + (price - calculatedPrice)); } double calculatedYield = bond.yield(bondDayCount, Compounding.Continuous, frequencies[l], tolerance, maxEvaluations); if (Math.Abs(yields[m] - calculatedYield) > tolerance) { Assert.Fail("yield calculation failed:" + "\n issue: " + issue + "\n maturity: " + maturity + "\n coupon: " + coupons[k] + "\n frequency: " + frequencies[l] + "\n" + "\n yield: " + yields[m] + "\n price: " + price + "\n yield': " + calculatedYield); } } } } } }
public void testImpliedVolatility() { //"Testing implied volatility for swaptions..."; CommonVars vars=new CommonVars(); int maxEvaluations = 100; double tolerance = 1.0e-08; Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash }; // test data double[] strikes = { 0.02, 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] vols = { 0.01, 0.05, 0.10, 0.20, 0.30, 0.70, 0.90 }; for (int i = 0; i < exercises.Length; i++) { for (int j = 0; j < lengths.Length; j++) { Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays, TimeUnit.Days); Date maturity = vars.calendar.advance(startDate, lengths[j], vars.floatingConvention); for (int t = 0; t < strikes.Length; t++) { for (int k = 0; k < type.Length; k++) { VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[t]) .withEffectiveDate(startDate) .withFloatingLegSpread(0.0) .withType(type[k]); for (int h = 0; h < types.Length; h++) { for (int u = 0; u < vols.Length; u++) { Swaption swaption = vars.makeSwaption(swap, exerciseDate, vols[u], types[h]); // Black price double value = swaption.NPV(); double implVol = 0.0; try { implVol = swaption.impliedVolatility(value, vars.termStructure, 0.10, tolerance, maxEvaluations); } catch (System.Exception e) { // couldn't bracket? swaption.setPricingEngine(vars.makeEngine(0.0)); double value2 = swaption.NPV(); if (Math.Abs(value - value2) < tolerance) { // ok, just skip: continue; } // otherwise, report error Assert.Fail("implied vol failure: " + exercises[i] + "x" + lengths[j] + " " + type[k] + "\nsettlement: " + types[h] + "\nstrike " + strikes[t] + "\natm level: " + swap.fairRate() + "\nvol: " + vols[u] + "\nprice: " + value + "\n" + e.Message.ToString()); } if (Math.Abs(implVol - vols[u]) > tolerance) { // the difference might not matter swaption.setPricingEngine(vars.makeEngine(implVol)); double value2 = swaption.NPV(); if (Math.Abs(value - value2) > tolerance) { Assert.Fail("implied vol failure: " + exercises[i] + "x" + lengths[j] + " " + type[k] + "\nsettlement: " + types[h] + "\nstrike " + strikes[t] + "\natm level: " + swap.fairRate() + "\nvol: " + vols[u] + "\nprice: " + value + "\nimplied vol: " + implVol + "\nimplied price: " + value2); } } } } } } } } }
public void testVega() { //"Testing swaption vega..."; CommonVars vars = new CommonVars(); Settlement.Type[] types = { Settlement.Type.Physical, Settlement.Type.Cash }; double[] strikes = { 0.03, 0.04, 0.05, 0.06, 0.07 }; double[] vols = { 0.01, 0.20, 0.30, 0.70, 0.90 }; double shift = 1e-8; for (int i=0; i<exercises.Length ; i++) { Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); // A VERIFIER§§§§ Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays, TimeUnit.Days); for (int j=0; j<lengths.Length ; j++) { for (int t=0; t<strikes.Length ; t++) { for (int h=0; h<type.Length ; h++) { VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[t]) .withEffectiveDate(startDate) .withFloatingLegSpread(0.0) .withType(type[h]); for (int u=0; u<vols.Length ; u++) { Swaption swaption = vars.makeSwaption(swap, exerciseDate, vols[u], types[h]); // FLOATING_POINT_EXCEPTION Swaption swaption1 = vars.makeSwaption(swap, exerciseDate, vols[u]-shift, types[h]); Swaption swaption2 = vars.makeSwaption(swap, exerciseDate, vols[u]+shift, types[h]); double swaptionNPV = swaption.NPV(); double numericalVegaPerPoint = (swaption2.NPV()-swaption1.NPV())/(200.0*shift); // check only relevant vega if (numericalVegaPerPoint/swaptionNPV>1.0e-7) { double analyticalVegaPerPoint = (double)swaption.result("vega")/100.0; double discrepancy = Math.Abs(analyticalVegaPerPoint - numericalVegaPerPoint); discrepancy /= numericalVegaPerPoint; double tolerance = 0.015; if (discrepancy > tolerance) Assert.Fail ("failed to compute swaption vega:" + "\n option tenor: " + exercises[i] + "\n volatility: " + vols[u] + "\n option type: " + swaption.type() + "\n swap tenor: " + lengths[j] + "\n strike: " + strikes[t] + "\n settlement: " + types[h] + "\n nominal: " + swaption.underlyingSwap().nominal + "\n npv: " + swaptionNPV + "\n calculated vega: " + analyticalVegaPerPoint + "\n expected vega: " + numericalVegaPerPoint + "\n discrepancy: " + discrepancy + "\n tolerance: " + tolerance); } } } } } } }
public void testStrikeDependency() { //("Testing swaption dependency on strike......"); CommonVars vars = new CommonVars(); double[] strikes = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; for (int i = 0; i < exercises.Length; i++) { for (int j = 0; j < lengths.Length; j++) { for (int k=0; k < type.Length ; k++) { Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays, TimeUnit.Days); // store the results for different rates... List<double> values = new InitializedList<double>(strikes.Length); List<double> values_cash = new InitializedList<double>(strikes.Length); double vol = 0.20; for (int l=0; l< strikes.Length ; l++) { VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, strikes[l]) .withEffectiveDate(startDate) .withFloatingLegSpread(0.0) .withType(type[k]); Swaption swaption = vars.makeSwaption(swap,exerciseDate,vol); // FLOATING_POINT_EXCEPTION values[l]=swaption.NPV(); Swaption swaption_cash = vars.makeSwaption( swap,exerciseDate,vol, Settlement.Type.Cash); values_cash[l]=swaption_cash.NPV(); } // and check that they go the right way if (type[k]==VanillaSwap.Type.Payer) { for (int z = 0; z < values.Count - 1; z++) { if( values[z]<values[z+1]){ Assert.Fail("NPV of Payer swaption with delivery settlement"+ "is increasing with the strike:" + "\noption tenor: " + exercises[i] + "\noption date: " + exerciseDate + "\nvolatility: " + vol + "\nswap tenor: " + lengths[j] + "\nvalue: " + values[z ] +" at strike: " + strikes[z ] + "\nvalue: " + values[z+1] + " at strike: " + strikes[z+1]); } } for (int z = 0; z < values_cash.Count - 1; z++) { if (values_cash[z] < values_cash[z + 1]) { Assert.Fail("NPV of Payer swaption with cash settlement" + "is increasing with the strike:" + "\noption tenor: " + exercises[i] + "\noption date: " + exerciseDate + "\nvolatility: " + vol + "\nswap tenor: " + lengths[j] + "\nvalue: " + values_cash[z] + " at strike: " + strikes[z] + "\nvalue: " + values_cash[z + 1] + " at strike: " + strikes[z + 1]); } } } else { for (int z = 0; z < values.Count - 1; z++){ if (values[z] > values[z+1]){ Assert.Fail("NPV of Receiver swaption with delivery settlement" + "is increasing with the strike:" + "\noption tenor: " + exercises[i] + "\noption date: " + exerciseDate + "\nvolatility: " + vol + "\nswap tenor: " + lengths[j] + "\nvalue: " + values[z] + " at strike: " + strikes[z] + "\nvalue: " + values[z + 1] + " at strike: " + strikes[z + 1]); } } for (int z = 0; z < values_cash.Count - 1; z++) { if (values[z] > values[z+1]) { Assert.Fail("NPV of Receiver swaption with cash settlement" + "is increasing with the strike:" + "\noption tenor: " + exercises[i] + "\noption date: " + exerciseDate + "\nvolatility: " + vol + "\nswap tenor: " + lengths[j] + "\nvalue: " + values_cash[z] + " at strike: " + strikes[z] + "\nvalue: " + values_cash[z + 1] + " at strike: " + strikes[z + 1]); } } } } } } }
public void testZSpreadWithGenericBond() { // Testing clean and dirty price with null Z-spread against theoretical prices... CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Date fixedBondStartDate1 = new Date(4,Month.January,2005); Date fixedBondMaturityDate1 = new Date(4,Month.January,2037); Schedule fixedBondSchedule1= new Schedule(fixedBondStartDate1, fixedBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg1 = new FixedRateLeg(fixedBondSchedule1) .withCouponRates(0.04, new ActualActual(ActualActual.Convention.ISDA)) .withNotionals(vars.faceAmount); Date fixedbondRedemption1 = bondCalendar.adjust(fixedBondMaturityDate1, BusinessDayConvention.Following); fixedBondLeg1.Add(new SimpleCashFlow(100.0, fixedbondRedemption1)); Bond fixedBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate1, fixedBondStartDate1, fixedBondLeg1); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondImpliedValue1 = fixedBond1.cleanPrice(); Date fixedBondSettlementDate1= fixedBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice1 = BondFunctions.cleanPrice(fixedBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate1); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondImpliedValue1-fixedBondCleanPrice1); if (error1>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + fixedBondImpliedValue1 + "\n par asset swap spread: " + fixedBondCleanPrice1 + "\n error: " + error1 + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Date fixedBondStartDate2 = new Date(5,Month.February,2005); Date fixedBondMaturityDate2 = new Date(5,Month.February,2019); Schedule fixedBondSchedule2= new Schedule(fixedBondStartDate2, fixedBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> fixedBondLeg2 = new FixedRateLeg(fixedBondSchedule2) .withCouponRates(0.05, new Thirty360(Thirty360.Thirty360Convention.BondBasis)) .withNotionals(vars.faceAmount); Date fixedbondRedemption2 = bondCalendar.adjust(fixedBondMaturityDate2, BusinessDayConvention.Following); fixedBondLeg2.Add(new SimpleCashFlow(100.0, fixedbondRedemption2)); Bond fixedBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, fixedBondMaturityDate2, fixedBondStartDate2, fixedBondLeg2); fixedBond2.setPricingEngine(bondEngine); double fixedBondImpliedValue2 = fixedBond2.cleanPrice(); Date fixedBondSettlementDate2= fixedBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double fixedBondCleanPrice2 = BondFunctions.cleanPrice(fixedBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, fixedBondSettlementDate2); double error3 = Math.Abs(fixedBondImpliedValue2-fixedBondCleanPrice2); if (error3>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + fixedBondImpliedValue2 + "\n par asset swap spread: " + fixedBondCleanPrice2 + "\n error: " + error3 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Date floatingBondStartDate1 = new Date(29,Month.September,2003); Date floatingBondMaturityDate1 = new Date(29,Month.September,2013); Schedule floatingBondSchedule1= new Schedule(floatingBondStartDate1, floatingBondMaturityDate1, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg1 = new IborLeg(floatingBondSchedule1, vars.iborIndex) .withPaymentDayCounter(new Actual360()) .withFixingDays(fixingDays) .withSpreads(0.0056) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date floatingbondRedemption1 = bondCalendar.adjust(floatingBondMaturityDate1, BusinessDayConvention.Following); floatingBondLeg1.Add(new SimpleCashFlow(100.0, floatingbondRedemption1)); Bond floatingBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate1, floatingBondStartDate1, floatingBondLeg1); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); double floatingBondImpliedValue1 = floatingBond1.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice1 = BondFunctions.cleanPrice(floatingBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); double error5 = Math.Abs(floatingBondImpliedValue1-floatingBondCleanPrice1); if (error5>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + floatingBondImpliedValue1 + "\n par asset swap spread: " + floatingBondCleanPrice1 + "\n error: " + error5 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Date floatingBondStartDate2 = new Date(24,Month.September,2004); Date floatingBondMaturityDate2 = new Date(24,Month.September,2018); Schedule floatingBondSchedule2 = new Schedule(floatingBondStartDate2, floatingBondMaturityDate2, new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); List<CashFlow> floatingBondLeg2 = new IborLeg(floatingBondSchedule2, vars.iborIndex) .withFixingDays(fixingDays) .withSpreads(0.0025) .withPaymentDayCounter(new Actual360()) .inArrears(inArrears) .withPaymentAdjustment(BusinessDayConvention.ModifiedFollowing) .withNotionals(vars.faceAmount); Date floatingbondRedemption2 = bondCalendar.adjust(floatingBondMaturityDate2, BusinessDayConvention.ModifiedFollowing); floatingBondLeg2.Add(new SimpleCashFlow(100.0, floatingbondRedemption2)); Bond floatingBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, floatingBondMaturityDate2, floatingBondStartDate2, floatingBondLeg2); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(22,Month.March,2007), 0.04013); double floatingBondImpliedValue2 = floatingBond2.cleanPrice(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double floatingBondCleanPrice2 = BondFunctions.cleanPrice(floatingBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Semiannual, fixedBondSettlementDate1); double error7 = Math.Abs(floatingBondImpliedValue2-floatingBondCleanPrice2); if (error7>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + floatingBondImpliedValue2 + "\n par asset swap spread: " + floatingBondCleanPrice2 + "\n error: " + error7 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Date cmsBondStartDate1 = new Date(22,Month.August,2005); Date cmsBondMaturityDate1 = new Date(22,Month.August,2020); Schedule cmsBondSchedule1= new Schedule(cmsBondStartDate1, cmsBondMaturityDate1, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg1 = new CmsLeg(cmsBondSchedule1, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withCaps(0.055) .withFloors(0.025) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption1 = bondCalendar.adjust(cmsBondMaturityDate1, BusinessDayConvention.Following); cmsBondLeg1.Add(new SimpleCashFlow(100.0, cmsbondRedemption1)); Bond cmsBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate1, cmsBondStartDate1, cmsBondLeg1); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(18,Month.August,2006), 0.04158); double cmsBondImpliedValue1 = cmsBond1.cleanPrice(); Date cmsBondSettlementDate1= cmsBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice1 = BondFunctions.cleanPrice(cmsBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate1); double error9 = Math.Abs(cmsBondImpliedValue1-cmsBondCleanPrice1); if (error9>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + cmsBondImpliedValue1 + "\n par asset swap spread: " + cmsBondCleanPrice1 + "\n error: " + error9 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Date cmsBondStartDate2 = new Date(06,Month.May,2005); Date cmsBondMaturityDate2 = new Date(06,Month.May,2015); Schedule cmsBondSchedule2= new Schedule(cmsBondStartDate2, cmsBondMaturityDate2, new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); List<CashFlow> cmsBondLeg2 = new CmsLeg(cmsBondSchedule2, vars.swapIndex) .withPaymentDayCounter(new Thirty360()) .withFixingDays(fixingDays) .withGearings(0.84) .inArrears(inArrears) .withNotionals(vars.faceAmount); Date cmsbondRedemption2 = bondCalendar.adjust(cmsBondMaturityDate2, BusinessDayConvention.Following); cmsBondLeg2.Add(new SimpleCashFlow(100.0, cmsbondRedemption2)); Bond cmsBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, cmsBondMaturityDate2, cmsBondStartDate2, cmsBondLeg2); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing(new Date(04,Month.May,2006), 0.04217); double cmsBondImpliedValue2 = cmsBond2.cleanPrice(); Date cmsBondSettlementDate2= cmsBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double cmsBondCleanPrice2 = BondFunctions.cleanPrice(cmsBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, cmsBondSettlementDate2); double error11 = Math.Abs(cmsBondImpliedValue2-cmsBondCleanPrice2); if (error11>tolerance) { Assert.Fail("wrong clean price for fixed bond:" + "\n market asset swap spread: " + cmsBondImpliedValue2 + "\n par asset swap spread: " + cmsBondCleanPrice2 + "\n error: " + error11 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Date zeroCpnBondStartDate1 = new Date(19,Month.December,1985); Date zeroCpnBondMaturityDate1 = new Date(20,Month.December,2015); Date zeroCpnBondRedemption1 = bondCalendar.adjust(zeroCpnBondMaturityDate1, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg1 = new List<CashFlow>{new SimpleCashFlow(100.0, zeroCpnBondRedemption1)}; Bond zeroCpnBond1 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate1, zeroCpnBondStartDate1, zeroCpnBondLeg1); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue1 = zeroCpnBond1.cleanPrice(); Date zeroCpnBondSettlementDate1= zeroCpnBond1.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice1 = BondFunctions.cleanPrice(zeroCpnBond1, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate1); double error13 = Math.Abs(zeroCpnBondImpliedValue1-zeroCpnBondCleanPrice1); if (error13>tolerance) { Assert.Fail("wrong clean price for zero coupon bond:" + "\n zero cpn implied value: " + zeroCpnBondImpliedValue1 + "\n zero cpn price: " + zeroCpnBondCleanPrice1 + "\n error: " + error13 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Date zeroCpnBondStartDate2 = new Date(17,Month.February,1998); Date zeroCpnBondMaturityDate2 = new Date(17,Month.February,2028); Date zerocpbondRedemption2 = bondCalendar.adjust(zeroCpnBondMaturityDate2, BusinessDayConvention.Following); List<CashFlow> zeroCpnBondLeg2 = new List<CashFlow>{new SimpleCashFlow(100.0, zerocpbondRedemption2)}; Bond zeroCpnBond2 = new Bond(settlementDays, bondCalendar, vars.faceAmount, zeroCpnBondMaturityDate2, zeroCpnBondStartDate2, zeroCpnBondLeg2); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondImpliedValue2 = zeroCpnBond2.cleanPrice(); Date zeroCpnBondSettlementDate2= zeroCpnBond2.settlementDate(); // standard market conventions: // bond's frequency + coumpounding and daycounter of the YieldCurve double zeroCpnBondCleanPrice2 = BondFunctions.cleanPrice(zeroCpnBond2, vars.termStructure, vars.spread, new Actual365Fixed(), vars.compounding, Frequency.Annual, zeroCpnBondSettlementDate2); double error15 = Math.Abs(zeroCpnBondImpliedValue2-zeroCpnBondCleanPrice2); if (error15>tolerance) { Assert.Fail("wrong clean price for zero coupon bond:" + "\n zero cpn implied value: " + zeroCpnBondImpliedValue2 + "\n zero cpn price: " + zeroCpnBondCleanPrice2 + "\n error: " + error15 + "\n tolerance: " + tolerance); } }
public void testCached() { // ("Testing bond price/yield calculation against cached values..."); CommonVars vars = new CommonVars(); // with implicit settlement calculation: Date today = new Date(22, Month.November, 2004); Settings.setEvaluationDate(today); Calendar bondCalendar = new NullCalendar(); DayCounter bondDayCount = new ActualActual(ActualActual.Convention.ISMA); int settlementDays = 1; var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, new SimpleQuote(0.03), new Actual360())); // actual market values from the evaluation date Frequency freq = Frequency.Semiannual; Schedule sch1 = new Schedule(new Date(31, Month.October, 2004), new Date(31, Month.October, 2006), new Period(freq), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch1, new List<double>() { 0.025 }, bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(1, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); double marketPrice1 = 99.203125; double marketYield1 = 0.02925; Schedule sch2 = new Schedule(new Date(15, Month.November, 2004), new Date(15, Month.November, 2009), new Period(freq), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch2, new List<double>() { 0.035 }, bondDayCount, BusinessDayConvention.ModifiedFollowing, 100.0, new Date(15, Month.November, 2004)); bond2.setPricingEngine(bondEngine); double marketPrice2 = 99.6875; double marketYield2 = 0.03569; // calculated values double cachedPrice1a = 99.204505, cachedPrice2a = 99.687192; double cachedPrice1b = 98.943393, cachedPrice2b = 101.986794; double cachedYield1a = 0.029257, cachedYield2a = 0.035689; double cachedYield1b = 0.029045, cachedYield2b = 0.035375; double cachedYield1c = 0.030423, cachedYield2c = 0.030432; // check double tolerance = 1.0e-6; double price, yield; price = bond1.cleanPrice(marketYield1, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(price - cachedPrice1a) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "\n expected: " + cachedPrice1a + "\n tolerance: " + tolerance + "\n error: " + (price - cachedPrice1a)); } price = bond1.cleanPrice(); if (Math.Abs(price - cachedPrice1b) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "\n expected: " + cachedPrice1b + "\n tolerance: " + tolerance + "\n error: " + (price - cachedPrice1b)); } yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(yield - cachedYield1a) > tolerance) { Assert.Fail("failed to reproduce cached compounded yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield1a + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield1a)); } yield = bond1.yield(marketPrice1, bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield1b) > tolerance) { Assert.Fail("failed to reproduce cached continuous yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield1b + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield1b)); } yield = bond1.yield(bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield1c) > tolerance) { Assert.Fail("failed to reproduce cached continuous yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield1c + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield1c)); } price = bond2.cleanPrice(marketYield2, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(price - cachedPrice2a) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "\n expected: " + cachedPrice2a + "\n tolerance: " + tolerance + "\n error: " + (price - cachedPrice2a)); } price = bond2.cleanPrice(); if (Math.Abs(price - cachedPrice2b) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "\n expected: " + cachedPrice2b + "\n tolerance: " + tolerance + "\n error: " + (price - cachedPrice2b)); } yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(yield - cachedYield2a) > tolerance) { Assert.Fail("failed to reproduce cached compounded yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield2a + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield2a)); } yield = bond2.yield(marketPrice2, bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield2b) > tolerance) { Assert.Fail("failed to reproduce cached continuous yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield2b + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield2b)); } yield = bond2.yield(bondDayCount, Compounding.Continuous, freq); if (Math.Abs(yield - cachedYield2c) > tolerance) { Assert.Fail("failed to reproduce cached continuous yield:" + "\n calculated: " + yield + "\n expected: " + cachedYield2c + "\n tolerance: " + tolerance + "\n error: " + (yield - cachedYield2c)); } // with explicit settlement date: Schedule sch3 = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2006), new Period(freq), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, new List<double>() { 0.02875 }, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); double marketYield3 = 0.02997; Date settlementDate = new Date(30, Month.November, 2004); double cachedPrice3 = 99.764759; price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq, settlementDate); if (Math.Abs(price - cachedPrice3) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "" + "\n expected: " + cachedPrice3 + "" + "\n error: " + (price - cachedPrice3)); } // this should give the same result since the issue date is the // earliest possible settlement date Settings.setEvaluationDate(new Date(22, Month.November, 2004)); price = bond3.cleanPrice(marketYield3, bondDayCount, Compounding.Compounded, freq); if (Math.Abs(price - cachedPrice3) > tolerance) { Assert.Fail("failed to reproduce cached price:" + "\n calculated: " + price + "" + "\n expected: " + cachedPrice3 + "" + "\n error: " + (price - cachedPrice3)); } }
public void testImpliedValue() { // Testing implied bond value against asset-swap fair price with null spread CommonVars vars = new CommonVars(); Calendar bondCalendar = new TARGET(); int settlementDays = 3; int fixingDays = 2; bool payFixedRate = true; bool parAssetSwap = true; bool inArrears = false; // Fixed Underlying bond (Isin: DE0001135275 DBR 4 01/04/37) // maturity doesn't occur on a business day Schedule fixedBondSchedule1 = new Schedule( new Date(4,Month.January,2005), new Date(4,Month.January,2037), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond fixedBond1 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule1, new List<double>(){0.04}, new ActualActual(ActualActual.Convention.ISDA), BusinessDayConvention.Following, 100.0, new Date(4,Month.January,2005)); IPricingEngine bondEngine = new DiscountingBondEngine(vars.termStructure); IPricingEngine swapEngine = new DiscountingSwapEngine(vars.termStructure); fixedBond1.setPricingEngine(bondEngine); double fixedBondPrice1 = fixedBond1.cleanPrice(); AssetSwap fixedBondAssetSwap1 = new AssetSwap(payFixedRate, fixedBond1, fixedBondPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondAssetSwap1.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice1 = fixedBondAssetSwap1.fairCleanPrice(); double tolerance = 1.0e-13; double error1 = Math.Abs(fixedBondAssetSwapPrice1-fixedBondPrice1); if (error1>tolerance) { Assert.Fail("wrong zero spread asset swap price for fixed bond:" + "\n bond's clean price: " + fixedBondPrice1 + "\n asset swap fair price: " + fixedBondAssetSwapPrice1 + "\n error: " + error1 + "\n tolerance: " + tolerance); } // Fixed Underlying bond (Isin: IT0006527060 IBRD 5 02/05/19) // maturity occurs on a business day Schedule fixedBondSchedule2 = new Schedule( new Date(5,Month.February,2005), new Date(5,Month.February,2019), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond fixedBond2 = new FixedRateBond(settlementDays, vars.faceAmount, fixedBondSchedule2, new List<double>(){0.05}, new Thirty360(Thirty360.Thirty360Convention.BondBasis), BusinessDayConvention.Following, 100.0, new Date(5,Month.February,2005)); fixedBond2.setPricingEngine(bondEngine); double fixedBondPrice2 = fixedBond2.cleanPrice(); AssetSwap fixedBondAssetSwap2 = new AssetSwap(payFixedRate, fixedBond2, fixedBondPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); fixedBondAssetSwap2.setPricingEngine(swapEngine); double fixedBondAssetSwapPrice2 = fixedBondAssetSwap2.fairCleanPrice(); double error2 = Math.Abs(fixedBondAssetSwapPrice2-fixedBondPrice2); if (error2>tolerance) { Assert.Fail("wrong zero spread asset swap price for fixed bond:" + "\n bond's clean price: " + fixedBondPrice2 + "\n asset swap fair price: " + fixedBondAssetSwapPrice2 + "\n error: " + error2 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: IT0003543847 ISPIM 0 09/29/13) // maturity doesn't occur on a business day Schedule floatingBondSchedule1 = new Schedule( new Date(29,Month.September,2003), new Date(29,Month.September,2013), new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond floatingBond1 = new FloatingRateBond(settlementDays, vars.faceAmount, floatingBondSchedule1, vars.iborIndex, new Actual360(), BusinessDayConvention.Following, fixingDays, new List<double>(){1}, new List<double>(){0.0056}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(29,Month.September,2003)); floatingBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond1.cashflows(), vars.pricer); vars.iborIndex.addFixing(new Date(27,Month.March,2007), 0.0402); double floatingBondPrice1 = floatingBond1.cleanPrice(); AssetSwap floatingBondAssetSwap1 = new AssetSwap(payFixedRate, floatingBond1, floatingBondPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap1.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice1 = floatingBondAssetSwap1.fairCleanPrice(); double error3 = Math.Abs(floatingBondAssetSwapPrice1-floatingBondPrice1); if (error3>tolerance) { Assert.Fail("wrong zero spread asset swap price for floater:" + "\n bond's clean price: " + floatingBondPrice1 + "\n asset swap fair price: " + floatingBondAssetSwapPrice1 + "\n error: " + error3 + "\n tolerance: " + tolerance); } // FRN Underlying bond (Isin: XS0090566539 COE 0 09/24/18) // maturity occurs on a business day Schedule floatingBondSchedule2 = new Schedule( new Date(24,Month.September,2004), new Date(24,Month.September,2018), new Period(Frequency.Semiannual), bondCalendar, BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); Bond floatingBond2 = new FloatingRateBond( settlementDays, vars.faceAmount, floatingBondSchedule2, vars.iborIndex, new Actual360(), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>(){1}, new List<double>(){0.0025}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(24,Month.September,2004)); floatingBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(floatingBond2.cashflows(), vars.pricer); vars.iborIndex.addFixing( new Date(22,Month.March,2007), 0.04013); double currentCoupon=0.04013+0.0025; double floatingCurrentCoupon= floatingBond2.nextCouponRate(); double error4= Math.Abs(floatingCurrentCoupon-currentCoupon); if (error4>tolerance) { Assert.Fail("wrong current coupon is returned for floater bond:" + "\n bond's calculated current coupon: " + currentCoupon + "\n current coupon asked to the bond: " + floatingCurrentCoupon + "\n error: " + error4 + "\n tolerance: " + tolerance); } double floatingBondPrice2 = floatingBond2.cleanPrice(); AssetSwap floatingBondAssetSwap2 = new AssetSwap(payFixedRate,floatingBond2, floatingBondPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); floatingBondAssetSwap2.setPricingEngine(swapEngine); double floatingBondAssetSwapPrice2 = floatingBondAssetSwap2.fairCleanPrice(); double error5 = Math.Abs(floatingBondAssetSwapPrice2-floatingBondPrice2); if (error5>tolerance) { Assert.Fail("wrong zero spread asset swap price for floater:" + "\n bond's clean price: " + floatingBondPrice2 + "\n asset swap fair price: " + floatingBondAssetSwapPrice2 + "\n error: " + error5 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0228052402 CRDIT 0 8/22/20) // maturity doesn't occur on a business day Schedule cmsBondSchedule1 = new Schedule( new Date(22,Month.August,2005), new Date(22,Month.August,2020), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond cmsBond1 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule1, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>(){1.0}, new List<double>(){0.0}, new List<double>(){0.055}, new List<double>(){0.025}, inArrears, 100.0, new Date(22,Month.August,2005)); cmsBond1.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond1.cashflows(), vars.cmspricer); vars.swapIndex.addFixing( new Date(18,Month.August,2006), 0.04158); double cmsBondPrice1 = cmsBond1.cleanPrice(); AssetSwap cmsBondAssetSwap1 = new AssetSwap(payFixedRate, cmsBond1, cmsBondPrice1, vars.iborIndex, vars.spread, null,vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap1.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice1 = cmsBondAssetSwap1.fairCleanPrice(); double error6 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1); if (error6>tolerance) { Assert.Fail("wrong zero spread asset swap price for cms bond:" + "\n bond's clean price: " + cmsBondPrice1 + "\n asset swap fair price: " + cmsBondAssetSwapPrice1 + "\n error: " + error6 + "\n tolerance: " + tolerance); } // CMS Underlying bond (Isin: XS0218766664 ISPIM 0 5/6/15) // maturity occurs on a business day Schedule cmsBondSchedule2 = new Schedule( new Date(06,Month.May,2005), new Date(06,Month.May,2015), new Period(Frequency.Annual), bondCalendar, BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); Bond cmsBond2 = new CmsRateBond(settlementDays, vars.faceAmount, cmsBondSchedule2, vars.swapIndex, new Thirty360(), BusinessDayConvention.Following, fixingDays, new List<double>(){0.84}, new List<double>(){0.0}, new List<double>(), new List<double>(), inArrears, 100.0, new Date(06,Month.May,2005)); cmsBond2.setPricingEngine(bondEngine); Utils.setCouponPricer(cmsBond2.cashflows(), vars.cmspricer); vars.swapIndex.addFixing( new Date(04,Month.May,2006), 0.04217); double cmsBondPrice2 = cmsBond2.cleanPrice(); AssetSwap cmsBondAssetSwap2 = new AssetSwap(payFixedRate,cmsBond2, cmsBondPrice2, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); cmsBondAssetSwap2.setPricingEngine(swapEngine); double cmsBondAssetSwapPrice2 = cmsBondAssetSwap2.fairCleanPrice(); double error7 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); if (error7>tolerance) { Assert.Fail("wrong zero spread asset swap price for cms bond:" + "\n bond's clean price: " + cmsBondPrice2 + "\n asset swap fair price: " + cmsBondAssetSwapPrice2 + "\n error: " + error7 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: DE0004771662 IBRD 0 12/20/15) // maturity doesn't occur on a business day Bond zeroCpnBond1 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(20,Month.December,2015), BusinessDayConvention.Following, 100.0, new Date(19,Month.December,1985)); zeroCpnBond1.setPricingEngine(bondEngine); double zeroCpnBondPrice1 = zeroCpnBond1.cleanPrice(); AssetSwap zeroCpnAssetSwap1 = new AssetSwap(payFixedRate,zeroCpnBond1, zeroCpnBondPrice1, vars.iborIndex, vars.spread, null, vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnAssetSwap1.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice1 = zeroCpnAssetSwap1.fairCleanPrice(); double error8 = Math.Abs(cmsBondAssetSwapPrice1-cmsBondPrice1); if (error8>tolerance) { Assert.Fail("wrong zero spread asset swap price for zero cpn bond:" + "\n bond's clean price: " + zeroCpnBondPrice1 + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice1 + "\n error: " + error8 + "\n tolerance: " + tolerance); } // Zero Coupon bond (Isin: IT0001200390 ISPIM 0 02/17/28) // maturity occurs on a business day Bond zeroCpnBond2 = new ZeroCouponBond(settlementDays, bondCalendar, vars.faceAmount, new Date(17,Month.February,2028), BusinessDayConvention.Following, 100.0, new Date(17,Month.February,1998)); zeroCpnBond2.setPricingEngine(bondEngine); double zeroCpnBondPrice2 = zeroCpnBond2.cleanPrice(); AssetSwap zeroCpnAssetSwap2 = new AssetSwap(payFixedRate, zeroCpnBond2, zeroCpnBondPrice2, vars.iborIndex, vars.spread, null,vars.iborIndex.dayCounter(), parAssetSwap); zeroCpnAssetSwap2.setPricingEngine(swapEngine); double zeroCpnBondAssetSwapPrice2 = zeroCpnAssetSwap2.fairCleanPrice(); double error9 = Math.Abs(cmsBondAssetSwapPrice2-cmsBondPrice2); if (error9>tolerance) { Assert.Fail("wrong zero spread asset swap price for zero cpn bond:" + "\n bond's clean price: " + zeroCpnBondPrice2 + "\n asset swap fair price: " + zeroCpnBondAssetSwapPrice2 + "\n error: " + error9 + "\n tolerance: " + tolerance); } }
public void testCachedFixed() { // "Testing fixed-coupon bond prices against cached values..."); CommonVars vars = new CommonVars(); Date today = new Date(22, Month.November, 2004); Settings.setEvaluationDate(today); int settlementDays = 1; var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360())); double tolerance = 1.0e-6; // plain Schedule sch = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2008), new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond1 = new FixedRateBond(settlementDays, vars.faceAmount, sch, new List<double>() { 0.02875 }, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); double cachedPrice1 = 99.298100; double price = bond1.cleanPrice(); if (Math.Abs(price - cachedPrice1) > tolerance) { Console.WriteLine("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice1 + "\n" + " error: " + (price - cachedPrice1)); } // varying coupons InitializedList<double> couponRates = new InitializedList<double>(4); couponRates[0] = 0.02875; couponRates[1] = 0.03; couponRates[2] = 0.03125; couponRates[3] = 0.0325; FixedRateBond bond2 = new FixedRateBond(settlementDays, vars.faceAmount, sch, couponRates, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond2.setPricingEngine(bondEngine); double cachedPrice2 = 100.334149; price = bond2.cleanPrice(); if (Math.Abs(price - cachedPrice2) > tolerance) { Console.WriteLine("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice2 + "\n" + " error: " + (price - cachedPrice2)); } // stub date Schedule sch3 = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.March, 2009), new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false, null, new Date(30, Month.November, 2008)); FixedRateBond bond3 = new FixedRateBond(settlementDays, vars.faceAmount, sch3, couponRates, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); double cachedPrice3 = 100.382794; price = bond3.cleanPrice(); if (Math.Abs(price - cachedPrice3) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice3 + "\n" + " error: " + (price - cachedPrice3)); } }
public void testCachedFloating() { // "Testing floating-rate bond prices against cached values..."); CommonVars vars = new CommonVars(); Date today = new Date(22, Month.November, 2004); Settings.setEvaluationDate(today); int settlementDays = 1; var riskFreeRate = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.025, new Actual360())); var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360())); IborIndex index = new USDLibor(new Period(6, TimeUnit.Months), riskFreeRate); int fixingDays = 1; double tolerance = 1.0e-6; IborCouponPricer pricer = new BlackIborCouponPricer(new Handle<OptionletVolatilityStructure>()); // plain Schedule sch = new Schedule(new Date(30, Month.November, 2004), new Date(30, Month.November, 2008), new Period(Frequency.Semiannual), new UnitedStates(UnitedStates.Market.GovernmentBond), BusinessDayConvention.ModifiedFollowing, BusinessDayConvention.ModifiedFollowing, DateGeneration.Rule.Backward, false); FloatingRateBond bond1 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, index, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>(), new List<double>(), new List<double>(), new List<double>(), false, 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(riskFreeRate); bond1.setPricingEngine(bondEngine); Utils.setCouponPricer(bond1.cashflows(), pricer); #if QL_USE_INDEXED_COUPON double cachedPrice1 = 99.874645; #else double cachedPrice1 = 99.874646; #endif double price = bond1.cleanPrice(); if (Math.Abs(price - cachedPrice1) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice1 + "\n" + " error: " + (price - cachedPrice1)); } // different risk-free and discount curve FloatingRateBond bond2 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, index, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>(), new List<double>(), new List<double>(), new List<double>(), false, 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine2 = new DiscountingBondEngine(discountCurve); bond2.setPricingEngine(bondEngine2); Utils.setCouponPricer(bond2.cashflows(), pricer); #if QL_USE_INDEXED_COUPON double cachedPrice2 = 97.955904; #else double cachedPrice2 = 97.955904; #endif price = bond2.cleanPrice(); if (Math.Abs(price - cachedPrice2) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice2 + "\n" + " error: " + (price - cachedPrice2)); } // varying spread InitializedList<double> spreads = new InitializedList<double>(4); spreads[0] = 0.001; spreads[1] = 0.0012; spreads[2] = 0.0014; spreads[3] = 0.0016; FloatingRateBond bond3 = new FloatingRateBond(settlementDays, vars.faceAmount, sch, index, new ActualActual(ActualActual.Convention.ISMA), BusinessDayConvention.ModifiedFollowing, fixingDays, new List<double>(), spreads, new List<double>(), new List<double>(), false, 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine2); Utils.setCouponPricer(bond3.cashflows(), pricer); #if QL_USE_INDEXED_COUPON double cachedPrice3 = 98.495458; #else double cachedPrice3 = 98.495459; #endif price = bond3.cleanPrice(); if (Math.Abs(price - cachedPrice3) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice3 + "\n" + " error: " + (price - cachedPrice3)); } }
public void testCachedZero() { Console.WriteLine("Testing zero-coupon bond prices against cached values..."); CommonVars vars = new CommonVars(); Date today = new Date(22, Month.November, 2004); Settings.setEvaluationDate(today); int settlementDays = 1; var discountCurve = new Handle<YieldTermStructure>(Utilities.flatRate(today, 0.03, new Actual360())); double tolerance = 1.0e-6; // plain ZeroCouponBond bond1 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), vars.faceAmount, new Date(30, Month.November, 2008), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); IPricingEngine bondEngine = new DiscountingBondEngine(discountCurve); bond1.setPricingEngine(bondEngine); double cachedPrice1 = 88.551726; double price = bond1.cleanPrice(); if (Math.Abs(price - cachedPrice1) > tolerance) { Console.WriteLine("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice1 + "\n" + " error: " + (price - cachedPrice1)); } ZeroCouponBond bond2 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), vars.faceAmount, new Date(30, Month.November, 2007), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond2.setPricingEngine(bondEngine); double cachedPrice2 = 91.278949; price = bond2.cleanPrice(); if (Math.Abs(price - cachedPrice2) > tolerance) { Console.WriteLine("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice2 + "\n" + " error: " + (price - cachedPrice2)); } ZeroCouponBond bond3 = new ZeroCouponBond(settlementDays, new UnitedStates(UnitedStates.Market.GovernmentBond), vars.faceAmount, new Date(30, Month.November, 2006), BusinessDayConvention.ModifiedFollowing, 100.0, new Date(30, Month.November, 2004)); bond3.setPricingEngine(bondEngine); double cachedPrice3 = 94.098006; price = bond3.cleanPrice(); if (Math.Abs(price - cachedPrice3) > tolerance) { Console.WriteLine("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice3 + "\n" + " error: " + (price - cachedPrice3)); } }
public void testBrazilianCached() { //("Testing Brazilian public bond prices against cached values..."); CommonVars vars = new CommonVars(); double faceAmount = 1000.0; double redemption = 100.0; Date issueDate = new Date(1, Month.January, 2007); Date today = new Date(6, Month.June, 2007); Settings.setEvaluationDate(today); // NTN-F maturity dates InitializedList<Date> maturityDates = new InitializedList<Date>(6); maturityDates[0] = new Date(1, Month.January, 2008); maturityDates[1] = new Date(1, Month.January, 2010); maturityDates[2] = new Date(1, Month.July, 2010); maturityDates[3] = new Date(1, Month.January, 2012); maturityDates[4] = new Date(1, Month.January, 2014); maturityDates[5] = new Date(1, Month.January, 2017); // NTN-F yields InitializedList<double> yields = new InitializedList<double>(6); yields[0] = 0.114614; yields[1] = 0.105726; yields[2] = 0.105328; yields[3] = 0.104283; yields[4] = 0.103218; yields[5] = 0.102948; // NTN-F prices InitializedList<double> prices = new InitializedList<double>(6); prices[0] = 1034.63031372; prices[1] = 1030.09919487; prices[2] = 1029.98307160; prices[3] = 1028.13585068; prices[4] = 1028.33383817; prices[5] = 1026.19716497; int settlementDays = 1; vars.faceAmount = 1000.0; // The tolerance is high because Andima truncate yields double tolerance = 1.0e-4; InitializedList<InterestRate> couponRates = new InitializedList<InterestRate>(1); couponRates[0] = new InterestRate(0.1, new Thirty360(), Compounding.Compounded, Frequency.Annual); for (int bondIndex = 0; bondIndex < maturityDates.Count; bondIndex++) { // plain InterestRate yield = new InterestRate(yields[bondIndex], new Business252(new Brazil()), Compounding.Compounded, Frequency.Annual); Schedule schedule = new Schedule(new Date(1, Month.January, 2007), maturityDates[bondIndex], new Period(Frequency.Semiannual), new Brazil(Brazil.Market.Settlement), BusinessDayConvention.Unadjusted, BusinessDayConvention.Unadjusted, DateGeneration.Rule.Backward, false); FixedRateBond bond = new FixedRateBond(settlementDays, faceAmount, schedule, couponRates, BusinessDayConvention.Following, redemption, issueDate); double cachedPrice = prices[bondIndex]; double price = vars.faceAmount * (bond.cleanPrice(yield.rate(), yield.dayCounter(), yield.compounding(), yield.frequency(), today) + bond.accruedAmount(today)) / 100; if (Math.Abs(price - cachedPrice) > tolerance) { Assert.Fail("failed to reproduce cached price:\n" + " calculated: " + price + "\n" + " expected: " + cachedPrice + "\n" + " error: " + (price - cachedPrice) + "\n" ); } } }
public void testSpreadDependency() { //"Testing swaption dependency on spread..."; CommonVars vars = new CommonVars(); double[] spreads = { -0.002, -0.001, 0.0, 0.001, 0.002 }; for (int i=0; i<exercises.Length ; i++) { for (int j=0; j<lengths.Length ; j++) { for (int k=0; k<type.Length ; k++) { Date exerciseDate = vars.calendar.advance(vars.today, exercises[i]); Date startDate = vars.calendar.advance(exerciseDate, vars.settlementDays,TimeUnit.Days); // store the results for different rates... List<double> values=new InitializedList<double>(spreads.Length); List<double> values_cash = new InitializedList<double>(spreads.Length); for (int l=0; l<spreads.Length; l++) { VanillaSwap swap = new MakeVanillaSwap(lengths[j], vars.index, 0.06) .withEffectiveDate(startDate) .withFloatingLegSpread(spreads[l]) .withType(type[k]); Swaption swaption = vars.makeSwaption(swap,exerciseDate,0.20); // FLOATING_POINT_EXCEPTION values[l]=swaption.NPV(); Swaption swaption_cash = vars.makeSwaption(swap,exerciseDate,0.20, Settlement.Type.Cash); values_cash[l]=swaption_cash.NPV(); } // and check that they go the right way if (type[k]==VanillaSwap.Type.Payer) { for (int n = 0; n < spreads.Length - 1; n++) { if (values[n] > values[n + 1]) Assert.Fail("NPV is decreasing with the spread " + "in a payer swaption (physical delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values[n] + " for spread: " + spreads[n] + "\nvalue: " + values[n + 1] + " for spread: " + spreads[n + 1]); if (values_cash[n] > values_cash[n + 1]) Assert.Fail("NPV is decreasing with the spread " + "in a payer swaption (cash delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values_cash[n] + " for spread: " + spreads[n] + "\nvalue: " + values_cash[n + 1] + " for spread: " + spreads[n + 1]); } } else { for (int n = 0; n < spreads.Length - 1; n++) { if (values[n] < values[n + 1]) Assert.Fail("NPV is increasing with the spread " + "in a receiver swaption (physical delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values[n] + " for spread: " + spreads[n] + "\nvalue: " + values[n + 1] + " for spread: " + spreads[n + 1]); if (values_cash[n] < values_cash[n+1]) Assert.Fail("NPV is increasing with the spread " + "in a receiver swaption (cash delivered):" + "\nexercise date: " + exerciseDate + "\nlength: " + lengths[j] + "\nvalue: " + values_cash[n ] + " for spread: " + spreads[n] + "\nvalue: " + values_cash[n+1] + " for spread: " + spreads[n+1]); } } } } } }