/// <summary> /// Test the adjoint algorithmic differentiation version of alpha. /// </summary> public virtual void alphaDSigma() { double expiry1 = 0.25; double expiry2 = 2.25; double numeraire = 10.0; double maturity = 9.0; int nbVolatility = VOLATILITY.size(); ValueDerivatives alphaDeriv = MODEL.alphaAdjoint(MODEL_PARAMETERS, expiry1, expiry2, numeraire, maturity); double alpha = alphaDeriv.Value; double[] alphaDerivatives = alphaDeriv.Derivatives.toArray(); double alpha2 = MODEL.alpha(MODEL_PARAMETERS, expiry1, expiry2, numeraire, maturity); assertEquals(alpha2, alpha, 1.0E-10); double shiftVol = 1.0E-6; double[] volatilityBumped = new double[nbVolatility]; Array.Copy(VOLATILITY.toArray(), 0, volatilityBumped, 0, nbVolatility); double[] alphaBumpedPlus = new double[nbVolatility]; double[] alphaBumpedMinus = new double[nbVolatility]; HullWhiteOneFactorPiecewiseConstantParameters parametersBumped; for (int loopvol = 0; loopvol < nbVolatility; loopvol++) { volatilityBumped[loopvol] += shiftVol; parametersBumped = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION, DoubleArray.copyOf(volatilityBumped), VOLATILITY_TIME); alphaBumpedPlus[loopvol] = MODEL.alpha(parametersBumped, expiry1, expiry2, numeraire, maturity); volatilityBumped[loopvol] -= 2 * shiftVol; parametersBumped = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION, DoubleArray.copyOf(volatilityBumped), VOLATILITY_TIME); alphaBumpedMinus[loopvol] = MODEL.alpha(parametersBumped, expiry1, expiry2, numeraire, maturity); assertEquals((alphaBumpedPlus[loopvol] - alphaBumpedMinus[loopvol]) / (2 * shiftVol), alphaDerivatives[loopvol], 1.0E-9); volatilityBumped[loopvol] = VOLATILITY.get(loopvol); } }
/// <summary> /// Test the payment delay convexity adjustment factor. /// </summary> public virtual void paymentDelayConvexityFactor() { double startExpiryTime = 1.00; double endExpiryTime = 3.00; double startFixingPeriod = 3.05; double endFixingPeriod = 3.55; double paymentTime = 3.45; double hwMeanReversion = 0.011; // Constant volatility double hwEta = 0.02; HullWhiteOneFactorPiecewiseConstantParameters parameters = HullWhiteOneFactorPiecewiseConstantParameters.of(hwMeanReversion, DoubleArray.of(hwEta), DoubleArray.of()); double factor1 = (Math.Exp(-hwMeanReversion * endFixingPeriod) - Math.Exp(-hwMeanReversion * paymentTime)) * (Math.Exp(-hwMeanReversion * endFixingPeriod) - Math.Exp(-hwMeanReversion * startFixingPeriod)); double num = 2 * Math.Pow(hwMeanReversion, 3); double factor2 = hwEta * hwEta * (Math.Exp(2 * hwMeanReversion * endExpiryTime) - Math.Exp(2 * hwMeanReversion * startExpiryTime)); double factorExpected = Math.Exp(factor1 * factor2 / num); double factorComputed = MODEL.paymentDelayConvexityFactor(parameters, startExpiryTime, endExpiryTime, startFixingPeriod, endFixingPeriod, paymentTime); assertEquals(factorExpected, factorComputed, TOLERANCE_RATE); // Piecewise constant constant volatility double[] hwEtaP = new double[] { 0.02, 0.021, 0.022, 0.023 }; double[] hwTime = new double[] { 0.5, 1.0, 2.0 }; HullWhiteOneFactorPiecewiseConstantParameters parametersP = HullWhiteOneFactorPiecewiseConstantParameters.of(hwMeanReversion, DoubleArray.copyOf(hwEtaP), DoubleArray.copyOf(hwTime)); double factorP2 = hwEtaP[2] * hwEtaP[2] * (Math.Exp(2 * hwMeanReversion * hwTime[2]) - Math.Exp(2 * hwMeanReversion * startExpiryTime)); factorP2 += hwEtaP[3] * hwEtaP[3] * (Math.Exp(2 * hwMeanReversion * endExpiryTime) - Math.Exp(2 * hwMeanReversion * hwTime[2])); double factorPExpected = Math.Exp(factor1 * factorP2 / num); double factorPComputed = MODEL.paymentDelayConvexityFactor(parametersP, startExpiryTime, endExpiryTime, startFixingPeriod, endFixingPeriod, paymentTime); assertEquals(factorPExpected, factorPComputed, TOLERANCE_RATE); }
/// <summary> /// Test the future convexity adjustment factor v a hard-coded value. /// </summary> public virtual void futureConvexityFactor() { LocalDate SPOT_DATE = LocalDate.of(2012, 9, 19); LocalDate LAST_TRADING_DATE = EURIBOR3M.calculateFixingFromEffective(SPOT_DATE, REF_DATA); LocalDate REFERENCE_DATE = LocalDate.of(2010, 8, 18); double tradeLastTime = DayCounts.ACT_ACT_ISDA.relativeYearFraction(REFERENCE_DATE, LAST_TRADING_DATE); double fixStartTime = DayCounts.ACT_ACT_ISDA.relativeYearFraction(REFERENCE_DATE, SPOT_DATE); double fixEndTime = DayCounts.ACT_ACT_ISDA.relativeYearFraction(REFERENCE_DATE, EURIBOR3M.calculateMaturityFromEffective(SPOT_DATE, REF_DATA)); double factor = MODEL.futuresConvexityFactor(MODEL_PARAMETERS, tradeLastTime, fixStartTime, fixEndTime); double expectedFactor = 1.000079130767980; assertEquals(expectedFactor, factor, TOLERANCE_RATE); // Derivative with respect to volatility parameters int nbSigma = MODEL_PARAMETERS.Volatility.size(); ValueDerivatives factorDeriv = MODEL.futuresConvexityFactorAdjoint(MODEL_PARAMETERS, tradeLastTime, fixStartTime, fixEndTime); double factor2 = factorDeriv.Value; double[] sigmaBar = factorDeriv.Derivatives.toArray(); assertEquals(factor, factor2, TOLERANCE_RATE); double[] sigmaBarExpected = new double[nbSigma]; double shift = 1E-6; for (int loops = 0; loops < nbSigma; loops++) { double[] volBumped = VOLATILITY.toArray(); volBumped[loops] += shift; HullWhiteOneFactorPiecewiseConstantParameters parametersBumped = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION, DoubleArray.copyOf(volBumped), VOLATILITY_TIME); double factorPlus = MODEL.futuresConvexityFactor(parametersBumped, tradeLastTime, fixStartTime, fixEndTime); volBumped[loops] -= 2 * shift; parametersBumped = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION, DoubleArray.copyOf(volBumped), VOLATILITY_TIME); double factorMinus = MODEL.futuresConvexityFactor(parametersBumped, tradeLastTime, fixStartTime, fixEndTime); sigmaBarExpected[loops] = (factorPlus - factorMinus) / (2 * shift); assertEquals(sigmaBarExpected[loops], sigmaBar[loops], TOLERANCE_RATE); } }
//------------------------------------------------------------------------- public virtual void test_presentValueSensitivityHullWhiteParameter() { DoubleArray computedRec = PRICER.presentValueSensitivityModelParamsHullWhite(SWAPTION_REC_LONG, RATE_PROVIDER, HW_PROVIDER); DoubleArray computedPay = PRICER.presentValueSensitivityModelParamsHullWhite(SWAPTION_PAY_SHORT, RATE_PROVIDER, HW_PROVIDER); DoubleArray vols = HW_PROVIDER.Parameters.Volatility; int size = vols.size(); double[] expectedRec = new double[size]; double[] expectedPay = new double[size]; for (int i = 0; i < size; ++i) { double[] volsUp = vols.toArray(); double[] volsDw = vols.toArray(); volsUp[i] += FD_TOL; volsDw[i] -= FD_TOL; HullWhiteOneFactorPiecewiseConstantParameters paramsUp = HullWhiteOneFactorPiecewiseConstantParameters.of(HW_PROVIDER.Parameters.MeanReversion, DoubleArray.copyOf(volsUp), HW_PROVIDER.Parameters.VolatilityTime.subArray(1, size)); HullWhiteOneFactorPiecewiseConstantParameters paramsDw = HullWhiteOneFactorPiecewiseConstantParameters.of(HW_PROVIDER.Parameters.MeanReversion, DoubleArray.copyOf(volsDw), HW_PROVIDER.Parameters.VolatilityTime.subArray(1, size)); HullWhiteOneFactorPiecewiseConstantParametersProvider provUp = HullWhiteOneFactorPiecewiseConstantParametersProvider.of(paramsUp, HW_PROVIDER.DayCount, HW_PROVIDER.ValuationDateTime); HullWhiteOneFactorPiecewiseConstantParametersProvider provDw = HullWhiteOneFactorPiecewiseConstantParametersProvider.of(paramsDw, HW_PROVIDER.DayCount, HW_PROVIDER.ValuationDateTime); expectedRec[i] = 0.5 * (PRICER.presentValue(SWAPTION_REC_LONG, RATE_PROVIDER, provUp).Amount - PRICER.presentValue(SWAPTION_REC_LONG, RATE_PROVIDER, provDw).Amount) / FD_TOL; expectedPay[i] = 0.5 * (PRICER.presentValue(SWAPTION_PAY_SHORT, RATE_PROVIDER, provUp).Amount - PRICER.presentValue(SWAPTION_PAY_SHORT, RATE_PROVIDER, provDw).Amount) / FD_TOL; } assertTrue(DoubleArrayMath.fuzzyEquals(computedRec.toArray(), expectedRec, NOTIONAL * FD_TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(computedPay.toArray(), expectedPay, NOTIONAL * FD_TOL)); }
/// <summary> /// Tests the equal and hash code methods. /// </summary> public virtual void equalHash() { HullWhiteOneFactorPiecewiseConstantParameters newParameter = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION, VOLATILITY, VOLATILITY_TIME); assertTrue(MODEL_PARAMETERS.Equals(newParameter)); assertTrue(MODEL_PARAMETERS.GetHashCode() == newParameter.GetHashCode()); HullWhiteOneFactorPiecewiseConstantParameters modifiedParameter = HullWhiteOneFactorPiecewiseConstantParameters.of(MEAN_REVERSION + 0.01, VOLATILITY, VOLATILITY_TIME); assertFalse(MODEL_PARAMETERS.Equals(modifiedParameter)); }
/// <summary> /// Test the payment delay convexity adjustment factor. Analysis of the size. /// In normal test, should have (enabled=false) /// </summary> //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test(enabled = false) public void paymentDelayConvexityFactorAnalysis() public virtual void paymentDelayConvexityFactorAnalysis() { double hwMeanReversion = 0.01; double rate = 0.02; double[] tenorTime = new double[] { 0.25, 0.50 }; int nbTenors = tenorTime.Length; double[] lagPayTime = new double[] { 1.0d / 365.0d, 2.0d / 365.0d, 7.0d / 365.0d }; int nbLags = lagPayTime.Length; double lagFixTime = 2.0d / 365.0d; int nbPeriods = 120; double startTimeFirst = 0.25; double startTimeStep = 0.25; double[] startTime = new double[nbPeriods]; for (int loopp = 0; loopp < nbPeriods; loopp++) { startTime[loopp] = startTimeFirst + loopp * startTimeStep; } // Constant volatility double hwEta = 0.02; HullWhiteOneFactorPiecewiseConstantParameters parameters = HullWhiteOneFactorPiecewiseConstantParameters.of(hwMeanReversion, DoubleArray.of(hwEta), DoubleArray.of(0)); //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][][] factor = new double[nbTenors][nbLags][nbPeriods]; double[][][] factor = RectangularArrays.ReturnRectangularDoubleArray(nbTenors, nbLags, nbPeriods); //JAVA TO C# CONVERTER NOTE: The following call to the 'RectangularArrays' helper class reproduces the rectangular array initialization that is automatic in Java: //ORIGINAL LINE: double[][][] adj = new double[nbTenors][nbLags][nbPeriods]; double[][][] adj = RectangularArrays.ReturnRectangularDoubleArray(nbTenors, nbLags, nbPeriods); for (int loopt = 0; loopt < nbTenors; loopt++) { for (int loopl = 0; loopl < nbLags; loopl++) { for (int loopp = 0; loopp < nbPeriods; loopp++) { factor[loopt][loopl][loopp] = MODEL.paymentDelayConvexityFactor(parameters, 0, startTime[loopp] - lagFixTime, startTime[loopp], startTime[loopp] + tenorTime[loopt], startTime[loopp] + tenorTime[loopt] - lagPayTime[loopl]); adj[loopt][loopl][loopp] = (1.0d / tenorTime[loopt] - rate) * (factor[loopt][loopl][loopp] - 1); } } } //JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @SuppressWarnings("unused") int t = 0; int t = 0; t++; }