/// <summary> /// Re-buckets a <seealso cref="CurrencyParameterSensitivities"/> to a given set of dates. /// <para> /// The list of dates must be sorted in chronological order. All sensitivities are re-bucketed to the same date list. /// The re-bucketing is done by linear weighting on the number of days, i.e. the sensitivities for dates outside the /// extremes are fully bucketed to the extremes and for date between two re-bucketing dates, the weight on the start /// date is the number days between end date and the date re-bucketed divided by the number of days between the /// start and the end. /// The input sensitivity should have a <seealso cref="DatedParameterMetadata"/> for each sensitivity. /// /// </para> /// </summary> /// <param name="sensitivities"> the input sensitivities </param> /// <param name="targetDates"> the list of dates for the re-bucketing </param> /// <returns> the sensitivity after the re-bucketing </returns> public static CurrencyParameterSensitivities linearRebucketing(CurrencyParameterSensitivities sensitivities, IList <LocalDate> targetDates) { checkSortedDates(targetDates); int nbBuckets = targetDates.Count; IList <ParameterMetadata> pmdTarget = targetDates.Select(date => LabelDateParameterMetadata.of(date, date.ToString())).ToList(); ImmutableList <CurrencyParameterSensitivity> sensitivitiesList = sensitivities.Sensitivities; IList <CurrencyParameterSensitivity> sensitivityTarget = new List <CurrencyParameterSensitivity>(); foreach (CurrencyParameterSensitivity sensitivity in sensitivitiesList) { double[] rebucketedSensitivityAmounts = new double[nbBuckets]; DoubleArray sensitivityAmounts = sensitivity.Sensitivity; IList <ParameterMetadata> parameterMetadataList = sensitivity.ParameterMetadata; for (int loopnode = 0; loopnode < sensitivityAmounts.size(); loopnode++) { ParameterMetadata nodeMetadata = parameterMetadataList[loopnode]; //JAVA TO C# CONVERTER WARNING: The .NET Type.FullName property will not always yield results identical to the Java Class.getName method: ArgChecker.isTrue(nodeMetadata is DatedParameterMetadata, "re-bucketing requires sensitivity date for node {} which is of type {} while 'DatedParameterMetadata' is expected", nodeMetadata.Label, nodeMetadata.GetType().FullName); DatedParameterMetadata datedParameterMetadata = (DatedParameterMetadata)nodeMetadata; LocalDate nodeDate = datedParameterMetadata.Date; rebucketingArray(targetDates, rebucketedSensitivityAmounts, sensitivityAmounts.get(loopnode), nodeDate); } CurrencyParameterSensitivity rebucketedSensitivity = CurrencyParameterSensitivity.of(sensitivity.MarketDataName, pmdTarget, sensitivity.Currency, DoubleArray.ofUnsafe(rebucketedSensitivityAmounts)); sensitivityTarget.Add(rebucketedSensitivity); } return(CurrencyParameterSensitivities.of(sensitivityTarget)); }
public virtual void test_volatility_sensitivity() { double eps = 1.0e-6; int nData = TIME.size(); for (int i = 0; i < NB_TEST; i++) { double expiry = VOLS.relativeTime(TEST_OPTION_EXPIRY[i]); BondFutureOptionSensitivity point = BondFutureOptionSensitivity.of(VOLS.Name, expiry, TEST_FUTURE_EXPIRY[i], TEST_STRIKE_PRICE[i], TEST_FUTURE_PRICE[i], USD, TEST_SENSITIVITY[i]); CurrencyParameterSensitivity sensActual = VOLS.parameterSensitivity(point).Sensitivities.get(0); double[] computed = sensActual.Sensitivity.toArray(); for (int j = 0; j < nData; j++) { DoubleArray volDataUp = VOL.with(j, VOL.get(j) + eps); DoubleArray volDataDw = VOL.with(j, VOL.get(j) - eps); InterpolatedNodalSurface paramUp = InterpolatedNodalSurface.of(METADATA, TIME, MONEYNESS, volDataUp, INTERPOLATOR_2D); InterpolatedNodalSurface paramDw = InterpolatedNodalSurface.of(METADATA, TIME, MONEYNESS, volDataDw, INTERPOLATOR_2D); BlackBondFutureExpiryLogMoneynessVolatilities provUp = BlackBondFutureExpiryLogMoneynessVolatilities.of(VAL_DATE_TIME, paramUp); BlackBondFutureExpiryLogMoneynessVolatilities provDw = BlackBondFutureExpiryLogMoneynessVolatilities.of(VAL_DATE_TIME, paramDw); double volUp = provUp.volatility(expiry, TEST_FUTURE_EXPIRY[i], TEST_STRIKE_PRICE[i], TEST_FUTURE_PRICE[i]); double volDw = provDw.volatility(expiry, TEST_FUTURE_EXPIRY[i], TEST_STRIKE_PRICE[i], TEST_FUTURE_PRICE[i]); double fd = 0.5 * (volUp - volDw) / eps; assertEquals(computed[j], fd, eps); } } }
public virtual void test_convertedTo_sameCurrency() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_EUR1, EUR, VECTOR_EUR1); CurrencyParameterSensitivity test = @base.convertedTo(EUR, FX_RATE); assertSame(test, @base); }
//------------------------------------------------------------------------- public virtual void test_multipliedBy() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity test = @base.multipliedBy(FACTOR1); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD_FACTOR)); }
//------------------------------------------------------------------------- public virtual void test_convertedTo() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_EUR1, EUR, VECTOR_EUR1); CurrencyParameterSensitivity test = @base.convertedTo(USD, FX_RATE); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA_EUR1, USD, VECTOR_EUR1_IN_USD)); }
private CurrencyParameterSensitivity parameterSensitivity(FxOptionSensitivity point) { double expiryTime = point.Expiry; double strike = currencyPair.isInverse(point.CurrencyPair) ? 1d / point.Strike : point.Strike; double forward = currencyPair.isInverse(point.CurrencyPair) ? 1d / point.Forward : point.Forward; double pointValue = point.Sensitivity; DoubleMatrix bucketedSensi = smile.volatilityAndSensitivities(expiryTime, strike, forward).Sensitivities; double[] times = smile.Expiries.toArray(); int nTimes = times.Length; IList <double> sensiList = new List <double>(); IList <ParameterMetadata> paramList = new List <ParameterMetadata>(); for (int i = 0; i < nTimes; ++i) { DoubleArray deltas = smile.VolatilityTerm.get(i).Delta; int nDeltas = deltas.size(); int nDeltasTotal = 2 * nDeltas + 1; double[] deltasTotal = new double[nDeltasTotal]; // absolute delta deltasTotal[nDeltas] = 0.5d; for (int j = 0; j < nDeltas; ++j) { deltasTotal[j] = 1d - deltas.get(j); deltasTotal[2 * nDeltas - j] = deltas.get(j); } for (int j = 0; j < nDeltasTotal; ++j) { sensiList.Add(bucketedSensi.get(i, j) * pointValue); DeltaStrike absoluteDelta = DeltaStrike.of(deltasTotal[j]); ParameterMetadata parameterMetadata = FxVolatilitySurfaceYearFractionParameterMetadata.of(times[i], absoluteDelta, currencyPair); paramList.Add(parameterMetadata); } } return(CurrencyParameterSensitivity.of(name, paramList, point.Currency, DoubleArray.copyOf(sensiList))); }
/// <summary> /// Calculates the market quote sensitivities from parameter sensitivity. /// <para> /// This calculates the market quote sensitivities of fixed incomes. /// The input parameter sensitivities must be computed based on the legal entity discounting provider. /// /// </para> /// </summary> /// <param name="paramSensitivities"> the curve parameter sensitivities </param> /// <param name="provider"> the legal entity discounting provider, containing Jacobian calibration information </param> /// <returns> the market quote sensitivities </returns> public virtual CurrencyParameterSensitivities sensitivity(CurrencyParameterSensitivities paramSensitivities, LegalEntityDiscountingProvider provider) { ArgChecker.notNull(paramSensitivities, "paramSensitivities"); ArgChecker.notNull(provider, "provider"); CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty(); foreach (CurrencyParameterSensitivity paramSens in paramSensitivities.Sensitivities) { // find the matching calibration info Curve curve = provider.findData(paramSens.MarketDataName).filter(v => v is Curve).map(v => (Curve)v).orElseThrow(() => new System.ArgumentException("Market Quote sensitivity requires curve: " + paramSens.MarketDataName)); JacobianCalibrationMatrix info = curve.Metadata.findInfo(CurveInfoType.JACOBIAN).orElseThrow(() => new System.ArgumentException("Market Quote sensitivity requires Jacobian calibration information")); // calculate the market quote sensitivity using the Jacobian DoubleMatrix jacobian = info.JacobianMatrix; DoubleArray paramSensMatrix = paramSens.Sensitivity; DoubleArray marketQuoteSensMatrix = (DoubleArray)MATRIX_ALGEBRA.multiply(paramSensMatrix, jacobian); DoubleArray marketQuoteSens = marketQuoteSensMatrix; // split between different curves IDictionary <CurveName, DoubleArray> split = info.splitValues(marketQuoteSens); foreach (KeyValuePair <CurveName, DoubleArray> entry in split.SetOfKeyValuePairs()) { CurveName curveName = entry.Key; CurrencyParameterSensitivity maketQuoteSens = provider.findData(curveName).map(c => c.createParameterSensitivity(paramSens.Currency, entry.Value)).orElse(CurrencyParameterSensitivity.of(curveName, paramSens.Currency, entry.Value)); result = result.combinedWith(maketQuoteSens); } } return(result); }
public virtual void test_plus_sensitivity_wrongName() { CurrencyParameterSensitivity base1 = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity base2 = CurrencyParameterSensitivity.of(NAME2, METADATA_USD1, USD, VECTOR_USD1); assertThrowsIllegalArg(() => base1.plus(base2)); }
//------------------------------------------------------------------------- public virtual void test_plus_sensitivity() { CurrencyParameterSensitivity base1 = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity test = base1.plus(base1); assertEquals(test, base1.multipliedBy(2)); }
public virtual void test_combine_duplicateNames() { CurrencyParameterSensitivity base1 = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity base2 = CurrencyParameterSensitivity.of(NAME1, METADATA_USD2, USD, VECTOR_USD2); assertThrowsIllegalArg(() => CurrencyParameterSensitivity.combine(NAME_COMBINED, base1, base2)); }
public virtual void hard_coded_value_two_curves_one_date() { for (int loopdate = 0; loopdate < SENSITIVITY_DATES.Count - 1; loopdate++) { IList <ParameterMetadata> pmdInput1 = new List <ParameterMetadata>(); pmdInput1.Add(LabelDateParameterMetadata.of(SENSITIVITY_DATES[loopdate], "test")); CurrencyParameterSensitivity s1 = CurrencyParameterSensitivity.of(NAME_1, pmdInput1, CCY_1, DoubleArray.of(SENSITIVITY_AMOUNT)); IList <ParameterMetadata> pmdInput2 = new List <ParameterMetadata>(); pmdInput2.Add(LabelDateParameterMetadata.of(SENSITIVITY_DATES[loopdate + 1], "test")); CurrencyParameterSensitivity s2 = CurrencyParameterSensitivity.of(NAME_2, pmdInput2, CCY_2, DoubleArray.of(SENSITIVITY_AMOUNT)); CurrencyParameterSensitivities sList = CurrencyParameterSensitivities.of(s1, s2); CurrencyParameterSensitivities sTarget = CurveSensitivityUtils.linearRebucketing(sList, TARGET_DATES); assertTrue(sTarget.Sensitivities.size() == 2); CurrencyParameterSensitivity sTarget1 = sTarget.Sensitivities.get(0); assertTrue(sTarget1.MarketDataName.Equals(NAME_1)); assertTrue(sTarget1.Currency.Equals(CCY_1)); assertTrue(sTarget1.Sensitivity.size() == TARGET_DATES.Count); assertEquals(sTarget1.Sensitivity.get(WEIGHTS_START[loopdate]), WEIGHTS_HC[loopdate] * SENSITIVITY_AMOUNT, TOLERANCE_SENSI); assertEquals(sTarget1.Sensitivity.get(WEIGHTS_START[loopdate] + 1), (1.0d - WEIGHTS_HC[loopdate]) * SENSITIVITY_AMOUNT, TOLERANCE_SENSI); CurrencyParameterSensitivity sTarget2 = sTarget.Sensitivities.get(1); assertTrue(sTarget2.MarketDataName.Equals(NAME_2)); assertTrue(sTarget2.Currency.Equals(CCY_2)); assertTrue(sTarget2.Sensitivity.size() == TARGET_DATES.Count); assertEquals(sTarget2.Sensitivity.get(WEIGHTS_START[loopdate + 1]), WEIGHTS_HC[loopdate + 1] * SENSITIVITY_AMOUNT, TOLERANCE_SENSI); assertEquals(sTarget2.Sensitivity.get(WEIGHTS_START[loopdate + 1] + 1), (1.0d - WEIGHTS_HC[loopdate + 1]) * SENSITIVITY_AMOUNT, TOLERANCE_SENSI); } }
private void equalWithRelativeTolerance(CurrencyParameterSensitivities computed, CurrencyParameterSensitivities expected, double tolerance) { IList <CurrencyParameterSensitivity> mutable = new List <CurrencyParameterSensitivity>(expected.Sensitivities); // for each sensitivity in this instance, find matching in other instance foreach (CurrencyParameterSensitivity sens1 in computed.Sensitivities) { // list is already sorted so binary search is safe //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: int index = Collections.binarySearch(mutable, sens1, CurrencyParameterSensitivity::compareKey); if (index >= 0) { // matched, so must be equal CurrencyParameterSensitivity sens2 = mutable[index]; equalZeroWithRelativeTolerance(sens1.Sensitivity, sens2.Sensitivity, tolerance); mutable.RemoveAt(index); } else { // did not match, so must be zero assertTrue(sens1.Sensitivity.equalZeroWithTolerance(tolerance)); } } // all that remain from other instance must be zero foreach (CurrencyParameterSensitivity sens2 in mutable) { assertTrue(sens2.Sensitivity.equalZeroWithTolerance(tolerance)); } }
private void presentValueSensitivityRawDataParallelSensitivity(SabrParametersSwaptionVolatilities sabrCalibrated, TenorRawOptionData dataRaw) { PointSensitivities points = LEG_PRICER.presentValueSensitivityModelParamsSabr(FLOOR_LEG, MULTICURVE, sabrCalibrated).build(); CurrencyParameterSensitivities sabrParametersSurfaceSensitivities = sabrCalibrated.parameterSensitivity(points); CurrencyParameterSensitivity parallelSensitivitiesSurface = RDSC.parallelSensitivity(sabrParametersSurfaceSensitivities, sabrCalibrated); DoubleArray sensitivityArray = parallelSensitivitiesSurface.Sensitivity; double fdShift = 1.0E-6; int surfacePointIndex = 0; for (int loopexpiry = 0; loopexpiry < EXPIRIES.size(); loopexpiry++) { for (int looptenor = 0; looptenor < TENORS.size(); looptenor++) { Tenor tenor = TENORS.get(looptenor); Pair <DoubleArray, DoubleArray> ds = dataRaw.getData(tenor).availableSmileAtExpiry(EXPIRIES.get(loopexpiry)); if (!ds.First.Empty) { double[] pv = new double[2]; // pv with shift up and down for (int loopsign = 0; loopsign < 2; loopsign++) { TenorRawOptionData dataShifted = SabrSwaptionCalibratorSmileTestUtils.rawDataShiftSmile(TENORS, EXPIRIES, ValueType.SIMPLE_MONEYNESS, MONEYNESS, ValueType.NORMAL_VOLATILITY, DATA_ARRAY_FULL, looptenor, loopexpiry, (2 * loopsign - 1) * fdShift); SabrParametersSwaptionVolatilities calibratedShifted = SABR_CALIBRATION.calibrateWithFixedBetaAndShift(DEFINITION, CALIBRATION_TIME, dataShifted, MULTICURVE, BETA_SURFACE, SHIFT_SABR_SURFACE); pv[loopsign] = LEG_PRICER.presentValue(FLOOR_LEG, MULTICURVE, calibratedShifted).Amount; } double sensitivityFd = (pv[1] - pv[0]) / (2 * fdShift); // FD sensitivity computation SabrSwaptionCalibratorSmileTestUtils.checkAcceptable(sensitivityFd, sensitivityArray.get(surfacePointIndex), 0.10, "Tenor/Expiry: " + TENORS.get(looptenor) + " / " + EXPIRIES.get(loopexpiry)); surfacePointIndex++; } } } }
private void test_from_functions_one_curve_all_dates(System.Func <LocalDate, ParameterMetadata> parameterMetadataFunction, System.Func <CurrencyParameterSensitivities, CurrencyParameterSensitivities> rebucketFunction) { IList <ParameterMetadata> pmdInput = new List <ParameterMetadata>(); double[] sensiExpected = new double[TARGET_DATES.Count]; for (int loopdate = 0; loopdate < SENSITIVITY_DATES.Count; loopdate++) { pmdInput.Add(parameterMetadataFunction(SENSITIVITY_DATES[loopdate])); sensiExpected[WEIGHTS_START[loopdate]] += WEIGHTS_HC[loopdate] * SENSITIVITY_AMOUNT; sensiExpected[WEIGHTS_START[loopdate] + 1] += (1.0d - WEIGHTS_HC[loopdate]) * SENSITIVITY_AMOUNT; } DoubleArray sens = DoubleArray.of(SENSITIVITY_DATES.Count, (d) => SENSITIVITY_AMOUNT); CurrencyParameterSensitivity s = CurrencyParameterSensitivity.of(NAME_1, pmdInput, CCY_1, sens); CurrencyParameterSensitivities s2 = CurrencyParameterSensitivities.of(s); CurrencyParameterSensitivities sTarget = rebucketFunction(s2); assertTrue(sTarget.Sensitivities.size() == 1); CurrencyParameterSensitivity sTarget1 = sTarget.Sensitivities.get(0); assertTrue(sTarget1.MarketDataName.Equals(NAME_1)); assertTrue(sTarget1.Currency.Equals(CCY_1)); assertTrue(sTarget1.Sensitivity.size() == TARGET_DATES.Count); for (int looptarget = 0; looptarget < TARGET_DATES.Count; looptarget++) { assertEquals(sTarget1.Sensitivity.get(looptarget), sensiExpected[looptarget], TOLERANCE_SENSI); } }
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(IborCapletFloorletVolatilitiesName.of(NAME), expiryTime, TEST_STRIKE[k], TEST_FORWARD, GBP, TEST_SENSITIVITY[i]); CurrencyParameterSensitivity sensActual = VOLS.parameterSensitivity(point).Sensitivities.get(0); DoubleArray computed = sensActual.Sensitivity; 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); NormalIborCapletFloorletExpiryStrikeVolatilities provUp = NormalIborCapletFloorletExpiryStrikeVolatilities.of(GBP_LIBOR_3M, VAL_DATE_TIME, paramUp); NormalIborCapletFloorletExpiryStrikeVolatilities provDw = NormalIborCapletFloorletExpiryStrikeVolatilities.of(GBP_LIBOR_3M, VAL_DATE_TIME, paramDw); 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; assertEquals(computed.get(j), fd * TEST_SENSITIVITY[i], eps); } } } }
// modified sensitivity function - CombinedCurve involved private CurrencyParameterSensitivities sensiCombinedFnBond(ImmutableLegalEntityDiscountingProvider provider) { CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty(); double sum = sumCombine(provider); // repo curves ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapCurrency = provider.RepoCurves; foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapCurrency.entrySet()) { CombinedCurve curveComb = (CombinedCurve)getCurve(entry.Value); InterpolatedNodalCurve baseCurveInt = checkInterpolated(curveComb.BaseCurve); InterpolatedNodalCurve spreadCurveInt = checkInterpolated(curveComb.SpreadCurve); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(baseCurveInt.Name, USD, DoubleArray.of(baseCurveInt.ParameterCount, i => 2d * sum * baseCurveInt.XValues.get(i)))); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(spreadCurveInt.Name, USD, DoubleArray.of(spreadCurveInt.ParameterCount, i => 2d * sum * spreadCurveInt.XValues.get(i)))); } // issuer curves ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapIndex = provider.IssuerCurves; foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapIndex.entrySet()) { CombinedCurve curveComb = (CombinedCurve)getCurve(entry.Value); InterpolatedNodalCurve baseCurveInt = checkInterpolated(curveComb.BaseCurve); InterpolatedNodalCurve spreadCurveInt = checkInterpolated(curveComb.SpreadCurve); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(baseCurveInt.Name, USD, DoubleArray.of(baseCurveInt.ParameterCount, i => 2d * sum * baseCurveInt.XValues.get(i)))); sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(spreadCurveInt.Name, USD, DoubleArray.of(spreadCurveInt.ParameterCount, i => 2d * sum * spreadCurveInt.XValues.get(i)))); } return(sensi); }
//------------------------------------------------------------------------- public virtual void test_multipliedBy_currency() { UnitParameterSensitivity @base = UnitParameterSensitivity.of(NAME1, METADATA1, VECTOR1); CurrencyParameterSensitivity test = @base.multipliedBy(USD, FACTOR1); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA1, USD, VECTOR1_FACTOR)); }
public override CurrencyParameterSensitivity createParameterSensitivity(Currency currency, DoubleArray sensitivities) { CurrencyParameterSensitivity baseSensi = baseCurve.createParameterSensitivity(currency, sensitivities.subArray(0, baseCurve.ParameterCount)); CurrencyParameterSensitivity spreadSensi = spreadCurve.createParameterSensitivity(currency, sensitivities.subArray(baseCurve.ParameterCount, sensitivities.size())); return(CurrencyParameterSensitivity.combine(Name, baseSensi, spreadSensi)); }
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_plus_array() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity test = @base.plus(VECTOR_USD1); assertEquals(test, @base.multipliedBy(2)); }
/// <summary> /// Returns the diagonal part of the sensitivity as {@code CurrencyParameterSensitivity}. /// </summary> /// <returns> the diagonal part </returns> public CurrencyParameterSensitivity diagonal() { CrossGammaParameterSensitivity blockDiagonal = getSensitivity(MarketDataName); int size = ParameterCount; return(CurrencyParameterSensitivity.of(MarketDataName, ParameterMetadata, Currency, DoubleArray.of(size, i => blockDiagonal.Sensitivity.get(i, i)))); }
//------------------------------------------------------------------------- public virtual void test_toUnitParameterSensitivity() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); UnitParameterSensitivity test = @base.toUnitParameterSensitivity(); assertEquals(test, UnitParameterSensitivity.of(NAME1, METADATA_USD1, VECTOR_USD1)); }
public virtual void test_sensitivities() { ParameterizedFunctionalCurve test = ParameterizedFunctionalCurve.of(METADATA, PARAMETERS, VALUE_FUNCTION, DERIVATIVE_FUNCTION, SENSITIVITY_FUNCTION); DoubleArray sensiVal = DoubleArray.of(1d, 2d, 3d); assertEquals(test.createParameterSensitivity(sensiVal), UnitParameterSensitivity.of(METADATA.CurveName, METADATA.ParameterMetadata.get(), sensiVal)); assertEquals(test.createParameterSensitivity(USD, sensiVal), CurrencyParameterSensitivity.of(METADATA.CurveName, METADATA.ParameterMetadata.get(), USD, sensiVal)); }
public virtual void test_diagonal() { CrossGammaParameterSensitivity @base = CrossGammaParameterSensitivity.of(NAME1, METADATA_USD1, USD, MATRIX_USD1); CurrencyParameterSensitivity test = @base.diagonal(); DoubleArray value = DoubleArray.of(MATRIX_USD1.get(0, 0), MATRIX_USD1.get(1, 1)); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, value)); }
//------------------------------------------------------------------------- public virtual void test_split1() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); ImmutableList <CurrencyParameterSensitivity> test = @base.split(); assertEquals(test.size(), 1); assertEquals(test.get(0), @base); }
public override DoubleArray apply(DoubleArray s) { double shift = s.get(0); Curve curveBumped = ParallelShiftedCurve.absolute(curve, shift); CurrencyParameterSensitivity pts = sensitivitiesFn.apply(curveBumped); return(pts.Sensitivity); }
//------------------------------------------------------------------------- public virtual void test_withSensitivity() { CurrencyParameterSensitivity @base = CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD1); CurrencyParameterSensitivity test = @base.withSensitivity(VECTOR_USD_FACTOR); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, VECTOR_USD_FACTOR)); assertThrowsIllegalArg(() => @base.withSensitivity(DoubleArray.of(1d))); }
public CurrencyParameterSensitivities parameterSensitivity(ZeroRateSensitivity pointSens) { double yearFraction = pointSens.YearFraction; UnitParameterSensitivity unitSens = curve.yValueParameterSensitivity(yearFraction); CurrencyParameterSensitivity curSens = unitSens.multipliedBy(pointSens.Currency, pointSens.Sensitivity); return(CurrencyParameterSensitivities.of(curSens)); }
public virtual void test_diagonal_eurUsd() { CrossGammaParameterSensitivity @base = CrossGammaParameterSensitivity.of(NAME1, METADATA_USD1, ImmutableList.of(Pair.of(NAME1, METADATA_USD1), Pair.of(NAME2, METADATA_EUR1)), USD, MATRIX_USD_EUR); CurrencyParameterSensitivity test = @base.diagonal(); DoubleArray value = DoubleArray.of(MATRIX_USD1.get(0, 0), MATRIX_USD1.get(1, 1)); assertEquals(test, CurrencyParameterSensitivity.of(NAME1, METADATA_USD1, USD, value)); }
//------------------------------------------------------------------------- /// <summary> /// Calculates the raw data sensitivities from SABR parameter sensitivity. /// <para> /// The SABR parameter sensitivities to data are stored in some optional data in the /// <seealso cref="SabrParametersSwaptionVolatilities"/>. /// The sensitivities to the SABR parameters passed in should be compatible with the SABR parameters in term of data order. /// </para> /// <para> /// Only the sensitivity to the SABR parameters for which there is a data sensitivity are taken into account. /// At least one of the four parameter must have such sensitivities. /// /// </para> /// </summary> /// <param name="paramSensitivities"> the curve SABR parameter sensitivities </param> /// <param name="volatilities"> the SABR parameters, including the data sensitivity metadata </param> /// <returns> the raw data sensitivities </returns> public virtual CurrencyParameterSensitivity parallelSensitivity(CurrencyParameterSensitivities paramSensitivities, SabrParametersSwaptionVolatilities volatilities) { IList <IList <DoubleArray> > sensitivityToRawData = new List <IList <DoubleArray> >(4); Optional <ImmutableList <DoubleArray> > alphaInfo = volatilities.DataSensitivityAlpha; sensitivityToRawData.Add(alphaInfo.orElse(null)); Optional <ImmutableList <DoubleArray> > betaInfo = volatilities.DataSensitivityBeta; sensitivityToRawData.Add(betaInfo.orElse(null)); Optional <ImmutableList <DoubleArray> > rhoInfo = volatilities.DataSensitivityRho; sensitivityToRawData.Add(rhoInfo.orElse(null)); Optional <ImmutableList <DoubleArray> > nuInfo = volatilities.DataSensitivityNu; sensitivityToRawData.Add(nuInfo.orElse(null)); ArgChecker.isTrue(alphaInfo.Present || betaInfo.Present || rhoInfo.Present || nuInfo.Present, "at least one sensitivity to raw data must be available"); checkCurrency(paramSensitivities); int nbSurfaceNode = sensitivityToRawData[0].Count; double[] sensitivityRawArray = new double[nbSurfaceNode]; Currency ccy = null; IList <ParameterMetadata> metadataResult = null; foreach (CurrencyParameterSensitivity s in paramSensitivities.Sensitivities) { ccy = s.Currency; //JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET: //ORIGINAL LINE: com.opengamma.strata.data.MarketDataName<?> name = s.getMarketDataName(); MarketDataName <object> name = s.MarketDataName; if (name is SurfaceName) { if (volatilities.Parameters.AlphaSurface.Name.Equals(name) && alphaInfo.Present) { updateSensitivity(s, sensitivityToRawData[0], sensitivityRawArray); metadataResult = s.ParameterMetadata; } if (volatilities.Parameters.BetaSurface.Name.Equals(name) && betaInfo.Present) { updateSensitivity(s, sensitivityToRawData[1], sensitivityRawArray); metadataResult = s.ParameterMetadata; } if (volatilities.Parameters.RhoSurface.Name.Equals(name) && rhoInfo.Present) { updateSensitivity(s, sensitivityToRawData[2], sensitivityRawArray); metadataResult = s.ParameterMetadata; } if (volatilities.Parameters.NuSurface.Name.Equals(name) && nuInfo.Present) { updateSensitivity(s, sensitivityToRawData[3], sensitivityRawArray); metadataResult = s.ParameterMetadata; } } } DoubleArray sensitivityRaw = DoubleArray.ofUnsafe(sensitivityRawArray); return(CurrencyParameterSensitivity.of(SurfaceName.of("RawDataParallelSensitivity"), metadataResult, ccy, sensitivityRaw)); }