public void testConsistency() { //("Testing dates..."); int minDate = Date.minDate().serialNumber() + 1, maxDate = Date.maxDate().serialNumber(); int dyold = new Date(minDate - 1).DayOfYear, dold = new Date(minDate - 1).Day, mold = new Date(minDate - 1).Month, yold = new Date(minDate - 1).Year, wdold = new Date(minDate - 1).weekday(); for (int i = minDate; i <= maxDate; i++) { Date t = new Date(i); int serial = t.serialNumber(); // check serial number consistency if (serial != i) Assert.Fail("inconsistent serial number:\n" + " original: " + i + "\n" + " date: " + t + "\n" + " serial number: " + serial); int dy = t.DayOfYear, d = t.Day, m = t.Month, y = t.Year, wd = t.weekday(); // check if skipping any date if (!((dy == dyold + 1) || (dy == 1 && dyold == 365 && !Date.IsLeapYear(yold)) || (dy == 1 && dyold == 366 && Date.IsLeapYear(yold)))) Assert.Fail("wrong day of year increment: \n" + " date: " + t + "\n" + " day of year: " + dy + "\n" + " previous: " + dyold); dyold = dy; if (!((d == dold + 1 && m == mold && y == yold) || (d == 1 && m == mold + 1 && y == yold) || (d == 1 && m == 1 && y == yold + 1))) Assert.Fail("wrong day,month,year increment: \n" + " date: " + t + "\n" + " day,month,year: " + d + "," + m + "," + y + "\n" + " previous: " + dold + "," + mold + "," + yold); dold = d; mold = m; yold = y; // check month definition if (m < 1 || m > 12) Assert.Fail("invalid month: \n" + " date: " + t + "\n" + " month: " + m); // check day definition if (d < 1) Assert.Fail("invalid day of month: \n" + " date: " + t + "\n" + " day: " + d); if (!((m == 1 && d <= 31) || (m == 2 && d <= 28) || (m == 2 && d == 29 && Date.IsLeapYear(y)) || (m == 3 && d <= 31) || (m == 4 && d <= 30) || (m == 5 && d <= 31) || (m == 6 && d <= 30) || (m == 7 && d <= 31) || (m == 8 && d <= 31) || (m == 9 && d <= 30) || (m == 10 && d <= 31) || (m == 11 && d <= 30) || (m == 12 && d <= 31))) Assert.Fail("invalid day of month: \n" + " date: " + t + "\n" + " day: " + d); // check weekday definition if (!((wd == wdold + 1) || (wd == 1 && wdold == 7))) Assert.Fail("invalid weekday: \n" + " date: " + t + "\n" + " weekday: " + wd + "\n" + " previous: " + wdold); wdold = wd; // create the same date with a different constructor Date s = new Date(d, m, y); // check serial number consistency serial = s.serialNumber(); if (serial != i) Assert.Fail("inconsistent serial number:\n" + " date: " + t + "\n" + " serial number: " + i + "\n" + " cloned date: " + s + "\n" + " serial number: " + serial); } }
public override void calculate() { /* both DTS, YTS ref dates and pricing date consistency * checks? settlement... */ Utils.QL_REQUIRE(!discountCurve_.empty(), () => "no discount term structure set"); Utils.QL_REQUIRE(!defaultTS_.empty(), () => "no ctpty default term structure set"); Utils.QL_REQUIRE(!swaptionletEngine_.empty(), () => "no swap option engine set"); Date priceDate = defaultTS_.link.referenceDate(); double cumOptVal = 0.0, cumPutVal = 0.0; // Vanilla swap so 0 leg is floater int index = 0; Date nextFD = arguments_.fixedPayDates[index]; Date swapletStart = priceDate; while (nextFD < priceDate) { index++; nextFD = arguments_.fixedPayDates[index]; } // Compute fair spread for strike value: // copy args into the non risky engine Swap.Arguments noCVAArgs = baseSwapEngine_.link.getArguments() as Swap.Arguments; noCVAArgs.legs = this.arguments_.legs; noCVAArgs.payer = this.arguments_.payer; baseSwapEngine_.link.calculate(); double baseSwapRate = ((FixedRateCoupon)arguments_.legs[0][0]).rate(); Swap.Results vSResults = baseSwapEngine_.link.getResults() as Swap.Results; double?baseSwapFairRate = -baseSwapRate * vSResults.legNPV[1] / vSResults.legNPV[0]; double?baseSwapNPV = vSResults.value; VanillaSwap.Type reversedType = arguments_.type == VanillaSwap.Type.Payer ? VanillaSwap.Type.Receiver : VanillaSwap.Type.Payer; // Swaplet options summatory: while (nextFD != arguments_.fixedPayDates.Last()) { // iFD coupon not fixed, create swaptionlet: IborIndex swapIndex = ((FloatingRateCoupon)arguments_.legs[1][0]).index() as IborIndex; // Alternatively one could cap this period to, say, 1M Period baseSwapsTenor = new Period(arguments_.fixedPayDates.Last().serialNumber() - swapletStart.serialNumber(), TimeUnit.Days); VanillaSwap swaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate) .withType(arguments_.type) .withNominal(arguments_.nominal) .withEffectiveDate(swapletStart) .withTerminationDate(arguments_.fixedPayDates.Last()).value(); VanillaSwap revSwaplet = new MakeVanillaSwap(baseSwapsTenor, swapIndex, baseSwapFairRate) .withType(reversedType) .withNominal(arguments_.nominal) .withEffectiveDate(swapletStart) .withTerminationDate(arguments_.fixedPayDates.Last()).value(); Swaption swaptionlet = new Swaption(swaplet, new EuropeanExercise(swapletStart)); Swaption putSwaplet = new Swaption(revSwaplet, new EuropeanExercise(swapletStart)); swaptionlet.setPricingEngine(swaptionletEngine_.currentLink()); putSwaplet.setPricingEngine(swaptionletEngine_.currentLink()); // atm underlying swap means that the value of put = value // call so this double pricing is not needed cumOptVal += swaptionlet.NPV() * defaultTS_.link.defaultProbability( swapletStart, nextFD); cumPutVal += putSwaplet.NPV() * invstDTS_.link.defaultProbability(swapletStart, nextFD); swapletStart = nextFD; index++; nextFD = arguments_.fixedPayDates[index]; } results_.value = baseSwapNPV - (1.0 - ctptyRecoveryRate_) * cumOptVal + (1.0 - invstRecoveryRate_) * cumPutVal; results_.fairRate = -baseSwapRate * (vSResults.legNPV[1] - (1.0 - ctptyRecoveryRate_) * cumOptVal + (1.0 - invstRecoveryRate_) * cumPutVal) / vSResults.legNPV[0]; }