/// <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);
        }
Beispiel #2
0
        /// <summary>
        /// Creates an {@code ResolvedFxSingle} using a rate.
        /// <para>
        /// This create an FX specifying a value date, notional in one currency, the second currency
        /// and the FX rate between the two.
        /// The currencies of the payments must differ.
        /// </para>
        /// <para>
        /// This factory identifies the currency pair of the exchange and assigns the payments
        /// to match the base or counter currency of the standardized currency pair.
        /// For example, a EUR/USD exchange always has EUR as the base payment and USD as the counter payment.
        /// </para>
        /// <para>
        /// No payment date adjustments apply.
        ///
        /// </para>
        /// </summary>
        /// <param name="amountCurrency1">  the amount of the near leg in the first currency </param>
        /// <param name="fxRate">  the near FX rate </param>
        /// <param name="paymentDate">  date that the FX settles </param>
        /// <returns> the resolved foreign exchange transaction </returns>
        public static ResolvedFxSingle of(CurrencyAmount amountCurrency1, FxRate fxRate, LocalDate paymentDate)
        {
            CurrencyPair pair = fxRate.Pair;

            ArgChecker.isTrue(pair.contains(amountCurrency1.Currency));
            Currency       currency2       = pair.Base.Equals(amountCurrency1.Currency) ? pair.Counter : pair.Base;
            CurrencyAmount amountCurrency2 = amountCurrency1.convertedTo(currency2, fxRate).negated();

            return(ResolvedFxSingle.of(Payment.of(amountCurrency1, paymentDate), Payment.of(amountCurrency2, paymentDate)));
        }
Beispiel #3
0
        //-------------------------------------------------------------------------
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @ImmutableValidator private void validate()
        private void validate()
        {
            CurrencyPair pair = observation.Index.CurrencyPair;

            if (!pair.contains(settlementCurrencyNotional.Currency))
            {
                throw new System.ArgumentException("FxIndex and settlement notional currency are incompatible");
            }
            if (!(pair.Equals(agreedFxRate.Pair) || pair.isInverse(agreedFxRate.Pair)))
            {
                throw new System.ArgumentException("FxIndex and agreed FX rate are incompatible");
            }
        }
Beispiel #4
0
        // internal method where adjustment may be null
        private static FxSingle create(CurrencyAmount amount, FxRate fxRate, LocalDate paymentDate, BusinessDayAdjustment paymentDateAdjustment)
        {
            ArgChecker.notNull(amount, "amount");
            ArgChecker.notNull(fxRate, "fxRate");
            ArgChecker.notNull(paymentDate, "paymentDate");
            CurrencyPair pair = fxRate.Pair;

            if (!pair.contains(amount.Currency))
            {
                throw new System.ArgumentException(Messages.format("FxRate '{}' and CurrencyAmount '{}' must have a currency in common", fxRate, amount));
            }
            Currency       currency2       = pair.Base.Equals(amount.Currency) ? pair.Counter : pair.Base;
            CurrencyAmount amountCurrency2 = amount.convertedTo(currency2, fxRate).negated();

            return(create(amount, amountCurrency2, paymentDate, paymentDateAdjustment));
        }