public void testRateDependency() { //("Testing vanilla-swap dependency on 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 }; double[] rates = new double[] { 0.03, 0.04, 0.05, 0.06, 0.07 }; for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < spreads.Length; j++) { // store the results for different rates... List <double> swap_values = new List <double>(); for (int k = 0; k < rates.Length; k++) { VanillaSwap swap = vars.makeSwap(lengths[i], rates[k], spreads[j]); swap_values.Add(swap.NPV()); } // and check that they go the right way for (int z = 0; z < swap_values.Count - 1; z++) { if (swap_values[z] < swap_values[z + 1]) { Assert.Fail( "NPV is increasing with the fixed rate in a swap: \n" + " length: " + lengths[i] + " years\n" + " value: " + swap_values[z] + " paying fixed rate: " + rates[z] + "\n" + " value: " + swap_values[z + 1] + " paying fixed rate: " + rates[z + 1]); } } } } }
public void testCachedValue() { // Testing Eonia-swap calculation against cached value... CommonVars vars = new CommonVars(); Settings.setEvaluationDate(vars.today); vars.settlement = vars.calendar.advance(vars.today, vars.settlementDays, TimeUnit.Days); double flat = 0.05; vars.eoniaTermStructure.linkTo(Utilities.flatRate(vars.settlement, flat, new Actual360())); double fixedRate = Math.Exp(flat) - 1; OvernightIndexedSwap swap = vars.makeSwap(new Period(1, TimeUnit.Years), fixedRate, 0.0); double cachedNPV = 0.001730450147; double tolerance = 1.0e-11; if (Math.Abs(swap.NPV() - cachedNPV) > tolerance) { QAssert.Fail("\nfailed to reproduce cached swap value:" + "\ncalculated: " + swap.NPV() + "\n expected: " + cachedNPV + "\n tolerance:" + tolerance); } }
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 testBootstrap() { // Testing Eonia-swap curve building... CommonVars vars = new CommonVars(); List <RateHelper> eoniaHelpers = new List <RateHelper>(); List <RateHelper> swap3mHelpers = new List <RateHelper>(); IborIndex euribor3m = new Euribor3M(); Eonia eonia = new Eonia(); for (int i = 0; i < depositData.Length; i++) { double rate = 0.01 * depositData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period term = new Period(depositData[i].n, depositData[i].unit); RateHelper helper = new DepositRateHelper(quote, term, depositData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); if (term <= new Period(2, TimeUnit.Days)) { eoniaHelpers.Add(helper); } if (term <= new Period(3, TimeUnit.Months)) { swap3mHelpers.Add(helper); } } for (int i = 0; i < fraData.Length; i++) { double rate = 0.01 * fraData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); RateHelper helper = new FraRateHelper(quote, fraData[i].nExpiry, fraData[i].nMaturity, fraData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); swap3mHelpers.Add(helper); } for (int i = 0; i < eoniaSwapData.Length; i++) { double rate = 0.01 * eoniaSwapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); RateHelper helper = new OISRateHelper(eoniaSwapData[i].settlementDays, term, quote, eonia); eoniaHelpers.Add(helper); } for (int i = 0; i < swapData.Length; i++) { double rate = 0.01 * swapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle <Quote> quote = new Handle <Quote>(simple); Period tenor = new Period(swapData[i].nIndexUnits, swapData[i].indexUnit); Period term = new Period(swapData[i].nTermUnits, swapData[i].termUnit); RateHelper helper = new SwapRateHelper(quote, term, vars.calendar, vars.fixedSwapFrequency, vars.fixedSwapConvention, vars.fixedSwapDayCount, euribor3m); if (tenor == new Period(3, TimeUnit.Months)) { swap3mHelpers.Add(helper); } } PiecewiseYieldCurve <Discount, LogLinear> eoniaTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today, eoniaHelpers, new Actual365Fixed()); PiecewiseYieldCurve <Discount, LogLinear> swapTS = new PiecewiseYieldCurve <Discount, LogLinear>(vars.today, swap3mHelpers, new Actual365Fixed()); vars.eoniaTermStructure.linkTo(eoniaTS); // test curve consistency double tolerance = 1.0e-10; for (int i = 0; i < eoniaSwapData.Length; i++) { double expected = eoniaSwapData[i].rate; Period term = new Period(eoniaSwapData[i].n, eoniaSwapData[i].unit); OvernightIndexedSwap swap = vars.makeSwap(term, 0.0, 0.0); double?calculated = 100.0 * swap.fairRate(); if (Math.Abs(expected - calculated.Value) > tolerance) { QAssert.Fail("curve inconsistency:\n" + " swap length: " + term + "\n" + " quoted rate: " + expected + "\n" + " calculated rate: " + calculated); } } }
public void testCachedValues() { //("Testing Bermudan swaption against cached values..."); CommonVars vars = new CommonVars(); vars.today = new Date(15, Month.February, 2002); Settings.setEvaluationDate(vars.today); vars.settlement = new Date(19, Month.February, 2002); // flat yield term structure impling 1x5 swap at 5% vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.04875825, new Actual365Fixed())); double atmRate = vars.makeSwap(0.0).fairRate(); VanillaSwap itmSwap = vars.makeSwap(0.8 * atmRate); VanillaSwap atmSwap = vars.makeSwap(atmRate); VanillaSwap otmSwap = vars.makeSwap(1.2 * atmRate); double a = 0.048696, sigma = 0.0058904; ShortRateModel model = new HullWhite(vars.termStructure, a, sigma); List <Date> exerciseDates = new List <Date>(); List <CashFlow> leg = atmSwap.fixedLeg(); for (int i = 0; i < leg.Count; i++) { Coupon coupon = (Coupon)(leg[i]); exerciseDates.Add(coupon.accrualStartDate()); } Exercise exercise = new BermudanExercise(exerciseDates); IPricingEngine treeEngine = new TreeSwaptionEngine(model, 50); IPricingEngine fdmEngine = new FdHullWhiteSwaptionEngine(model as HullWhite); #if QL_USE_INDEXED_COUPON double itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759; double itmValueFdm = 42.2111, atmValueFdm = 12.8879, otmValueFdm = 2.44443; #else double itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769; double itmValueFdm = 42.2091, atmValueFdm = 12.8864, otmValueFdm = 2.4437; #endif double tolerance = 1.0e-4; Swaption swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - itmValue) > tolerance) { QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); } swaption.setPricingEngine(fdmEngine); if (Math.Abs(swaption.NPV() - itmValueFdm) > tolerance) { QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValueFdm); } swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - atmValue) > tolerance) { QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); } swaption.setPricingEngine(fdmEngine); if (Math.Abs(swaption.NPV() - atmValueFdm) > tolerance) { QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValueFdm); } swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - otmValue) > tolerance) { QAssert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); } swaption.setPricingEngine(fdmEngine); if (Math.Abs(swaption.NPV() - otmValueFdm) > tolerance) { QAssert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValueFdm); } for (int j = 0; j < exerciseDates.Count; j++) { exerciseDates[j] = vars.calendar.adjust(exerciseDates[j] - 10); } exercise = new BermudanExercise(exerciseDates); #if QL_USE_INDEXED_COUPON itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388; #else itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399; #endif swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - itmValue) > tolerance) { QAssert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); } swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - atmValue) > tolerance) { QAssert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); } swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(treeEngine); if (Math.Abs(swaption.NPV() - otmValue) > tolerance) { QAssert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); } }
public void testCachedValues() { //("Testing Bermudan swaption against cached values..."); CommonVars vars = new CommonVars(); vars.today = new Date(15, Month.February, 2002); Settings.setEvaluationDate(vars.today); vars.settlement = new Date(19, Month.February, 2002); // flat yield term structure impling 1x5 swap at 5% vars.termStructure.linkTo(Utilities.flatRate(vars.settlement, 0.04875825, new Actual365Fixed())); double atmRate = vars.makeSwap(0.0).fairRate(); VanillaSwap itmSwap = vars.makeSwap(0.8*atmRate); VanillaSwap atmSwap = vars.makeSwap(atmRate); VanillaSwap otmSwap = vars.makeSwap(1.2*atmRate); double a = 0.048696, sigma = 0.0058904; ShortRateModel model=new HullWhite(vars.termStructure,a, sigma); List<Date> exerciseDates= new List<Date>(); List<CashFlow> leg = atmSwap.fixedLeg(); for (int i=0; i<leg.Count; i++) { Coupon coupon = (Coupon)(leg[i]); exerciseDates.Add(coupon.accrualStartDate()); } Exercise exercise = new BermudanExercise(exerciseDates); IPricingEngine engine = new TreeSwaptionEngine(model, 50); #if QL_USE_INDEXED_COUPON Real itmValue = 42.2413, atmValue = 12.8789, otmValue = 2.4759; #else double itmValue = 42.2470, atmValue = 12.8826, otmValue = 2.4769; #endif double tolerance = 1.0e-4; Swaption swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-itmValue) > tolerance) Assert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-atmValue) > tolerance) Assert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-otmValue) > tolerance) Assert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); for (int j=0; j<exerciseDates.Count; j++) exerciseDates[j] = vars.calendar.adjust(exerciseDates[j]-10); exercise = new BermudanExercise(exerciseDates); #if QL_USE_INDEXED_COUPON itmValue = 42.1917; atmValue = 12.7788; otmValue = 2.4388; #else itmValue = 42.1974; atmValue = 12.7825; otmValue = 2.4399; #endif swaption = new Swaption(itmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-itmValue) > tolerance) Assert.Fail("failed to reproduce cached in-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + itmValue); swaption = new Swaption(atmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-atmValue) > tolerance) Assert.Fail("failed to reproduce cached at-the-money swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + atmValue); swaption = new Swaption(otmSwap, exercise); swaption.setPricingEngine(engine); if (Math.Abs(swaption.NPV()-otmValue) > tolerance) Assert.Fail("failed to reproduce cached out-of-the-money " + "swaption value:\n" + "calculated: " + swaption.NPV() + "\n" + "expected: " + otmValue); }
public void testFairSpread() { // Testing Eonia-swap calculation of fair floating spread... CommonVars vars = new CommonVars(); Period[] lengths = { new Period(1,TimeUnit.Years), new Period(2,TimeUnit.Years), new Period(5,TimeUnit.Years), new Period(10,TimeUnit.Years), new Period(20,TimeUnit.Years) }; double[] rates = { 0.04, 0.05, 0.06, 0.07 }; for (int i=0; i<lengths.Length; i++) { for (int j=0; j<rates.Length; j++) { OvernightIndexedSwap swap = vars.makeSwap(lengths[i], rates[j], 0.0); double? fairSpread = swap.fairSpread(); swap = vars.makeSwap(lengths[i], rates[j], fairSpread.Value); if (Math.Abs(swap.NPV()) > 1.0e-10) { Assert.Fail("Recalculating with implied spread:" + "\n length: " + lengths[i] + "\n fixed rate: " + rates[j] + "\nfair spread: " + fairSpread + "\n swap value: " + swap.NPV()); } } } }
public void testFairRate() { // Testing Eonia-swap calculation of fair fixed rate... CommonVars vars = new CommonVars(); Period[] lengths = new Period[] { new Period(1, TimeUnit.Years), new Period(2, TimeUnit.Years), new Period(5, TimeUnit.Years), new Period(10, TimeUnit.Years), new Period(20, TimeUnit.Years) }; double[] spreads = { -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++) { OvernightIndexedSwap swap = vars.makeSwap(lengths[i], 0.0, spreads[j]); swap = vars.makeSwap(lengths[i], swap.fairRate().Value, spreads[j]); if (Math.Abs(swap.NPV()) > 1.0e-10) { Assert.Fail("recalculating with implied rate:\n" + " length: " + lengths[i] + " \n" + " floating spread: " + (spreads[j]) + "\n" + " swap value: " + swap.NPV()); } } } }
public void testCachedValue() { // Testing Eonia-swap calculation against cached value... CommonVars vars = new CommonVars(); Settings.setEvaluationDate(vars.today); vars.settlement = vars.calendar.advance(vars.today,vars.settlementDays,TimeUnit.Days); double flat = 0.05; vars.eoniaTermStructure.linkTo(Utilities.flatRate(vars.settlement,flat,new Actual360())); double fixedRate = Math.Exp(flat) - 1; OvernightIndexedSwap swap = vars.makeSwap(new Period(1,TimeUnit.Years), fixedRate, 0.0); double cachedNPV = 0.001730450147; double tolerance = 1.0e-11; if (Math.Abs(swap.NPV()-cachedNPV) > tolerance) Assert.Fail("\nfailed to reproduce cached swap value:" + "\ncalculated: " + swap.NPV() + "\n expected: " + cachedNPV + "\n tolerance:" + tolerance); }
public void testBootstrap() { // Testing Eonia-swap curve building... CommonVars vars = new CommonVars(); List<RateHelper> eoniaHelpers = new List<RateHelper>(); List<RateHelper> swap3mHelpers = new List<RateHelper>(); IborIndex euribor3m = new Euribor3M(); Eonia eonia = new Eonia(); for (int i = 0; i < depositData.Length; i++) { double rate = 0.01 * depositData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle<Quote> quote = new Handle<Quote>(simple); Period term = new Period(depositData[i].n , depositData[i].unit); RateHelper helper = new DepositRateHelper(quote, term, depositData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); if (term <= new Period(2,TimeUnit.Days)) eoniaHelpers.Add(helper); if (term <= new Period(3,TimeUnit.Months)) swap3mHelpers.Add(helper); } for (int i = 0; i < fraData.Length; i++) { double rate = 0.01 * fraData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle<Quote> quote = new Handle<Quote>(simple); RateHelper helper = new FraRateHelper(quote, fraData[i].nExpiry, fraData[i].nMaturity, fraData[i].settlementDays, euribor3m.fixingCalendar(), euribor3m.businessDayConvention(), euribor3m.endOfMonth(), euribor3m.dayCounter()); swap3mHelpers.Add(helper); } for (int i = 0; i < eoniaSwapData.Length; i++) { double rate = 0.01 * eoniaSwapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle<Quote> quote = new Handle<Quote>(simple); Period term = new Period(eoniaSwapData[i].n , eoniaSwapData[i].unit); RateHelper helper = new OISRateHelper(eoniaSwapData[i].settlementDays, term, quote, eonia); eoniaHelpers.Add(helper); } for (int i = 0; i < swapData.Length; i++) { double rate = 0.01 * swapData[i].rate; SimpleQuote simple = new SimpleQuote(rate); Handle<Quote> quote = new Handle<Quote>(simple); Period tenor = new Period(swapData[i].nIndexUnits , swapData[i].indexUnit); Period term = new Period(swapData[i].nTermUnits , swapData[i].termUnit); RateHelper helper = new SwapRateHelper(quote, term, vars.calendar, vars.fixedSwapFrequency, vars.fixedSwapConvention, vars.fixedSwapDayCount, euribor3m); if (tenor == new Period(3,TimeUnit.Months)) swap3mHelpers.Add(helper); } PiecewiseYieldCurve<Discount, LogLinear> eoniaTS = new PiecewiseYieldCurve<Discount, LogLinear>(vars.today, eoniaHelpers, new Actual365Fixed()); PiecewiseYieldCurve<Discount, LogLinear> swapTS = new PiecewiseYieldCurve<Discount, LogLinear>(vars.today, swap3mHelpers, new Actual365Fixed()); vars.eoniaTermStructure.linkTo(eoniaTS); // test curve consistency double tolerance = 1.0e-10; for (int i = 0; i < eoniaSwapData.Length; i++) { double expected = eoniaSwapData[i].rate; Period term = new Period(eoniaSwapData[i].n , eoniaSwapData[i].unit); OvernightIndexedSwap swap = vars.makeSwap(term, 0.0, 0.0); double? calculated = 100.0 * swap.fairRate(); if (Math.Abs(expected-calculated.Value) > tolerance) Assert.Fail("curve inconsistency:\n" + " swap length: " + term + "\n" + " quoted rate: " + expected + "\n" + " calculated rate: " + calculated); } }
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 testSpreadDependency() { //("Testing vanilla-swap dependency on floating spread..."); CommonVars vars = new CommonVars(); int[] lengths = new int[] { 1, 2, 5, 10, 20 }; double[] spreads = new double[] { -0.01, -0.002, -0.001, 0.0, 0.001, 0.002, 0.01 }; double[] rates = new double[] { 0.04, 0.05, 0.06, 0.07 }; for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < rates.Length; j++) { // store the results for different rates... List<double> swap_values = new List<double>(); for (int k = 0; k < spreads.Length; k++) { VanillaSwap swap = vars.makeSwap(lengths[i], rates[j], spreads[k]); swap_values.Add(swap.NPV()); } // and check that they go the right way for (int z = 0; z < swap_values.Count - 1; z++) { if (swap_values[z] > swap_values[z + 1]) Assert.Fail( "NPV is decreasing with the floating spread in a swap: \n" + " length: " + lengths[i] + " years\n" + " value: " + swap_values[z] + " receiving spread: " + rates[z] + "\n" + " value: " + swap_values[z + 1] + " receiving spread: " + rates[z + 1]); } } } }
public void testFairSpread() { //("Testing vanilla-swap calculation of fair floating spread..."); CommonVars vars = new CommonVars(); int[] lengths = new int[] { 1, 2, 5, 10, 20 }; double[] rates = new double[] { 0.04, 0.05, 0.06, 0.07 }; for (int i = 0; i < lengths.Length; i++) { for (int j = 0; j < rates.Length; j++) { VanillaSwap swap = vars.makeSwap(lengths[i], rates[j], 0.0); swap = vars.makeSwap(lengths[i], rates[j], swap.fairSpread()); if (Math.Abs(swap.NPV()) > 1.0e-10) { Assert.Fail("recalculating with implied spread:\n" + " length: " + lengths[i] + " years\n" + " fixed rate: " + rates[j] + "\n" + " swap value: " + swap.NPV()); } } } }