public virtual void parSpreadSensitivity() { // March PointSensitivities pointMar = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_MAR, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT); CurrencyParameterSensitivities sensiMar = LED_PROVIDER.parameterSensitivity(pointMar); double[] sensiIssuerMar = new double[] { -4.795692708445902E-6, -2.0781215861310126E-5, -7.730767169573405E-5, -1.6071777740512183E-4, -2.3044416935116369E-4, -3.333307694739688E-4, -4.263036155523118E-4, -5.685365085703306E-4, -0.10407934097674876, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoMar = new double[] { 0.0, 0.0, 0.0, 0.0, 0.001370140084809201, 3.3554451056551886E-4, 0.0, 0.0 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerMar, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoMar, TOL)); // June PointSensitivities pointJun = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_JUN, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT); CurrencyParameterSensitivities sensiJun = LED_PROVIDER.parameterSensitivity(pointJun); double[] sensiIssuerJun = new double[] { -1.1453989553600325E-5, -2.348926498286566E-5, -1.0106640809190963E-4, -1.9509367993719023E-4, -3.132622179286758E-4, -4.395002117284386E-4, -5.572262990208806E-4, -7.858225833901946E-4, -0.07087170775675304, -0.03539736978075175, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoJun = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.003012223890022257, 0.0024215917547237764, 0.0 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerJun, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoJun, TOL)); // September PointSensitivities pointSep = TRADE_PRICER.parSpreadSensitivity(FUTURE_TRADE_SEP, LED_PROVIDER).multipliedBy(HUNDRED * ONE_BASIS_POINT); CurrencyParameterSensitivities sensiSep = LED_PROVIDER.parameterSensitivity(pointSep); double[] sensiIssuerSep = new double[] { -6.287268294968501E-6, -2.7244672992830814E-5, -1.0135221390528455E-4, -2.1070486533414349E-4, -3.021178394458564E-4, -4.370046427203812E-4, -5.588942763935072E-4, -7.453650144370277E-4, -0.03687605192905092, -0.07313888023068209, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoSep = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.007209056180693214, 0.0020653493968426154 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerSep, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoSep, TOL)); }
public virtual void regression_hullWhiteSensitivity() { DoubleArray computed = PRICER.presentValueSensitivityModelParamsHullWhite(SWAPTION_PAY_LONG, RATE_PROVIDER, HW_PROVIDER); double[] expected = new double[] { 2.9365484063149095E7, 3.262667329294093E7, 7.226220286364576E7, 2.4446925038968167E8, 120476.73820821749 }; assertTrue(DoubleArrayMath.fuzzyEquals(computed.toArray(), expected, NOTIONAL * TOL)); }
public virtual void swapRateDa() { double shift = 1.0E-8; double x = 0.0; ValueDerivatives computed = MODEL.swapRateDaf1(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, ALPHA_IBOR); double swapRateComputed = computed.Value; double[] dafComputed = computed.Derivatives.toArray(); double swapRateExpected = MODEL.swapRate(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, ALPHA_IBOR); assertEquals(swapRateComputed, swapRateExpected, TOLERANCE_RATE); double[] dafExpected = new double[ALPHA_FIXED.size()]; for (int loopcf = 0; loopcf < ALPHA_FIXED.size(); loopcf++) { double[] afBumped = ALPHA_FIXED.toArray(); afBumped[loopcf] += shift; double swapRatePlus = MODEL.swapRate(x, DCF_FIXED, DoubleArray.copyOf(afBumped), DCF_IBOR, ALPHA_IBOR); afBumped[loopcf] -= 2 * shift; double swapRateMinus = MODEL.swapRate(x, DCF_FIXED, DoubleArray.copyOf(afBumped), DCF_IBOR, ALPHA_IBOR); dafExpected[loopcf] = (swapRatePlus - swapRateMinus) / (2 * shift); } assertTrue(DoubleArrayMath.fuzzyEquals(dafExpected, dafComputed, TOLERANCE_RATE_DELTA)); double[] daiExpected = new double[DCF_IBOR.size()]; for (int loopcf = 0; loopcf < DCF_IBOR.size(); loopcf++) { double[] aiBumped = ALPHA_IBOR.toArray(); aiBumped[loopcf] += shift; double swapRatePlus = MODEL.swapRate(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, DoubleArray.copyOf(aiBumped)); aiBumped[loopcf] -= 2 * shift; double swapRateMinus = MODEL.swapRate(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, DoubleArray.copyOf(aiBumped)); daiExpected[loopcf] = (swapRatePlus - swapRateMinus) / (2 * shift); } double[] daiComputed = MODEL.swapRateDai1(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, ALPHA_IBOR).Derivatives.toArray(); assertTrue(DoubleArrayMath.fuzzyEquals(daiExpected, daiComputed, TOLERANCE_RATE_DELTA)); }
//------------------------------------------------------------------------- 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)); }
public virtual void test_consistency_singleName() { IsdaCreditCurveDefinition curveDefinition = IsdaCreditCurveDefinition.of(CURVE_NAME, EUR, VALUATION_DATE, ACT_365F, CURVE_NODES_PS, true, true); LegalEntitySurvivalProbabilities creditCurveComputed = CALIBRATOR.calibrate(curveDefinition, MARKET_DATA_PS, RATES_PROVIDER, REF_DATA); NodalCurve curveComputed = (NodalCurve)creditCurveComputed.SurvivalProbabilities.findData(CURVE_NAME).get(); double computedIndex = curveComputed.Metadata.getInfo(CurveInfoType.CDS_INDEX_FACTOR); assertEquals(computedIndex, 93.0 / 97.0, TOL); IsdaCompliantCreditCurveCalibrator cdsCalibrator = FastCreditCurveCalibrator.standard(); IList <CdsIsdaCreditCurveNode> cdsNodes = new List <CdsIsdaCreditCurveNode>(); for (int i = 0; i < CURVE_NODES_PS.size(); ++i) { cdsNodes.Add(CdsIsdaCreditCurveNode.ofParSpread(CURVE_NODES_PS.get(i).Template, CURVE_NODES_PS.get(i).ObservableId, CURVE_NODES_PS.get(i).CdsIndexId)); ParameterMetadata metadata = curveComputed.getParameterMetadata(i); assertTrue(metadata is ResolvedTradeParameterMetadata); ResolvedTradeParameterMetadata tradeMetadata = (ResolvedTradeParameterMetadata)metadata; assertTrue(tradeMetadata.Trade is ResolvedCdsIndexTrade); } IsdaCreditCurveDefinition cdsCurveDefinition = IsdaCreditCurveDefinition.of(CURVE_NAME, EUR, VALUATION_DATE, ACT_365F, cdsNodes, true, false); LegalEntitySurvivalProbabilities creditCurveExpected = cdsCalibrator.calibrate(cdsCurveDefinition, MARKET_DATA_PS, RATES_PROVIDER, REF_DATA); NodalCurve curveExpected = (NodalCurve)creditCurveExpected.SurvivalProbabilities.findData(CURVE_NAME).get(); assertTrue(DoubleArrayMath.fuzzyEquals(curveComputed.XValues.toArray(), curveExpected.XValues.toArray(), TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(curveComputed.YValues.toArray(), curveExpected.YValues.toArray(), TOL)); assertEquals(curveComputed.Metadata.getInfo(CurveInfoType.JACOBIAN), curveExpected.Metadata.getInfo(CurveInfoType.JACOBIAN)); }
public virtual void swapRateDx2Da() { double shift = 1.0E-7; double x = 0.0; Pair <DoubleArray, DoubleArray> dx2DaComputed = MODEL.swapRateDx2Da1(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, ALPHA_IBOR); double[] dx2DafExpected = new double[DCF_FIXED.size()]; for (int loopcf = 0; loopcf < DCF_FIXED.size(); loopcf++) { double[] afBumped = ALPHA_FIXED.toArray(); afBumped[loopcf] += shift; double swapRatePlus = MODEL.swapRateDx2(x, DCF_FIXED, DoubleArray.copyOf(afBumped), DCF_IBOR, ALPHA_IBOR); afBumped[loopcf] -= 2 * shift; double swapRateMinus = MODEL.swapRateDx2(x, DCF_FIXED, DoubleArray.copyOf(afBumped), DCF_IBOR, ALPHA_IBOR); dx2DafExpected[loopcf] = (swapRatePlus - swapRateMinus) / (2 * shift); } assertTrue(DoubleArrayMath.fuzzyEquals(dx2DafExpected, dx2DaComputed.First.toArray(), TOLERANCE_RATE_DELTA2)); double[] dx2DaiExpected = new double[DCF_IBOR.size()]; for (int loopcf = 0; loopcf < DCF_IBOR.size(); loopcf++) { double[] aiBumped = ALPHA_IBOR.toArray(); aiBumped[loopcf] += shift; double swapRatePlus = MODEL.swapRateDx2(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, DoubleArray.copyOf(aiBumped)); aiBumped[loopcf] -= 2 * shift; double swapRateMinus = MODEL.swapRateDx2(x, DCF_FIXED, ALPHA_FIXED, DCF_IBOR, DoubleArray.copyOf(aiBumped)); dx2DaiExpected[loopcf] = (swapRatePlus - swapRateMinus) / (2 * shift); } assertTrue(DoubleArrayMath.fuzzyEquals(dx2DaiExpected, dx2DaComputed.Second.toArray(), TOLERANCE_RATE_DELTA2)); }
public virtual void test_volatility_sensitivity() { double eps = 1.0e-6; int nData = TIME.size(); for (int i = 0; i < NB_TEST; i++) { for (int k = 0; k < NB_TEST; k++) { double expiryTime = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); IborCapletFloorletSensitivity point = IborCapletFloorletSensitivity.of(VOLS.Name, expiryTime, TEST_STRIKE[k], TEST_FORWARD, GBP, TEST_SENSITIVITY[i]); double[] sensFd = new double[nData]; for (int j = 0; j < nData; j++) { DoubleArray volDataUp = VOL.subArray(0, nData).with(j, VOL.get(j) + eps); DoubleArray volDataDw = VOL.subArray(0, nData).with(j, VOL.get(j) - eps); InterpolatedNodalSurface paramUp = InterpolatedNodalSurface.of(METADATA, TIME, STRIKE, volDataUp, INTERPOLATOR_2D); InterpolatedNodalSurface paramDw = InterpolatedNodalSurface.of(METADATA, TIME, STRIKE, volDataDw, INTERPOLATOR_2D); ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities provUp = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(GBP_LIBOR_3M, VAL_DATE_TIME, paramUp, CURVE); ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities provDw = ShiftedBlackIborCapletFloorletExpiryStrikeVolatilities.of(GBP_LIBOR_3M, VAL_DATE_TIME, paramDw, CURVE); double volUp = provUp.volatility(TEST_OPTION_EXPIRY[i], TEST_STRIKE[k], TEST_FORWARD); double volDw = provDw.volatility(TEST_OPTION_EXPIRY[i], TEST_STRIKE[k], TEST_FORWARD); double fd = 0.5 * (volUp - volDw) / eps; sensFd[j] = fd * TEST_SENSITIVITY[i]; } CurrencyParameterSensitivity sensActual = VOLS.parameterSensitivity(point).Sensitivities.get(0); double[] computed = sensActual.Sensitivity.toArray(); assertTrue(DoubleArrayMath.fuzzyEquals(computed, sensFd, eps)); } } }
public virtual void test_optionPrice() { double tol = 1.0e-12; EuropeanVanillaOptionFunction test = EuropeanVanillaOptionFunction.of(STRIKE, TIME_TO_EXPIRY, PutCall.PUT, NUM); double spot = 100d; double u = 1.05; double d = 0.98; double m = Math.Sqrt(u * d); double up = 0.29; double dp = 0.25; double mp = 1d - up - dp; // test getPayoffAtExpiryTrinomial DoubleArray computedPayoff = test.getPayoffAtExpiryTrinomial(spot, d, m); int expectedSize = 2 * NUM + 1; assertEquals(computedPayoff.size(), expectedSize); for (int i = 0; i < expectedSize; ++i) { double price = spot * Math.Pow(u, 0.5 * i) * Math.Pow(d, NUM - 0.5 * i); double expectedPayoff = Math.Max(STRIKE - price, 0d); assertEquals(computedPayoff.get(i), expectedPayoff, tol); } // test getNextOptionValues double df = 0.92; int n = 2; DoubleArray values = DoubleArray.of(1.4, 0.9, 0.1, 0.05, 0.0, 0.0, 0.0); DoubleArray computedNextValues = test.getNextOptionValues(df, up, mp, dp, values, spot, d, m, n); DoubleArray expectedNextValues = DoubleArray.of(df * (1.4 * dp + 0.9 * mp + 0.1 * up), df * (0.9 * dp + 0.1 * mp + 0.05 * up), df * (0.1 * dp + 0.05 * mp), df * 0.05 * dp, 0.0); assertTrue(DoubleArrayMath.fuzzyEquals(computedNextValues.toArray(), expectedNextValues.toArray(), tol)); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Test public void tes_differentiateNoCrosst() public virtual void tes_differentiateNoCrosst() { System.Func <DoubleArray, DoubleArray> func = (DoubleArray x) => { double x1 = x.get(0); double x2 = x.get(1); return(DoubleArray.of(x1 * x1 * x1 + x2 * x2, Math.Exp(1.5 * x1), Math.Log(2d * x1) * Math.Sin(x2))); }; double[][] keys = new double[][] { new double[] { 1.5, -2.1 }, new double[] { 2.3445, 0.5 } }; System.Func <DoubleArray, DoubleMatrix> funcExp = (DoubleArray x) => { double x1 = x.get(0); double x2 = x.get(1); double[][] mat = new double[][] { new double[] { 6d * x1, 2.25 * Math.Exp(1.5 * x1), -Math.Sin(x2) / x1 / x1 }, new double[] { 2d, 0d, -Math.Log(2d * x1) * Math.Sin(x2) } }; return(DoubleMatrix.ofUnsafe(mat)); }; VectorFieldSecondOrderDifferentiator fd = new VectorFieldSecondOrderDifferentiator(); System.Func <DoubleArray, DoubleMatrix> fdFuncs = fd.differentiateNoCross(func); foreach (double[] key in keys) { DoubleMatrix cmp = fdFuncs(DoubleArray.ofUnsafe(key)); DoubleMatrix exp = funcExp(DoubleArray.ofUnsafe(key)); assertTrue(DoubleArrayMath.fuzzyEquals(cmp.column(0).toArray(), exp.row(0).toArray(), 1.0e-5)); assertTrue(DoubleArrayMath.fuzzyEquals(cmp.column(1).toArray(), exp.row(1).toArray(), 1.0e-5)); } }
public virtual void presentValueSensitivity() { // March PointSensitivities pointMar = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_MAR, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT); CurrencyParameterSensitivities sensiMar = LED_PROVIDER.parameterSensitivity(pointMar); double[] sensiIssuerMar = new double[] { -4.795692708445902, -20.78121586131013, -77.30767169573404, -160.71777740512184, -230.44416935116368, -333.3307694739688, -426.3036155523117, -568.5365085703306, -104079.34097674876, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoMar = new double[] { 0.0, 0.0, 0.0, 0.0, 1370.1400848092012, 335.54451056551886, 0.0, 0.0 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerMar, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiMar.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoMar, TOL)); // June PointSensitivities pointJun = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_JUN, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT); CurrencyParameterSensitivities sensiJun = LED_PROVIDER.parameterSensitivity(pointJun); double[] sensiIssuerJun = new double[] { -11.453989553600326, -23.489264982865656, -101.06640809190962, -195.09367993719025, -313.2622179286758, -439.5002117284386, -557.2262990208807, -785.8225833901945, -70871.70775675304, -35397.369780751746, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoJun = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 3012.223890022257, 2421.5917547237764, 0.0 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerJun, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiJun.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoJun, TOL)); // September PointSensitivities pointSep = TRADE_PRICER.presentValueSensitivity(FUTURE_TRADE_SEP, LED_PROVIDER).multipliedBy(ONE_BASIS_POINT); CurrencyParameterSensitivities sensiSep = LED_PROVIDER.parameterSensitivity(pointSep); double[] sensiIssuerSep = new double[] { -6.287268294968501, -27.244672992830814, -101.35221390528456, -210.7048653341435, -302.1178394458564, -437.0046427203812, -558.8942763935072, -745.3650144370276, -36876.05192905092, -73138.88023068209, -0.0, -0.0, -0.0, -0.0, -0.0, -0.0 }; double[] sensiRepoSep = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 7209.056180693215, 2065.3493968426155 }; assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(ISSUER_CURVE_NAME, JPY).Sensitivity.toArray(), sensiIssuerSep, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(sensiSep.getSensitivity(REPO_CURVE_NAME, JPY).Sensitivity.toArray(), sensiRepoSep, TOL)); }
public virtual void regression_curveSensitivity() { PointSensitivities point = PRICER.presentValueSensitivityRates(SWAPTION_PAY_LONG, RATE_PROVIDER, HW_PROVIDER).build(); CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point); double[] dscExp = new double[] { 0.0, 0.0, 0.0, 0.0, -1.4127023229222856E7, -1.744958350376594E7 }; double[] fwdExp = new double[] { 0.0, 0.0, 0.0, 0.0, -2.0295973516660026E8, 4.12336887967829E8 }; assertTrue(DoubleArrayMath.fuzzyEquals(computed.getSensitivity(HullWhiteIborFutureDataSet.DSC_NAME, EUR).Sensitivity.toArray(), dscExp, NOTIONAL * TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(computed.getSensitivity(HullWhiteIborFutureDataSet.FWD6_NAME, EUR).Sensitivity.toArray(), fwdExp, NOTIONAL * TOL)); }
public virtual void test_formula() { CoxRossRubinsteinLatticeSpecification test = new CoxRossRubinsteinLatticeSpecification(); DoubleArray computed = test.getParametersTrinomial(VOL, RATE, DT); double u = Math.Exp(VOL * Math.Sqrt(2.0 * DT)); double d = Math.Exp(-VOL * Math.Sqrt(2.0 * DT)); double up = Math.Pow((Math.Exp(0.5 * RATE * DT) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))) / (Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))), 2); double dp = Math.Pow((Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(0.5 * RATE * DT)) / (Math.Exp(VOL * Math.Sqrt(0.5 * DT)) - Math.Exp(-VOL * Math.Sqrt(0.5 * DT))), 2); DoubleArray expected = DoubleArray.of(u, 1d, d, up, 1d - up - dp, dp); assertTrue(DoubleArrayMath.fuzzyEquals(computed.toArray(), expected.toArray(), 1.0e-14)); }
public virtual void test_volatilityMaturityPart() { double u = 5.001332435062505; DoubleMatrix v = DoubleMatrix.copyOf(new double[][] { new double[] { 5.012261396811139, 5.515068493150685, 6.010958904109589, 6.515068493150685, 7.010958904109589, 7.515068493150685, 8.01095890410959, 8.520458118122614, 9.017725877685455, 9.515068493150684, 10.013698630136986 } }); DoubleMatrix computed = MODEL.volatilityMaturityPart(MODEL_PARAMETERS, u, v); double[] expected = new double[] { 0.010395243419747402, 0.48742124221025085, 0.9555417903726049, 1.4290478001940943, 1.8925104710768026, 2.361305017379811, 2.8201561576361778, 3.289235677728508, 3.7447552766260217, 4.198083407732067, 4.650327387669373 }; assertTrue(DoubleArrayMath.fuzzyEquals(computed.row(0).toArray(), expected, TOLERANCE_RATE)); }
public virtual void parSpreadTest() { LocalDate valuationDate = LocalDate.of(2013, 2, 27); DoubleArray ycTime = DoubleArray.ofUnsafe(new double[] { 0.09041095890410959, 0.1726027397260274, 0.26301369863013696, 0.5123287671232877, 0.7616438356164383, 1.010958904109589, 2.008219178082192, 3.008219178082192, 4.008219178082192, 5.008219178082192, 6.008219178082192, 7.013698630136987, 8.01095890410959, 9.01095890410959, 10.01095890410959, 12.01917808219178, 15.016438356164384, 20.01917808219178, 25.021917808219175, 30.027397260273972 }); DoubleArray ycRate = DoubleArray.ofUnsafe(new double[] { 0.0020651105531615476, 0.0024506037920717797, 0.0028872269869485313, 0.004599628230463427, 0.006160809466806469, 0.0075703969168129295, 0.003965128877560435, 0.005059104202201957, 0.0069669135253734825, 0.009361825469323602, 0.011916895611422482, 0.014311922779901886, 0.016519187063048578, 0.018512121993907647, 0.020289623737560873, 0.02329885162861984, 0.026399509889410745, 0.029087919732133784, 0.03037740056662963, 0.03110021763406523 }); IsdaCreditDiscountFactors yc = IsdaCreditDiscountFactors.of(EUR, valuationDate, CurveName.of("yc_usd"), ycTime, ycRate, ACT_365F); double[] timeNodeExp = new double[] { 0.5616438356164384, 1.0575342465753426, 2.0575342465753423, 3.0602739726027397, 4.06027397260274, 5.06027397260274, 6.06027397260274, 7.063013698630137, 8.063013698630137, 9.063013698630137, 10.063013698630137 }; double[] rateNodeExp = new double[] { 0.00876054089781935, 0.011037345646850688, 0.015955126945240167, 0.020617953392829177, 0.025787811343896218, 0.030329992053915133, 0.03313419899444371, 0.03528129159875671, 0.03675340516560903, 0.037946169956317416, 0.038951101800190346 }; double[] rateNodeExpMf = new double[] { 0.008754510260229803, 0.011030502992814844, 0.01594817866773906, 0.02060947097554756, 0.025776720596175737, 0.030316032527460755, 0.03311839631615255, 0.03526404051997617, 0.03673513322394772, 0.03792689865945585, 0.03893107891569398 }; ImmutableCreditRatesProvider ratesProvider = ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).discountCurves(ImmutableMap.of(EUR, yc)).recoveryRateCurves(ImmutableMap.of(LEGAL_ENTITY, ConstantRecoveryRates.of(LEGAL_ENTITY, valuationDate, 0.25))).creditCurves(ImmutableMap.of()).build(); LocalDate startDate = LocalDate.of(2012, 12, 20); LocalDate[] pillarDates = new LocalDate[] { LocalDate.of(2013, 9, 20), LocalDate.of(2014, 3, 20), LocalDate.of(2015, 3, 20), LocalDate.of(2016, 3, 20), LocalDate.of(2017, 3, 20), LocalDate.of(2018, 3, 20), LocalDate.of(2019, 3, 20), LocalDate.of(2020, 3, 20), LocalDate.of(2021, 3, 20), LocalDate.of(2022, 3, 20), LocalDate.of(2023, 3, 20) }; int nPillars = pillarDates.Length; ImmutableMarketDataBuilder builderCredit = ImmutableMarketData.builder(valuationDate); IList <CdsIsdaCreditCurveNode> nodes = new List <CdsIsdaCreditCurveNode>(nPillars); double[] quotes = new double[] { 0.006485, 0.008163, 0.011763, 0.015136, 0.018787, 0.021905, 0.023797, 0.025211, 0.02617, 0.026928, 0.027549 }; for (int i = 0; i < nPillars; ++i) { CdsConvention conv = ImmutableCdsConvention.of("conv", EUR, ACT_360, Frequency.P3M, BUS_ADJ, CDS_SETTLE_STD); CdsTemplate temp = DatesCdsTemplate.of(startDate, pillarDates[i], conv); QuoteId id = QuoteId.of(StandardId.of("OG", pillarDates[i].ToString())); nodes.Add(CdsIsdaCreditCurveNode.ofParSpread(temp, id, LEGAL_ENTITY)); builderCredit.addValue(id, quotes[i]); } ImmutableMarketData marketData = builderCredit.build(); IsdaCreditCurveDefinition curveDefinition = IsdaCreditCurveDefinition.of(CurveName.of("zz"), EUR, valuationDate, ACT_365F, nodes, true, true); LegalEntitySurvivalProbabilities cc = BUILDER_ISDA.calibrate(curveDefinition, marketData, ratesProvider, REF_DATA); NodalCurve resCurve = ((IsdaCreditDiscountFactors)cc.SurvivalProbabilities).Curve; for (int i = 0; i < nPillars; ++i) { ParameterMetadata param = resCurve.getParameterMetadata(i); assertTrue(param is ResolvedTradeParameterMetadata); ResolvedTradeParameterMetadata tradeParam = (ResolvedTradeParameterMetadata)param; assertTrue(tradeParam.Trade is ResolvedCdsTrade); } assertTrue(DoubleArrayMath.fuzzyEquals(resCurve.XValues.toArray(), timeNodeExp, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(resCurve.YValues.toArray(), rateNodeExp, TOL)); testJacobian(BUILDER_ISDA, cc, ratesProvider, nodes, quotes, 1d, EPS); LegalEntitySurvivalProbabilities ccMf = BUILDER_MARKIT.calibrate(curveDefinition, marketData, ratesProvider, REF_DATA); NodalCurve resCurveMf = ((IsdaCreditDiscountFactors)ccMf.SurvivalProbabilities).Curve; assertTrue(DoubleArrayMath.fuzzyEquals(resCurveMf.XValues.toArray(), timeNodeExp, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(resCurveMf.YValues.toArray(), rateNodeExpMf, TOL)); testJacobian(BUILDER_MARKIT, ccMf, ratesProvider, nodes, quotes, 1d, EPS); }
public virtual void limitingTest() { BoundCurveInterpolator bci = LINEAR.bind(X_DATA, Y_DATA, DISCOUNT_FACTOR_QUADRATIC_LEFT_ZERO_RATE, PRODUCT_LINEAR); double small = 1.0e-8; assertEquals(bci.interpolate(small), bci.interpolate(10d * small), Y_DATA.get(0) * 10d * small); double derivative = bci.firstDerivative(small); double derivativeExp = (bci.interpolate(small + 0.5 * small) - bci.interpolate(small - 0.5 * small)) / small; assertEquals(derivative, derivativeExp, Y_DATA.get(0) * small); DoubleArray sensi = bci.parameterSensitivity(small); DoubleArray sensiS = bci.parameterSensitivity(small * 5d); assertTrue(DoubleArrayMath.fuzzyEquals(sensi.toArray(), sensiS.toArray(), Y_DATA.get(0) * 10d * small)); }
public virtual void test_formula() { TrigeorgisLatticeSpecification test = new TrigeorgisLatticeSpecification(); DoubleArray computed = test.getParametersTrinomial(VOL, RATE, DT); double dx = VOL * Math.Sqrt(3d * DT); double nu = RATE - 0.5 * VOL * VOL; double u = Math.Exp(dx); double d = Math.Exp(-dx); double up = 0.5 * ((VOL * VOL * DT + nu * nu * DT * DT) / (dx * dx) + nu * DT / dx); double dm = 1d - (VOL * VOL * DT + nu * nu * DT * DT) / (dx * dx); double dp = 0.5 * ((VOL * VOL * DT + nu * nu * DT * DT) / (dx * dx) - nu * DT / dx); DoubleArray expected = DoubleArray.of(u, 1d, d, up, dm, dp); assertTrue(DoubleArrayMath.fuzzyEquals(computed.toArray(), expected.toArray(), 1.0e-14)); }
public virtual void test_regression_single() { double[] expectedTimes = new double[] { 4.852054794520548 }; double[] expectedRates = new double[] { 0.04666754810728295 }; ImmutableList <CdsIndexIsdaCreditCurveNode> singleNode = CURVE_NODES.subList(1, 2); IsdaCreditCurveDefinition curveDefinition = IsdaCreditCurveDefinition.of(CURVE_NAME, EUR, VALUATION_DATE, ACT_365F, singleNode, true, false); LegalEntitySurvivalProbabilities creditCurve = CALIBRATOR.calibrate(curveDefinition, MARKET_DATA, RATES_PROVIDER, REF_DATA); NodalCurve curve = (NodalCurve)creditCurve.SurvivalProbabilities.findData(CURVE_NAME).get(); assertTrue(DoubleArrayMath.fuzzyEquals(curve.XValues.toArray(), expectedTimes, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(curve.YValues.toArray(), expectedRates, TOL)); assertTrue(curve.getParameterMetadata(0) is DatedParameterMetadata); double computedIndex = curve.Metadata.getInfo(CurveInfoType.CDS_INDEX_FACTOR); assertEquals(computedIndex, 93.0 / 97.0, TOL); testJacobian(creditCurve, RATES_PROVIDER, singleNode, PUF_QUOTES); }
public virtual void test_regression() { double[] expectedTimes = new double[] { 2.852054794520548, 4.852054794520548, 6.854794520547945, 9.854794520547944 }; double[] expectedRates = new double[] { 0.03240798261187516, 0.04858422754375164, 0.0616141083562273, 0.06235460926516589 }; IsdaCreditCurveDefinition curveDefinition = IsdaCreditCurveDefinition.of(CURVE_NAME, EUR, VALUATION_DATE, ACT_365F, CURVE_NODES, true, false); LegalEntitySurvivalProbabilities creditCurve = CALIBRATOR.calibrate(curveDefinition, MARKET_DATA, RATES_PROVIDER, REF_DATA); NodalCurve curve = (NodalCurve)creditCurve.SurvivalProbabilities.findData(CURVE_NAME).get(); assertTrue(DoubleArrayMath.fuzzyEquals(curve.XValues.toArray(), expectedTimes, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(curve.YValues.toArray(), expectedRates, TOL)); assertTrue(curve.getParameterMetadata(0) is DatedParameterMetadata); assertTrue(curve.getParameterMetadata(1) is DatedParameterMetadata); assertTrue(curve.getParameterMetadata(2) is DatedParameterMetadata); assertTrue(curve.getParameterMetadata(3) is DatedParameterMetadata); double computedIndex = curve.Metadata.getInfo(CurveInfoType.CDS_INDEX_FACTOR); assertEquals(computedIndex, 93.0 / 97.0, TOL); testJacobian(creditCurve, RATES_PROVIDER, CURVE_NODES, PUF_QUOTES); }
public virtual void pufTest() { LocalDate valuationDate = LocalDate.of(2013, 4, 10); DoubleArray ycTime = DoubleArray.ofUnsafe(new double[] { 0.09041095890410959, 0.1726027397260274, 0.2547945205479452, 0.5123287671232877, 0.7616438356164383, 1.010958904109589, 2.008219178082192, 3.008219178082192, 4.008219178082192, 5.008219178082192, 6.008219178082192, 7.013698630136987, 8.01095890410959, 9.01095890410959, 10.01095890410959, 12.01917808219178, 15.016438356164384, 20.01917808219178, 25.021917808219175, 30.027397260273972 }); DoubleArray ycRate = DoubleArray.ofUnsafe(new double[] { 0.0020205071813561414, 0.0024226927083852126, 0.00280147037504029, 0.004449041082144009, 0.005821804782808804, 0.007254879152733453, 0.00378133614924816, 0.004815163234294319, 0.006576302084547871, 0.00884241431837336, 0.011358805989279104, 0.013793391727035883, 0.016014197840890115, 0.01801564209277191, 0.019757164421290663, 0.022773295945438254, 0.025862337032619587, 0.02848646344754061, 0.029753383126110852, 0.03045277462637107 }); IsdaCreditDiscountFactors yc = IsdaCreditDiscountFactors.of(EUR, valuationDate, CurveName.of("yc_usd"), ycTime, ycRate, ACT_365F); double[] timeNodeExp = new double[] { 0.19452054794520549, 0.4465753424657534, 0.6958904109589041, 0.9424657534246575, 1.1945205479452055, 1.4465753424657535, 1.6958904109589041, 1.9424657534246574, 2.1945205479452055, 2.4465753424657533, 2.695890410958904, 2.9452054794520546, 3.197260273972603, 3.4493150684931506, 3.6986301369863015, 3.9452054794520546, 4.197260273972603, 4.449315068493151, 4.698630136986301, 4.945205479452055, 5.197260273972603, 5.449315068493151, 5.698630136986301, 5.945205479452055, 6.197260273972603, 6.449315068493151, 6.698630136986301, 6.947945205479452, 7.2, 7.4520547945205475, 7.701369863013698, 7.947945205479452, 8.2, 8.452054794520548, 8.7013698630137, 8.947945205479453, 9.2, 9.452054794520548, 9.7013698630137, 9.947945205479453, 10.2 }; double[] rateNodeExp = new double[] { 0.11219168510100914, 0.11085321179769615, 0.11753783265486063, 0.11806409789291543, 0.12007843111645247, 0.12273722191216528, 0.12541993298405366, 0.12773640093265545, 0.1290535220739981, 0.13294183149211675, 0.13659302947963856, 0.13988488561043758, 0.1429469312254705, 0.14606538453369572, 0.14916286828444447, 0.15219682906227, 0.1548315745851032, 0.158141193071526, 0.16163981714033765, 0.1650400193930357, 0.1682351993447916, 0.1683744003954113, 0.168657453080796, 0.16915067878510565, 0.1694852880010724, 0.16990705130936645, 0.1704456138969621, 0.17105852486248443, 0.1717088423125347, 0.1727906445582425, 0.17407566745397665, 0.17547300248653266, 0.17679395545074758, 0.17769841457372118, 0.1788064602071617, 0.18001498257267778, 0.18123747758791092, 0.18253661761388457, 0.18406319235262744, 0.18582983758830868, 0.18750386499176422 }; double[] rateNodeExpMf = new double[] { 0.11107220823737506, 0.11011543264900588, 0.11685607164947402, 0.11742079953945683, 0.1194445192166302, 0.12220026187805585, 0.12494798294628297, 0.12731185688090763, 0.12860146674492023, 0.1325216904413876, 0.1362014254649678, 0.13951646788193767, 0.14254141853655264, 0.14567581048732742, 0.1487851622438674, 0.15182838855605538, 0.15442415754322128, 0.15774061191016645, 0.16124288871765308, 0.1646451035564102, 0.167796451103847, 0.16794456750248196, 0.16823438468063495, 0.1687328171292339, 0.16904360885724334, 0.16947020572961907, 0.17001201556723175, 0.17062724832190826, 0.17125190473373603, 0.17233319414449558, 0.17361785479583028, 0.1750136127341691, 0.17630530410589512, 0.17720871748506664, 0.17831270423353415, 0.17951604233911425, 0.18070939732103264, 0.18200162521943403, 0.18351891000003046, 0.1852740041292825, 0.18691086960422418 }; ImmutableCreditRatesProvider ratesProvider = ImmutableCreditRatesProvider.builder().valuationDate(valuationDate).discountCurves(ImmutableMap.of(EUR, yc)).recoveryRateCurves(ImmutableMap.of(LEGAL_ENTITY, ConstantRecoveryRates.of(LEGAL_ENTITY, valuationDate, 0.4))).creditCurves(ImmutableMap.of()).build(); LocalDate startDate = LocalDate.of(2013, 3, 20); LocalDate[] pillarDate = new LocalDate[] { LocalDate.of(2013, 6, 20), LocalDate.of(2013, 9, 20), LocalDate.of(2013, 12, 20), LocalDate.of(2014, 3, 20), LocalDate.of(2014, 6, 20), LocalDate.of(2014, 9, 20), LocalDate.of(2014, 12, 20), LocalDate.of(2015, 3, 20), LocalDate.of(2015, 6, 20), LocalDate.of(2015, 9, 20), LocalDate.of(2015, 12, 20), LocalDate.of(2016, 3, 20), LocalDate.of(2016, 6, 20), LocalDate.of(2016, 9, 20), LocalDate.of(2016, 12, 20), LocalDate.of(2017, 3, 20), LocalDate.of(2017, 6, 20), LocalDate.of(2017, 9, 20), LocalDate.of(2017, 12, 20), LocalDate.of(2018, 3, 20), LocalDate.of(2018, 6, 20), LocalDate.of(2018, 9, 20), LocalDate.of(2018, 12, 20), LocalDate.of(2019, 3, 20), LocalDate.of(2019, 6, 20), LocalDate.of(2019, 9, 20), LocalDate.of(2019, 12, 20), LocalDate.of(2020, 3, 20), LocalDate.of(2020, 6, 20), LocalDate.of(2020, 9, 20), LocalDate.of(2020, 12, 20), LocalDate.of(2021, 3, 20), LocalDate.of(2021, 6, 20), LocalDate.of(2021, 9, 20), LocalDate.of(2021, 12, 20), LocalDate.of(2022, 3, 20), LocalDate.of(2022, 6, 20), LocalDate.of(2022, 9, 20), LocalDate.of(2022, 12, 20), LocalDate.of(2023, 3, 20), LocalDate.of(2023, 6, 20) }; int nPillars = pillarDate.Length; double coupon = 500d * ONE_BP; ImmutableMarketDataBuilder builderCredit = ImmutableMarketData.builder(valuationDate); IList <CdsIsdaCreditCurveNode> nodes = new List <CdsIsdaCreditCurveNode>(nPillars); double[] quotes = new double[] { 0.32, 0.69, 1.32, 1.79, 2.36, 3.01, 3.7, 4.39, 5.02, 5.93, 6.85, 7.76, 8.67, 9.6, 10.53, 11.45, 12.33, 13.29, 14.26, 15.2, 16.11, 16.62, 17.12, 17.62, 18.09, 18.55, 19, 19.44, 19.87, 20.33, 20.79, 21.24, 21.67, 22.04, 22.41, 22.77, 23.12, 23.46, 23.8, 24.14, 24.46 }; for (int i = 0; i < nPillars; ++i) { CdsConvention conv = ImmutableCdsConvention.of("conv", EUR, ACT_360, Frequency.P3M, BUS_ADJ, CDS_SETTLE_STD); CdsTemplate temp = DatesCdsTemplate.of(startDate, pillarDate[i], conv); QuoteId id = QuoteId.of(StandardId.of("OG", pillarDate[i].ToString())); nodes.Add(CdsIsdaCreditCurveNode.ofPointsUpfront(temp, id, LEGAL_ENTITY, coupon)); builderCredit.addValue(id, quotes[i] * ONE_PC); } ImmutableMarketData marketData = builderCredit.build(); IsdaCreditCurveDefinition curveDefinition = IsdaCreditCurveDefinition.of(CurveName.of("cc"), EUR, valuationDate, ACT_365F, nodes, true, false); LegalEntitySurvivalProbabilities cc = BUILDER_ISDA.calibrate(curveDefinition, marketData, ratesProvider, REF_DATA); NodalCurve resCurve = ((IsdaCreditDiscountFactors)cc.SurvivalProbabilities).Curve; assertTrue(DoubleArrayMath.fuzzyEquals(resCurve.XValues.toArray(), timeNodeExp, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(resCurve.YValues.toArray(), rateNodeExp, TOL)); testJacobian(BUILDER_ISDA, cc, ratesProvider, nodes, quotes, ONE_PC, EPS); LegalEntitySurvivalProbabilities ccMf = BUILDER_MARKIT.calibrate(curveDefinition, marketData, ratesProvider, REF_DATA); NodalCurve resCurveMf = ((IsdaCreditDiscountFactors)ccMf.SurvivalProbabilities).Curve; assertTrue(DoubleArrayMath.fuzzyEquals(resCurveMf.XValues.toArray(), timeNodeExp, TOL)); assertTrue(DoubleArrayMath.fuzzyEquals(resCurveMf.YValues.toArray(), rateNodeExpMf, TOL)); testJacobian(BUILDER_MARKIT, ccMf, ratesProvider, nodes, quotes, ONE_PC, EPS); }
public virtual void test_optionPrice_down() { double tol = 1.0e-12; double barrier = 97d; ConstantContinuousSingleBarrierKnockoutFunction test = ConstantContinuousSingleBarrierKnockoutFunction.of(STRIKE, TIME_TO_EXPIRY, PutCall.CALL, NUM, BarrierType.DOWN, barrier, REBATE); double spot = 100d; double u = 1.05; double d = 0.98; double m = Math.Sqrt(u * d); double up = 0.29; double dp = 0.25; double mp = 1d - up - dp; // test getPayoffAtExpiryTrinomial DoubleArray computedPayoff = test.getPayoffAtExpiryTrinomial(spot, d, m); int expectedSize = 2 * NUM + 1; assertEquals(computedPayoff.size(), expectedSize); double[] price = new double[expectedSize]; for (int i = 0; i < expectedSize; ++i) { price[i] = spot * Math.Pow(u, 0.5 * i) * Math.Pow(d, NUM - 0.5 * i); } for (int i = 0; i < expectedSize; ++i) { double expectedPayoff = price[i] > barrier?Math.Max(price[i] - STRIKE, 0d) : REBATE_AMOUNT; if (i != 0 && price[i - 1] < barrier && price[i] > barrier) { expectedPayoff = 0.5 * (expectedPayoff * (price[i] - barrier) + REBATE_AMOUNT * (barrier - price[i - 1])) / (price[i] - price[i - 1]) + 0.5 * expectedPayoff; } assertEquals(computedPayoff.get(i), expectedPayoff, tol); } // test getNextOptionValues double df = 0.92; int n = 2; DoubleArray values = DoubleArray.of(1.4, 0.9, 0.1, 0.05, 0.0, 0.0, 0.0); DoubleArray computedNextValues = test.getNextOptionValues(df, up, mp, dp, values, spot, d, m, n); double tmp = df * (0.9 * dp + 0.1 * mp + 0.05 * up); DoubleArray expectedNextValues = DoubleArray.of(REBATE_AMOUNT, 0.5 * (tmp * (m * d - barrier / spot) + REBATE_AMOUNT * (barrier / spot - d * d)) / (m * d - d * d) + 0.5 * tmp, df * (0.1 * dp + 0.05 * mp), df * 0.05 * dp, 0.0); assertTrue(DoubleArrayMath.fuzzyEquals(computedNextValues.toArray(), expectedNextValues.toArray(), tol)); }
public virtual void test_optionPrice_up() { double tol = 1.0e-12; ConstantContinuousSingleBarrierKnockoutFunction test = ConstantContinuousSingleBarrierKnockoutFunction.of(STRIKE, TIME_TO_EXPIRY, PutCall.PUT, NUM, BarrierType.UP, BARRIER, REBATE); double spot = 130d; double u = 1.05; double d = 0.98; double m = Math.Sqrt(u * d); double up = 0.29; double dp = 0.25; double mp = 1d - up - dp; // test getPayoffAtExpiryTrinomial DoubleArray computedPayoff = test.getPayoffAtExpiryTrinomial(spot, d, m); int expectedSize = 2 * NUM + 1; assertEquals(computedPayoff.size(), expectedSize); double[] price = new double[expectedSize]; for (int i = 0; i < expectedSize; ++i) { price[i] = spot * Math.Pow(u, 0.5 * i) * Math.Pow(d, NUM - 0.5 * i); } for (int i = 0; i < expectedSize; ++i) { double expectedPayoff = price[i] < BARRIER?Math.Max(STRIKE - price[i], 0d) : REBATE_AMOUNT; if (i != expectedSize - 1 && price[i] < BARRIER && price[i + 1] > BARRIER) { expectedPayoff = 0.5 * ((BARRIER - price[i]) * expectedPayoff + (price[i + 1] - BARRIER) * REBATE_AMOUNT) / (price[i + 1] - price[i]) + 0.5 * expectedPayoff; } assertEquals(computedPayoff.get(i), expectedPayoff, tol); } // test getNextOptionValues double df = 0.92; int n = 2; DoubleArray values = DoubleArray.of(1.4, 0.9, 0.1, 0.05, 0.0, 0.0, 0.0); DoubleArray computedNextValues = test.getNextOptionValues(df, up, mp, dp, values, spot, d, m, n); double tmp = df * 0.05 * dp; DoubleArray expectedNextValues = DoubleArray.of(df * (1.4 * dp + 0.9 * mp + 0.1 * up), df * (0.9 * dp + 0.1 * mp + 0.05 * up), df * (0.1 * dp + 0.05 * mp), 0.5 * ((BARRIER / spot - u * m) * tmp + (u * u - BARRIER / spot) * REBATE_AMOUNT) / (u * u - u * m) + 0.5 * tmp, REBATE_AMOUNT); assertTrue(DoubleArrayMath.fuzzyEquals(computedNextValues.toArray(), expectedNextValues.toArray(), tol)); }
public virtual void test_derivative_sensitivity() { BoundCurveInterpolator bind = CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, Y_DATA, EXTRAP, EXTRAP); System.Func <double, double> derivFunc = x => bind.interpolate(x); for (int i = 0; i < X_LEFT_TEST.size(); ++i) { assertEquals(bind.firstDerivative(X_LEFT_TEST.get(i)), DIFF_CALC.differentiate(derivFunc).apply(X_LEFT_TEST.get(i)), EPS); int index = i; System.Func <DoubleArray, double> sensFunc = y => CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, y, EXTRAP, EXTRAP).interpolate(X_LEFT_TEST.get(index)); assertTrue(DoubleArrayMath.fuzzyEquals(bind.parameterSensitivity(X_LEFT_TEST.get(index)).toArray(), SENS_CALC.differentiate(sensFunc).apply(Y_DATA).toArray(), EPS)); } for (int i = 0; i < X_RIGHT_TEST.size(); ++i) { assertEquals(bind.firstDerivative(X_RIGHT_TEST.get(i)), DIFF_CALC.differentiate(derivFunc).apply(X_RIGHT_TEST.get(i)), EPS); int index = i; System.Func <DoubleArray, double> sensFunc = y => CurveInterpolators.DOUBLE_QUADRATIC.bind(X_DATA, y, EXTRAP, EXTRAP).interpolate(X_RIGHT_TEST.get(index)); assertTrue(DoubleArrayMath.fuzzyEquals(bind.parameterSensitivity(X_RIGHT_TEST.get(index)).toArray(), SENS_CALC.differentiate(sensFunc).apply(Y_DATA).toArray(), EPS)); } }