Ejemplo n.º 1
0
        // 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);
        }
Ejemplo n.º 2
0
        private CurrencyParameterSensitivities sensitivityCreidtCurve <T>(ImmutableCreditRatesProvider provider, System.Func <ImmutableCreditRatesProvider, CurrencyAmount> valueFn, MetaProperty <ImmutableMap <T, LegalEntitySurvivalProbabilities> > metaProperty, CurrencyAmount valueInit)
        {
            ImmutableMap <T, LegalEntitySurvivalProbabilities> baseCurves = metaProperty.get(provider);
            CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty();

            foreach (T key in baseCurves.Keys)
            {
                LegalEntitySurvivalProbabilities credit = baseCurves.get(key);
                CreditDiscountFactors            creditDiscountFactors = credit.SurvivalProbabilities;
                DiscountFactors discountFactors = creditDiscountFactors.toDiscountFactors();
                Curve           curve           = checkDiscountFactors(discountFactors);
                int             paramCount      = curve.ParameterCount;
                double[]        sensitivity     = new double[paramCount];
                for (int i = 0; i < paramCount; i++)
                {
                    Curve dscBumped = curve.withParameter(i, curve.getParameter(i) + shift);
                    IDictionary <T, LegalEntitySurvivalProbabilities> mapBumped = new Dictionary <T, LegalEntitySurvivalProbabilities>(baseCurves);
                    mapBumped[key] = LegalEntitySurvivalProbabilities.of(credit.LegalEntityId, createCreditDiscountFactors(creditDiscountFactors, dscBumped));
                    ImmutableCreditRatesProvider providerDscBumped = provider.toBuilder().set(metaProperty, mapBumped).build();
                    sensitivity[i] = (valueFn(providerDscBumped).Amount - valueInit.Amount) / shift;
                }
                result = result.combinedWith(curve.createParameterSensitivity(valueInit.Currency, DoubleArray.copyOf(sensitivity)));
            }
            return(result);
        }
        /// <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);
        }
        /// <summary>
        /// Calculates the present value sensitivity of the FX barrier option product.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of <seealso cref="#presentValue"/> to
        /// the underlying curve parameters.
        /// </para>
        /// <para>
        /// The sensitivity is computed by bump and re-price.
        ///
        /// </para>
        /// </summary>
        /// <param name="option">  the option product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <param name="baseTreeData">  the trinomial tree data </param>
        /// <returns> the present value of the product </returns>
        public virtual CurrencyParameterSensitivities presentValueSensitivityRates(ResolvedFxSingleBarrierOption option, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities, RecombiningTrinomialTreeData baseTreeData)
        {
            ArgChecker.isTrue(baseTreeData.NumberOfSteps == calibrator.NumberOfSteps, "the number of steps mismatch between pricer and trinomial tree data");
            double                         shift            = 1.0e-5;
            CurrencyAmount                 pvBase           = presentValue(option, ratesProvider, volatilities, baseTreeData);
            ResolvedFxVanillaOption        underlyingOption = option.UnderlyingOption;
            ResolvedFxSingle               underlyingFx     = underlyingOption.Underlying;
            CurrencyPair                   currencyPair     = underlyingFx.CurrencyPair;
            ImmutableRatesProvider         immRatesProvider = ratesProvider.toImmutableRatesProvider();
            ImmutableMap <Currency, Curve> baseCurves       = immRatesProvider.DiscountCurves;
            CurrencyParameterSensitivities result           = CurrencyParameterSensitivities.empty();

            foreach (KeyValuePair <Currency, Curve> entry in baseCurves.entrySet())
            {
                if (currencyPair.contains(entry.Key))
                {
                    Curve       curve       = entry.Value;
                    int         nParams     = curve.ParameterCount;
                    DoubleArray sensitivity = DoubleArray.of(nParams, i =>
                    {
                        Curve dscBumped = curve.withParameter(i, curve.getParameter(i) + shift);
                        IDictionary <Currency, Curve> mapBumped = new Dictionary <Currency, Curve>(baseCurves);
                        mapBumped[entry.Key] = dscBumped;
                        ImmutableRatesProvider providerDscBumped = immRatesProvider.toBuilder().discountCurves(mapBumped).build();
                        double pvBumped = presentValue(option, providerDscBumped, volatilities).Amount;
                        return((pvBumped - pvBase.Amount) / shift);
                    });
                    result = result.combinedWith(curve.createParameterSensitivity(pvBase.Currency, sensitivity));
                }
            }
            return(result);
        }
Ejemplo n.º 5
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the first order sensitivities of a function of a {@code CreditRatesProvider} to a double by finite difference.
        /// <para>
        /// The finite difference is computed by forward type.
        /// The function should return a value in the same currency for any rates provider of {@code CreditRatesProvider}.
        ///
        /// </para>
        /// </summary>
        /// <param name="provider">  the rates provider </param>
        /// <param name="valueFn">  the function from a rate provider to a currency amount for which the sensitivity should be computed </param>
        /// <returns> the curve sensitivity </returns>
        public virtual CurrencyParameterSensitivities sensitivity(CreditRatesProvider provider, System.Func <ImmutableCreditRatesProvider, CurrencyAmount> valueFn)
        {
            ImmutableCreditRatesProvider immutableProvider = provider.toImmutableCreditRatesProvider();
            CurrencyAmount valueInit = valueFn(immutableProvider);
            CurrencyParameterSensitivities discounting = sensitivityDiscountCurve(immutableProvider, valueFn, ImmutableCreditRatesProvider.meta().discountCurves(), valueInit);
            CurrencyParameterSensitivities credit      = sensitivityCreidtCurve(immutableProvider, valueFn, ImmutableCreditRatesProvider.meta().creditCurves(), valueInit);

            return(discounting.combinedWith(credit));
        }
Ejemplo n.º 6
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the first order sensitivities of a function of a LegalEntityDiscountingProvider to a double by finite difference.
        /// <para>
        /// The finite difference is computed by forward type.
        /// The function should return a value in the same currency for any rates provider of LegalEntityDiscountingProvider.
        ///
        /// </para>
        /// </summary>
        /// <param name="provider">  the rates provider </param>
        /// <param name="valueFn">  the function from a rate provider to a currency amount for which the sensitivity should be computed </param>
        /// <returns> the curve sensitivity </returns>
        public virtual CurrencyParameterSensitivities sensitivity(LegalEntityDiscountingProvider provider, System.Func <ImmutableLegalEntityDiscountingProvider, CurrencyAmount> valueFn)
        {
            ImmutableLegalEntityDiscountingProvider immProv = provider.toImmutableLegalEntityDiscountingProvider();
            CurrencyAmount valueInit = valueFn(immProv);
            CurrencyParameterSensitivities discounting = sensitivity(immProv, valueFn, ImmutableLegalEntityDiscountingProvider.meta().repoCurves(), valueInit);
            CurrencyParameterSensitivities forward     = sensitivity(immProv, valueFn, ImmutableLegalEntityDiscountingProvider.meta().issuerCurves(), valueInit);

            return(discounting.combinedWith(forward));
        }
Ejemplo n.º 7
0
        //-------------------------------------------------------------------------
        // computes diagonal part
        private CurrencyParameterSensitivities sensitivityDiagonal(RatesProvider provider, System.Func <ImmutableRatesProvider, CurrencyAmount> valueFn)
        {
            ImmutableRatesProvider         immProv     = provider.toImmutableRatesProvider();
            CurrencyAmount                 valueInit   = valueFn(immProv);
            CurrencyParameterSensitivities discounting = sensitivity(immProv, immProv.DiscountCurves, (@base, bumped) => @base.toBuilder().discountCurves(bumped).build(), valueFn, valueInit);
            CurrencyParameterSensitivities forward     = sensitivity(immProv, immProv.IndexCurves, (@base, bumped) => @base.toBuilder().indexCurves(bumped).build(), valueFn, valueInit);

            return(discounting.combinedWith(forward));
        }
Ejemplo n.º 8
0
        public virtual void present_value_sensitivity_payer_receiver_parity()
        {
            PointSensitivities             pvptLongPay  = PRICER_SWAPTION_BLACK.presentValueSensitivityRatesStickyStrike(SWAPTION_LONG_PAY, MULTI_USD, BLACK_VOLS_USD_STD).build();
            PointSensitivities             pvptShortRec = PRICER_SWAPTION_BLACK.presentValueSensitivityRatesStickyStrike(SWAPTION_SHORT_REC, MULTI_USD, BLACK_VOLS_USD_STD).build();
            PointSensitivities             pvptSwapRec  = PRICER_SWAP.presentValueSensitivity(RSWAP_PAY, MULTI_USD).build();
            CurrencyParameterSensitivities pvpsLongPay  = MULTI_USD.parameterSensitivity(pvptLongPay);
            CurrencyParameterSensitivities pvpsShortRec = MULTI_USD.parameterSensitivity(pvptShortRec);
            CurrencyParameterSensitivities pvpsSwapRec  = MULTI_USD.parameterSensitivity(pvptSwapRec);

            assertTrue(pvpsLongPay.combinedWith(pvpsShortRec).equalWithTolerance(pvpsSwapRec, TOLERANCE_PV_DELTA));
        }
        //-------------------------------------------------------------------------
        public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is CreditCurveZeroRateSensitivity)
                {
                    CreditCurveZeroRateSensitivity   pt      = (CreditCurveZeroRateSensitivity)point;
                    LegalEntitySurvivalProbabilities factors = survivalProbabilities(pt.LegalEntityId, pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
                else if (point is ZeroRateSensitivity)
                {
                    ZeroRateSensitivity   pt      = (ZeroRateSensitivity)point;
                    CreditDiscountFactors factors = discountFactors(pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
            }
            return(sens);
        }
        public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is RepoCurveZeroRateSensitivity)
                {
                    RepoCurveZeroRateSensitivity pt      = (RepoCurveZeroRateSensitivity)point;
                    RepoCurveDiscountFactors     factors = repoCurveDiscountFactors(pt.RepoGroup, pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
                else if (point is IssuerCurveZeroRateSensitivity)
                {
                    IssuerCurveZeroRateSensitivity pt      = (IssuerCurveZeroRateSensitivity)point;
                    IssuerCurveDiscountFactors     factors = issuerCurveDiscountFactors(pt.LegalEntityGroup, pt.CurveCurrency);
                    sens = sens.combinedWith(factors.parameterSensitivity(pt));
                }
            }
            return(sens);
        }
        //-------------------------------------------------------------------------
        public virtual void pointToParameterMultiple()
        {
            CurrencyParameterSensitivities psComputed = PROVIDER.parameterSensitivity(POINT);

            assertEquals(psComputed.Sensitivities.size(), 6);
            CurrencyParameterSensitivities psExpected = CurrencyParameterSensitivities.empty();

            for (int i = 0; i < POINTS.Length; i++)
            {
                psExpected = psExpected.combinedWith(PROVIDER.parameterSensitivity(POINTS[i]));
            }
            assertTrue(psComputed.equalWithTolerance(psExpected, TOLERANCE_SENSI));
        }
Ejemplo n.º 12
0
        //-------------------------------------------------------------------------
        private CurrencyParameterSensitivities sensiFn(ImmutableRatesProvider provider)
        {
            CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty();
            // Currency
            ImmutableMap <Currency, Curve> mapCurrency = provider.DiscountCurves;

            foreach (KeyValuePair <Currency, Curve> entry in mapCurrency.entrySet())
            {
                InterpolatedNodalCurve curveInt = checkInterpolated(entry.Value);
                double sumSqrt = sum(provider);
                sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curveInt.Name, USD, DoubleArray.of(curveInt.ParameterCount, i => 2d * sumSqrt * curveInt.XValues.get(i))));
            }
            // Index
            ImmutableMap <Index, Curve> mapIndex = provider.IndexCurves;

            foreach (KeyValuePair <Index, Curve> entry in mapIndex.entrySet())
            {
                InterpolatedNodalCurve curveInt = checkInterpolated(entry.Value);
                double sumSqrt = sum(provider);
                sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curveInt.Name, USD, DoubleArray.of(curveInt.ParameterCount, i => 2d * sumSqrt * curveInt.XValues.get(i))));
            }
            return(sensi);
        }
Ejemplo n.º 13
0
        // modified sensitivity function - CombinedCurve involved
        private CurrencyParameterSensitivities sensiCombinedFn(ImmutableRatesProvider provider)
        {
            CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty();
            double sum = sumCombine(provider);
            // Currency
            ImmutableMap <Currency, Curve> mapCurrency = provider.DiscountCurves;

            foreach (KeyValuePair <Currency, Curve> entry in mapCurrency.entrySet())
            {
                CombinedCurve          curveComb      = (CombinedCurve)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))));
            }
            // Index
            ImmutableMap <Index, Curve> mapIndex = provider.IndexCurves;

            foreach (KeyValuePair <Index, Curve> entry in mapIndex.entrySet())
            {
                if (entry.Value is CombinedCurve)
                {
                    CombinedCurve          curveComb      = (CombinedCurve)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))));
                }
                else
                {
                    InterpolatedNodalCurve curveInt = checkInterpolated(entry.Value);
                    sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curveInt.Name, USD, DoubleArray.of(curveInt.ParameterCount, i => 2d * sum * curveInt.XValues.get(i))));
                }
            }
            return(sensi);
        }
Ejemplo n.º 14
0
        //-------------------------------------------------------------------------
        private CurrencyParameterSensitivities sensiFnBond(ImmutableLegalEntityDiscountingProvider provider)
        {
            CurrencyParameterSensitivities sensi = CurrencyParameterSensitivities.empty();
            double sum = this.sum(provider);
            // repo curves
            ImmutableMap <Pair <RepoGroup, Currency>, DiscountFactors> mapRepoCurves = provider.RepoCurves;

            foreach (KeyValuePair <Pair <RepoGroup, Currency>, DiscountFactors> entry in mapRepoCurves.entrySet())
            {
                DiscountFactors        discountFactors = entry.Value;
                InterpolatedNodalCurve curve           = (InterpolatedNodalCurve)getCurve(discountFactors);
                sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curve.Name, discountFactors.Currency, DoubleArray.of(discountFactors.ParameterCount, i => 2d * curve.XValues.get(i) * sum)));
            }
            // issuer curves
            ImmutableMap <Pair <LegalEntityGroup, Currency>, DiscountFactors> mapIssuerCurves = provider.IssuerCurves;

            foreach (KeyValuePair <Pair <LegalEntityGroup, Currency>, DiscountFactors> entry in mapIssuerCurves.entrySet())
            {
                DiscountFactors        discountFactors = entry.Value;
                InterpolatedNodalCurve curve           = (InterpolatedNodalCurve)getCurve(discountFactors);
                sensi = sensi.combinedWith(CurrencyParameterSensitivity.of(curve.Name, discountFactors.Currency, DoubleArray.of(discountFactors.ParameterCount, i => 2d * curve.XValues.get(i) * sum)));
            }
            return(sensi);
        }
        public virtual void test_presentValueSensitivity_parity()
        {
            CurrencyParameterSensitivities pvSensiRecLong  = RATE_PROVIDER.parameterSensitivity(SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiRecShort = RATE_PROVIDER.parameterSensitivity(SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(SWAPTION_REC_SHORT, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiPayLong  = RATE_PROVIDER.parameterSensitivity(SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(SWAPTION_PAY_LONG, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiPayShort = RATE_PROVIDER.parameterSensitivity(SWAPTION_PRICER.presentValueSensitivityRatesStickyModel(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build());

            assertTrue(pvSensiRecLong.equalWithTolerance(pvSensiRecShort.multipliedBy(-1d), NOTIONAL * TOL));
            assertTrue(pvSensiPayLong.equalWithTolerance(pvSensiPayShort.multipliedBy(-1d), NOTIONAL * TOL));

            CurrencyParameterSensitivities pvSensiSwap = RATE_PROVIDER.parameterSensitivity(SWAP_PRICER.presentValueSensitivity(RSWAP_PAY, RATE_PROVIDER).build());

            assertTrue(pvSensiSwap.equalWithTolerance(pvSensiPayLong.combinedWith(pvSensiRecLong.multipliedBy(-1d)), NOTIONAL * TOL));
            assertTrue(pvSensiSwap.equalWithTolerance(pvSensiRecShort.combinedWith(pvSensiPayShort.multipliedBy(-1d)), NOTIONAL * TOL));
        }
Ejemplo n.º 16
0
        public virtual void test_presentValueSensitivity_parity()
        {
            CurrencyParameterSensitivities pvSensiRecLong  = RATE_PROVIDER.parameterSensitivity(PRICER.presentValueSensitivityRates(SWAPTION_REC_LONG, RATE_PROVIDER, HW_PROVIDER).build());
            CurrencyParameterSensitivities pvSensiRecShort = RATE_PROVIDER.parameterSensitivity(PRICER.presentValueSensitivityRates(SWAPTION_REC_SHORT, RATE_PROVIDER, HW_PROVIDER).build());
            CurrencyParameterSensitivities pvSensiPayLong  = RATE_PROVIDER.parameterSensitivity(PRICER.presentValueSensitivityRates(SWAPTION_PAY_LONG, RATE_PROVIDER, HW_PROVIDER).build());
            CurrencyParameterSensitivities pvSensiPayShort = RATE_PROVIDER.parameterSensitivity(PRICER.presentValueSensitivityRates(SWAPTION_PAY_SHORT, RATE_PROVIDER, HW_PROVIDER).build());

            assertTrue(pvSensiRecLong.equalWithTolerance(pvSensiRecShort.multipliedBy(-1d), NOTIONAL * TOL));
            assertTrue(pvSensiPayLong.equalWithTolerance(pvSensiPayShort.multipliedBy(-1d), NOTIONAL * TOL));
            PointSensitivities             expectedPoint = SWAP_PRICER.presentValueSensitivity(RSWAP_PAY, RATE_PROVIDER).build();
            CurrencyParameterSensitivities expected      = RATE_PROVIDER.parameterSensitivity(expectedPoint);

            assertTrue(expected.equalWithTolerance(pvSensiPayLong.combinedWith(pvSensiRecLong.multipliedBy(-1d)), NOTIONAL * TOL));
            assertTrue(expected.equalWithTolerance(pvSensiRecShort.combinedWith(pvSensiPayShort.multipliedBy(-1d)), NOTIONAL * TOL));
        }
        //-------------------------------------------------------------------------
        public CurrencyParameterSensitivities parameterSensitivity(IborRateSensitivity pointSensitivity)
        {
            LocalDate                      fixingStartDate = pointSensitivity.Observation.EffectiveDate;
            LocalDate                      fixingEndDate   = pointSensitivity.Observation.MaturityDate;
            double                         accrualFactor   = pointSensitivity.Observation.YearFraction;
            double                         forwardBar      = pointSensitivity.Sensitivity;
            double                         dfForwardStart  = discountFactors.discountFactor(fixingStartDate);
            double                         dfForwardEnd    = discountFactors.discountFactor(fixingEndDate);
            double                         dfStartBar      = forwardBar / (accrualFactor * dfForwardEnd);
            double                         dfEndBar        = -forwardBar * dfForwardStart / (accrualFactor * dfForwardEnd * dfForwardEnd);
            ZeroRateSensitivity            zrsStart        = discountFactors.zeroRatePointSensitivity(fixingStartDate, pointSensitivity.Currency);
            ZeroRateSensitivity            zrsEnd          = discountFactors.zeroRatePointSensitivity(fixingEndDate, pointSensitivity.Currency);
            CurrencyParameterSensitivities psStart         = discountFactors.parameterSensitivity(zrsStart).multipliedBy(dfStartBar);
            CurrencyParameterSensitivities psEnd           = discountFactors.parameterSensitivity(zrsEnd).multipliedBy(dfEndBar);

            return(psStart.combinedWith(psEnd));
        }
        public CurrencyParameterSensitivities parameterSensitivity(PointSensitivities pointSensitivities)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is FxOptionSensitivity)
                {
                    FxOptionSensitivity pt = (FxOptionSensitivity)point;
                    if (pt.VolatilitiesName.Equals(Name))
                    {
                        sens = sens.combinedWith(parameterSensitivity(pt));
                    }
                }
            }
            return(sens);
        }
        //-------------------------------------------------------------------------
        public CurrencyParameterSensitivities parameterSensitivity(OvernightRateSensitivity pointSensitivity)
        {
            OvernightIndex                 index          = pointSensitivity.Index;
            LocalDate                      startDate      = pointSensitivity.Observation.EffectiveDate;
            LocalDate                      endDate        = pointSensitivity.EndDate;
            double                         accrualFactor  = index.DayCount.yearFraction(startDate, endDate);
            double                         forwardBar     = pointSensitivity.Sensitivity;
            double                         dfForwardStart = discountFactors.discountFactor(startDate);
            double                         dfForwardEnd   = discountFactors.discountFactor(endDate);
            double                         dfStartBar     = forwardBar / (accrualFactor * dfForwardEnd);
            double                         dfEndBar       = -forwardBar * dfForwardStart / (accrualFactor * dfForwardEnd * dfForwardEnd);
            ZeroRateSensitivity            zrsStart       = discountFactors.zeroRatePointSensitivity(startDate, pointSensitivity.Currency);
            ZeroRateSensitivity            zrsEnd         = discountFactors.zeroRatePointSensitivity(endDate, pointSensitivity.Currency);
            CurrencyParameterSensitivities psStart        = discountFactors.parameterSensitivity(zrsStart).multipliedBy(dfStartBar);
            CurrencyParameterSensitivities psEnd          = discountFactors.parameterSensitivity(zrsEnd).multipliedBy(dfEndBar);

            return(psStart.combinedWith(psEnd));
        }
Ejemplo n.º 20
0
        // computes the sensitivity with respect to the curves
        private CurrencyParameterSensitivities sensitivity <T>(ImmutableRatesProvider provider, IDictionary <T, Curve> baseCurves, System.Func <ImmutableRatesProvider, IDictionary <T, Curve>, ImmutableRatesProvider> storeBumpedFn, System.Func <ImmutableRatesProvider, CurrencyAmount> valueFn, CurrencyAmount valueInit)
        {
            CurrencyParameterSensitivities result = CurrencyParameterSensitivities.empty();

            foreach (KeyValuePair <T, Curve> entry in baseCurves.SetOfKeyValuePairs())
            {
                Curve       curve       = entry.Value;
                DoubleArray sensitivity = DoubleArray.of(curve.ParameterCount, i =>
                {
                    Curve dscBumped = curve.withParameter(i, curve.getParameter(i) + shift);
                    IDictionary <T, Curve> mapBumped         = new Dictionary <T, Curve>(baseCurves);
                    mapBumped[entry.Key]                     = dscBumped;
                    ImmutableRatesProvider providerDscBumped = storeBumpedFn(provider, mapBumped);
                    return((valueFn(providerDscBumped).Amount - valueInit.Amount) / shift);
                });
                result = result.combinedWith(curve.createParameterSensitivity(valueInit.Currency, sensitivity));
            }
            return(result);
        }
        public CurrencyParameterSensitivity singleCreditCurveParameterSensitivity(PointSensitivities pointSensitivities, StandardId legalEntityId, Currency currency)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is CreditCurveZeroRateSensitivity)
                {
                    CreditCurveZeroRateSensitivity pt = (CreditCurveZeroRateSensitivity)point;
                    if (pt.LegalEntityId.Equals(legalEntityId) && pt.Currency.Equals(currency))
                    {
                        LegalEntitySurvivalProbabilities factors = survivalProbabilities(pt.LegalEntityId, pt.CurveCurrency);
                        sens = sens.combinedWith(factors.parameterSensitivity(pt));
                    }
                }
            }
            ArgChecker.isTrue(sens.size() == 1, "sensitivity must be unique");
            return(sens.Sensitivities.get(0));
        }
        public CurrencyParameterSensitivity singleDiscountCurveParameterSensitivity(PointSensitivities pointSensitivities, Currency currency)
        {
            CurrencyParameterSensitivities sens = CurrencyParameterSensitivities.empty();

            foreach (PointSensitivity point in pointSensitivities.Sensitivities)
            {
                if (point is ZeroRateSensitivity)
                {
                    ZeroRateSensitivity pt = (ZeroRateSensitivity)point;
                    if (pt.Currency.Equals(currency))
                    {
                        CreditDiscountFactors factors = discountFactors(pt.CurveCurrency);
                        sens = sens.combinedWith(factors.parameterSensitivity(pt));
                    }
                }
            }
            ArgChecker.isTrue(sens.size() == 1, "sensitivity must be unique");
            return(sens.Sensitivities.get(0));
        }
        //-------------------------------------------------------------------------
        public virtual void test_presentValueSensitivity()
        {
            PointSensitivities             point    = OPTION_TRADE_PRICER.presentValueSensitivityRates(OPTION_TRADE, RATE_PROVIDER, VOLS);
            CurrencyParameterSensitivities computed = RATE_PROVIDER.parameterSensitivity(point);
            double futurePrice    = FUTURE_PRICER.price(OPTION_PRODUCT.UnderlyingFuture, RATE_PROVIDER);
            double strike         = OPTION_PRODUCT.StrikePrice;
            double expiryTime     = ACT_365F.relativeYearFraction(VAL_DATE, OPTION_PRODUCT.ExpiryDate);
            double logMoneyness   = Math.Log(strike / futurePrice);
            double logMoneynessUp = Math.Log(strike / (futurePrice + EPS));
            double logMoneynessDw = Math.Log(strike / (futurePrice - EPS));
            double vol            = SURFACE.zValue(expiryTime, logMoneyness);
            double volUp          = SURFACE.zValue(expiryTime, logMoneynessUp);
            double volDw          = SURFACE.zValue(expiryTime, logMoneynessDw);
            double volSensi       = 0.5 * (volUp - volDw) / EPS;
            double vega           = BlackFormulaRepository.vega(futurePrice, strike, expiryTime, vol);
            CurrencyParameterSensitivities sensiVol = RATE_PROVIDER.parameterSensitivity(FUTURE_PRICER.priceSensitivity(OPTION_PRODUCT.UnderlyingFuture, RATE_PROVIDER)).multipliedBy(-vega * volSensi * NOTIONAL * QUANTITY);
            CurrencyParameterSensitivities expected = FD_CAL.sensitivity(RATE_PROVIDER, (p) => OPTION_TRADE_PRICER.presentValue(OPTION_TRADE, (p), VOLS, REFERENCE_PRICE));

            assertTrue(computed.equalWithTolerance(expected.combinedWith(sensiVol), 30d * EPS * NOTIONAL * QUANTITY));
        }
        public virtual void test_presentValueSensitivityRatesStickyStrike_parity()
        {
            CurrencyParameterSensitivities pvSensiRecLong  = RATE_PROVIDER.parameterSensitivity(PRICER_SWAPTION.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_LONG, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiRecShort = RATE_PROVIDER.parameterSensitivity(PRICER_SWAPTION.presentValueSensitivityRatesStickyStrike(SWAPTION_REC_SHORT, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiPayLong  = RATE_PROVIDER.parameterSensitivity(PRICER_SWAPTION.presentValueSensitivityRatesStickyStrike(SWAPTION_PAY_LONG, RATE_PROVIDER, VOLS).build());
            CurrencyParameterSensitivities pvSensiPayShort = RATE_PROVIDER.parameterSensitivity(PRICER_SWAPTION.presentValueSensitivityRatesStickyStrike(SWAPTION_PAY_SHORT, RATE_PROVIDER, VOLS).build());

            assertTrue(pvSensiRecLong.equalWithTolerance(pvSensiRecShort.multipliedBy(-1d), NOTIONAL * TOL));
            assertTrue(pvSensiPayLong.equalWithTolerance(pvSensiPayShort.multipliedBy(-1d), NOTIONAL * TOL));

            double forward = PRICER_SWAP.parRate(RSWAP_REC, RATE_PROVIDER);
            PointSensitivityBuilder forwardSensi = PRICER_SWAP.parRateSensitivity(RSWAP_REC, RATE_PROVIDER);
            double annuityCash      = PRICER_SWAP.LegPricer.annuityCash(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), forward);
            double annuityCashDeriv = PRICER_SWAP.LegPricer.annuityCashDerivative(RSWAP_REC.getLegs(SwapLegType.FIXED).get(0), forward).getDerivative(0);
            double discount         = RATE_PROVIDER.discountFactor(USD, SETTLE_DATE);
            PointSensitivityBuilder        discountSensi = RATE_PROVIDER.discountFactors(USD).zeroRatePointSensitivity(SETTLE_DATE);
            PointSensitivities             expecedPoint  = discountSensi.multipliedBy(annuityCash * (forward - STRIKE)).combinedWith(forwardSensi.multipliedBy(discount * annuityCash + discount * annuityCashDeriv * (forward - STRIKE))).build();
            CurrencyParameterSensitivities expected      = RATE_PROVIDER.parameterSensitivity(expecedPoint);

            assertTrue(expected.equalWithTolerance(pvSensiPayLong.combinedWith(pvSensiRecLong.multipliedBy(-1d)), NOTIONAL * TOL));
            assertTrue(expected.equalWithTolerance(pvSensiRecShort.combinedWith(pvSensiPayShort.multipliedBy(-1d)), NOTIONAL * TOL));
        }
        public virtual void regressionPvSurfaceSensi()
        {
            PointSensitivities pointComputed = SWAPTION_PRICER.presentValueSensitivityModelParamsSabr(SWAPTION_PAY_LONG, RATE_PROVIDER, VOLS_REGRESSION).build();

            assertSensitivity(pointComputed, SabrParameterType.ALPHA, 6.5786313367554754E7, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.BETA, -1.2044275797229866E7, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.RHO, 266223.51118849067, REGRESSION_TOL);
            assertSensitivity(pointComputed, SabrParameterType.NU, 400285.5505271345, REGRESSION_TOL);
            CurrencyParameterSensitivities sensiComputed = VOLS_REGRESSION.parameterSensitivity(pointComputed);

            double[][] alphaExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 6204.475194599179 },
                new double[] { 2.0, 5.0, 3.94631212984123E7 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 4136.961894403858 },
                new double[] { 2.0, 10.0, 2.631285063205345E7 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][] betaExp = new double[][]
            {
                new double[] { 0.0, 1.0, -0.0 },
                new double[] { 0.5, 1.0, -0.0 },
                new double[] { 1.0, 1.0, -0.0 },
                new double[] { 2.0, 1.0, -0.0 },
                new double[] { 5.0, 1.0, -0.0 },
                new double[] { 10.0, 1.0, -0.0 },
                new double[] { 0.0, 5.0, -0.0 },
                new double[] { 0.5, 5.0, -0.0 },
                new double[] { 1.0, 5.0, -1135.926404680998 },
                new double[] { 2.0, 5.0, -7224978.759366533 },
                new double[] { 5.0, 5.0, -0.0 },
                new double[] { 10.0, 5.0, -0.0 },
                new double[] { 0.0, 10.0, -0.0 },
                new double[] { 0.5, 10.0, -0.0 },
                new double[] { 1.0, 10.0, -757.402375482629 },
                new double[] { 2.0, 10.0, -4817403.70908317 },
                new double[] { 5.0, 10.0, -0.0 },
                new double[] { 10.0, 10.0, -0.0 }
            };
            double[][] rhoExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 25.10821912392996 },
                new double[] { 2.0, 5.0, 159699.03429338703 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 16.741423326578513 },
                new double[] { 2.0, 10.0, 106482.62725265314 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][] nuExp = new double[][]
            {
                new double[] { 0.0, 1.0, 0.0 },
                new double[] { 0.5, 1.0, 0.0 },
                new double[] { 1.0, 1.0, 0.0 },
                new double[] { 2.0, 1.0, 0.0 },
                new double[] { 5.0, 1.0, 0.0 },
                new double[] { 10.0, 1.0, 0.0 },
                new double[] { 0.0, 5.0, 0.0 },
                new double[] { 0.5, 5.0, 0.0 },
                new double[] { 1.0, 5.0, 37.751952372314484 },
                new double[] { 2.0, 5.0, 240118.59649585965 },
                new double[] { 5.0, 5.0, 0.0 },
                new double[] { 10.0, 5.0, 0.0 },
                new double[] { 0.0, 10.0, 0.0 },
                new double[] { 0.5, 10.0, 0.0 },
                new double[] { 1.0, 10.0, 25.171893432592533 },
                new double[] { 2.0, 10.0, 160104.03018547 },
                new double[] { 5.0, 10.0, 0.0 },
                new double[] { 10.0, 10.0, 0.0 }
            };
            double[][][]      exps     = new double[][][] { alphaExp, betaExp, rhoExp, nuExp };
            SurfaceMetadata[] metadata = new SurfaceMetadata[] { SwaptionSabrRateVolatilityDataSet.META_ALPHA, SwaptionSabrRateVolatilityDataSet.META_BETA_USD, SwaptionSabrRateVolatilityDataSet.META_RHO, SwaptionSabrRateVolatilityDataSet.META_NU };
            // x-y-value order does not match sorted order in surface, thus sort it
            CurrencyParameterSensitivities sensiExpected = CurrencyParameterSensitivities.empty();

            for (int i = 0; i < exps.Length; ++i)
            {
                int size = exps[i].Length;
                IDictionary <DoublesPair, double> sensiMap = new SortedDictionary <DoublesPair, double>();
                for (int j = 0; j < size; ++j)
                {
                    sensiMap[DoublesPair.of(exps[i][j][0], exps[i][j][1])] = exps[i][j][2];
                }
                IList <ParameterMetadata> paramMetadata = new List <ParameterMetadata>(size);
                IList <double>            sensi         = new List <double>();
                foreach (KeyValuePair <DoublesPair, double> entry in sensiMap.SetOfKeyValuePairs())
                {
                    paramMetadata.Add(SwaptionSurfaceExpiryTenorParameterMetadata.of(entry.Key.First, entry.Key.Second));
                    sensi.Add(entry.Value);
                }
                SurfaceMetadata surfaceMetadata = metadata[i].withParameterMetadata(paramMetadata);
                sensiExpected = sensiExpected.combinedWith(CurrencyParameterSensitivity.of(surfaceMetadata.SurfaceName, surfaceMetadata.ParameterMetadata.get(), USD, DoubleArray.copyOf(sensi)));
            }
            testSurfaceParameterSensitivities(sensiComputed, sensiExpected, REGRESSION_TOL * NOTIONAL);
        }