//-------------------------------------------------------------------------
        public virtual void explainPresentValue(KnownAmountSwapPaymentPeriod period, RatesProvider provider, ExplainMapBuilder builder)
        {
            Currency  currency    = period.Currency;
            LocalDate paymentDate = period.PaymentDate;

            builder.put(ExplainKey.ENTRY_TYPE, "KnownAmountPaymentPeriod");
            builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.START_DATE, period.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, period.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(period.StartDate, period.EndDate));
            if (paymentDate.isBefore(provider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate));
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, provider)));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(period, provider)));
            }
        }
コード例 #2
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Explains the present value of the FRA product.
        /// <para>
        /// This returns explanatory information about the calculation.
        ///
        /// </para>
        /// </summary>
        /// <param name="fra">  the FRA product for which present value should be computed </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the explanatory information </returns>
        public virtual ExplainMap explainPresentValue(ResolvedFra fra, RatesProvider provider)
        {
            ExplainMapBuilder builder  = ExplainMap.builder();
            Currency          currency = fra.Currency;

            builder.put(ExplainKey.ENTRY_TYPE, "FRA");
            builder.put(ExplainKey.PAYMENT_DATE, fra.PaymentDate);
            builder.put(ExplainKey.START_DATE, fra.StartDate);
            builder.put(ExplainKey.END_DATE, fra.EndDate);
            builder.put(ExplainKey.ACCRUAL_YEAR_FRACTION, fra.YearFraction);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(fra.StartDate, fra.EndDate));
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.NOTIONAL, CurrencyAmount.of(currency, fra.Notional));
            builder.put(ExplainKey.TRADE_NOTIONAL, CurrencyAmount.of(currency, fra.Notional));
            if (fra.PaymentDate.isBefore(provider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                double rate = rateComputationFn.explainRate(fra.FloatingRate, fra.StartDate, fra.EndDate, provider, builder);
                builder.put(ExplainKey.FIXED_RATE, fra.FixedRate);
                builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, fra.PaymentDate));
                builder.put(ExplainKey.PAY_OFF_RATE, rate);
                builder.put(ExplainKey.UNIT_AMOUNT, unitAmount(fra, provider));
                builder.put(ExplainKey.FORECAST_VALUE, forecastValue(fra, provider));
                builder.put(ExplainKey.PRESENT_VALUE, presentValue(fra, provider));
            }
            return(builder.build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to the SABR model parameters of the swaption product.
        /// <para>
        /// The sensitivity of the present value to the SABR model parameters, alpha, beta, rho and nu.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the swaption product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="swaptionVolatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the SABR model parameters </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityModelParamsSabr(ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities)
        {
            validate(swaption, ratesProvider, swaptionVolatilities);
            double          expiry     = swaptionVolatilities.relativeTime(swaption.Expiry);
            ResolvedSwap    underlying = swaption.Underlying;
            ResolvedSwapLeg fixedLeg   = this.fixedLeg(underlying);
            double          tenor      = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate);
            double          shift      = swaptionVolatilities.shift(expiry, tenor);
            double          strike     = calculateStrike(fixedLeg);

            if (expiry < 0d)
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            double      forward    = SwapPricer.parRate(underlying, ratesProvider);
            double      volatility = swaptionVolatilities.volatility(expiry, tenor, strike, forward);
            double      numeraire  = calculateNumeraire(swaption, fixedLeg, forward, ratesProvider);
            DoubleArray derivative = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward).Derivatives;
            double      vega       = numeraire * swaption.LongShort.sign() * BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility);
            // sensitivities
            Currency ccy = fixedLeg.Currency;
            SwaptionVolatilitiesName name = swaptionVolatilities.Name;

            return(PointSensitivityBuilder.of(SwaptionSabrSensitivity.of(name, expiry, tenor, ALPHA, ccy, vega * derivative.get(2)), SwaptionSabrSensitivity.of(name, expiry, tenor, BETA, ccy, vega * derivative.get(3)), SwaptionSabrSensitivity.of(name, expiry, tenor, RHO, ccy, vega * derivative.get(4)), SwaptionSabrSensitivity.of(name, expiry, tenor, NU, ccy, vega * derivative.get(5))));
        }
        //-------------------------------------------------------------------------
        public virtual void explainPresentValue(FxResetNotionalExchange @event, RatesProvider provider, ExplainMapBuilder builder)
        {
            Currency  currency    = @event.Currency;
            LocalDate paymentDate = @event.PaymentDate;

            builder.put(ExplainKey.ENTRY_TYPE, "FxResetNotionalExchange");
            builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.TRADE_NOTIONAL, @event.NotionalAmount);
            if (paymentDate.isBefore(provider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                builder.addListEntry(ExplainKey.OBSERVATIONS, child =>
                {
                    child.put(ExplainKey.ENTRY_TYPE, "FxObservation");
                    child.put(ExplainKey.INDEX, @event.Observation.Index);
                    child.put(ExplainKey.FIXING_DATE, @event.Observation.FixingDate);
                    child.put(ExplainKey.INDEX_VALUE, fxRate(@event, provider));
                });
                builder.put(ExplainKey.DISCOUNT_FACTOR, provider.discountFactor(currency, paymentDate));
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(@event, provider)));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValue(@event, provider)));
            }
        }
コード例 #5
0
        /// <summary>
        /// Calculates the present value of the fixed coupon bond trade with z-spread from the
        /// clean price of the underlying product.
        /// <para>
        /// The present value of the trade is the value on the valuation date.
        /// The result is expressed using the payment currency of the bond.
        /// </para>
        /// <para>
        /// The z-spread is a parallel shift applied to continuously compounded rates or periodic
        /// compounded rates of the discounting curve.
        /// </para>
        /// <para>
        /// Coupon payments of the underlying product are considered based on the settlement date of the trade.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="provider">  the discounting provider </param>
        /// <param name="refData">  the reference data used to calculate the settlement date </param>
        /// <param name="cleanPrice">  the clean price </param>
        /// <param name="zSpread">  the z-spread </param>
        /// <param name="compoundedRateType">  the compounded rate type </param>
        /// <param name="periodsPerYear">  the number of periods per year </param>
        /// <returns> the present value of the fixed coupon bond trade </returns>
        public virtual CurrencyAmount presentValueFromCleanPriceWithZSpread(ResolvedFixedCouponBondTrade trade, LegalEntityDiscountingProvider provider, ReferenceData refData, double cleanPrice, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear)
        {
            ResolvedFixedCouponBond product  = trade.Product;
            LocalDate standardSettlementDate = this.standardSettlementDate(product, provider, refData);
            LocalDate tradeSettlementDate    = settlementDate(trade, provider.ValuationDate);
            Currency  currency = product.Currency;
            RepoCurveDiscountFactors repoDf = DiscountingFixedCouponBondProductPricer.repoCurveDf(product, provider);
            double df         = repoDf.discountFactor(standardSettlementDate);
            double pvStandard = (cleanPrice * product.Notional + productPricer.accruedInterest(product, standardSettlementDate)) * df;

            if (standardSettlementDate.isEqual(tradeSettlementDate))
            {
                return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard)));
            }
            // check coupon payment between two settlement dates
            IssuerCurveDiscountFactors issuerDf = DiscountingFixedCouponBondProductPricer.issuerCurveDf(product, provider);
            double pvDiff = 0d;

            if (standardSettlementDate.isAfter(tradeSettlementDate))
            {
                pvDiff = productPricer.presentValueCouponWithZSpread(product, issuerDf, tradeSettlementDate, standardSettlementDate, zSpread, compoundedRateType, periodsPerYear);
            }
            else
            {
                pvDiff = -productPricer.presentValueCouponWithZSpread(product, issuerDf, standardSettlementDate, tradeSettlementDate, zSpread, compoundedRateType, periodsPerYear);
            }
            return(presentValueFromProductPresentValue(trade, provider, CurrencyAmount.of(currency, pvStandard + pvDiff)));
        }
        /// <summary>
        /// Calibrate trinomial tree to Black volatilities.
        /// <para>
        /// {@code timeToExpiry} determines the coverage of the resulting trinomial tree.
        /// Thus this should match the time to expiry of the target instrument to price using the calibrated tree.
        ///
        /// </para>
        /// </summary>
        /// <param name="timeToExpiry">  the time to expiry </param>
        /// <param name="currencyPair">  the currency pair </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="volatilities">  the Black volatility provider </param>
        /// <returns> the trinomial tree data </returns>
        public virtual RecombiningTrinomialTreeData calibrateTrinomialTree(double timeToExpiry, CurrencyPair currencyPair, RatesProvider ratesProvider, BlackFxOptionVolatilities volatilities)
        {
            validate(ratesProvider, volatilities);
            if (timeToExpiry <= 0d)
            {
                throw new System.ArgumentException("option expired");
            }
            Currency        ccyBase                = currencyPair.Base;
            Currency        ccyCounter             = currencyPair.Counter;
            double          todayFx                = ratesProvider.fxRate(currencyPair);
            DiscountFactors baseDiscountFactors    = ratesProvider.discountFactors(ccyBase);
            DiscountFactors counterDiscountFactors = ratesProvider.discountFactors(ccyCounter);

            System.Func <double, double> interestRate = (double?t) =>
            {
                return(counterDiscountFactors.zeroRate(t.Value));
            };
            System.Func <double, double> dividendRate = (double?t) =>
            {
                return(baseDiscountFactors.zeroRate(t.Value));
            };
            System.Func <DoublesPair, double> impliedVolSurface = (DoublesPair tk) =>
            {
                double dfBase    = baseDiscountFactors.discountFactor(tk.First);
                double dfCounter = counterDiscountFactors.discountFactor(tk.First);
                double forward   = todayFx * dfBase / dfCounter;
                return(volatilities.volatility(currencyPair, tk.First, tk.Second, forward));
            };
            ImpliedTrinomialTreeLocalVolatilityCalculator localVol = new ImpliedTrinomialTreeLocalVolatilityCalculator(nSteps, timeToExpiry);

            return(localVol.calibrateImpliedVolatility(impliedVolSurface, todayFx, interestRate, dividendRate));
        }
コード例 #7
0
        /// <summary>
        /// Explains the present value of a single payment period with z-spread.
        /// <para>
        /// This adds information to the <seealso cref="ExplainMapBuilder"/> to aid understanding of the calculation.
        ///
        /// </para>
        /// </summary>
        /// <param name="period">  the period to price </param>
        /// <param name="ratesProvider">  the rates provider, used to determine price index values </param>
        /// <param name="issuerDiscountFactors">  the discount factor provider </param>
        /// <param name="zSpread">  the z-spread </param>
        /// <param name="compoundedRateType">  the compounded rate type </param>
        /// <param name="periodsPerYear">  the number of periods per year </param>
        /// <param name="builder">  the builder to populate </param>
        public virtual void explainPresentValueWithZSpread(CapitalIndexedBondPaymentPeriod period, RatesProvider ratesProvider, IssuerCurveDiscountFactors issuerDiscountFactors, ExplainMapBuilder builder, double zSpread, CompoundedRateType compoundedRateType, int periodsPerYear)
        {
            Currency  currency    = period.Currency;
            LocalDate paymentDate = period.PaymentDate;

            builder.put(ExplainKey.ENTRY_TYPE, "CapitalIndexedBondPaymentPeriod");
            builder.put(ExplainKey.PAYMENT_DATE, paymentDate);
            builder.put(ExplainKey.PAYMENT_CURRENCY, currency);
            builder.put(ExplainKey.START_DATE, period.StartDate);
            builder.put(ExplainKey.UNADJUSTED_START_DATE, period.UnadjustedStartDate);
            builder.put(ExplainKey.END_DATE, period.EndDate);
            builder.put(ExplainKey.UNADJUSTED_END_DATE, period.UnadjustedEndDate);
            builder.put(ExplainKey.DAYS, (int)DAYS.between(period.UnadjustedStartDate, period.UnadjustedEndDate));
            if (paymentDate.isBefore(ratesProvider.ValuationDate))
            {
                builder.put(ExplainKey.COMPLETED, true);
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.zero(currency));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.zero(currency));
            }
            else
            {
                builder.put(ExplainKey.DISCOUNT_FACTOR, issuerDiscountFactors.discountFactor(paymentDate));
                builder.put(ExplainKey.FORECAST_VALUE, CurrencyAmount.of(currency, forecastValue(period, ratesProvider)));
                builder.put(ExplainKey.PRESENT_VALUE, CurrencyAmount.of(currency, presentValueWithZSpread(period, ratesProvider, issuerDiscountFactors, zSpread, compoundedRateType, periodsPerYear)));
            }
        }
コード例 #8
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the forward exchange rate.
        /// </summary>
        /// <param name="ndf">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the forward rate </returns>
        public virtual FxRate forwardFxRate(ResolvedFxNdf ndf, RatesProvider provider)
        {
            Currency ccySettle   = ndf.SettlementCurrency;
            Currency ccyOther    = ndf.NonDeliverableCurrency;
            double   forwardRate = provider.fxIndexRates(ndf.Index).rate(ndf.Observation, ccySettle);

            return(FxRate.of(ccySettle, ccyOther, forwardRate));
        }
コード例 #9
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price of the deliverable swap futures product.
        /// <para>
        /// The price of the product is the price on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the price of the product, in decimal form </returns>
        public double price(ResolvedDsf future, RatesProvider ratesProvider)
        {
            ResolvedSwap   swap     = future.UnderlyingSwap;
            Currency       currency = future.Currency;
            CurrencyAmount pvSwap   = swapPricer.presentValue(swap, currency, ratesProvider);
            double         df       = ratesProvider.discountFactor(currency, future.DeliveryDate);

            return(1d + pvSwap.Amount / df);
        }
コード例 #10
0
 /// <summary>
 /// Assert that the {@code CurrencyAmount} is of the expected currency.
 /// </summary>
 /// <param name="ccy">  the expected currency </param>
 /// <returns> this if the currency matches the expectation, else
 ///   throw an {@code AssertionError} </returns>
 public virtual CurrencyAmountAssert hasCurrency(Currency ccy)
 {
     NotNull;
     if (!actual.Currency.Equals(ccy))
     {
         failWithMessage("Expected CurrencyAmount with currency: <%s> but was: <%s>", ccy, actual.Currency);
     }
     return(this);
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the deposit fair rate given the start and end time and the accrual factor.
        /// <para>
        /// When the deposit has already started the number may not be meaningful as the remaining period
        /// is not in line with the accrual factor.
        ///
        /// </para>
        /// </summary>
        /// <param name="deposit">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the par rate </returns>
        public virtual double parRate(ResolvedTermDeposit deposit, RatesProvider provider)
        {
            Currency        currency        = deposit.Currency;
            DiscountFactors discountFactors = provider.discountFactors(currency);
            double          dfStart         = discountFactors.discountFactor(deposit.StartDate);
            double          dfEnd           = discountFactors.discountFactor(deposit.EndDate);
            double          accrualFactor   = deposit.YearFraction;

            return((dfStart / dfEnd - 1d) / accrualFactor);
        }
コード例 #12
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the price sensitivity of the deliverable swap futures product.
        /// <para>
        /// The price sensitivity of the product is the sensitivity of the price to the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="future">  the future </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the price curve sensitivity of the product </returns>
        public PointSensitivities priceSensitivity(ResolvedDsf future, RatesProvider ratesProvider)
        {
            ResolvedSwap            swap        = future.UnderlyingSwap;
            Currency                currency    = future.Currency;
            double                  pvSwap      = swapPricer.presentValue(swap, currency, ratesProvider).Amount;
            double                  dfInv       = 1d / ratesProvider.discountFactor(currency, future.DeliveryDate);
            PointSensitivityBuilder sensiSwapPv = swapPricer.presentValueSensitivity(swap, ratesProvider).multipliedBy(dfInv);
            PointSensitivityBuilder sensiDf     = ratesProvider.discountFactors(currency).zeroRatePointSensitivity(future.DeliveryDate).multipliedBy(-pvSwap * dfInv * dfInv);

            return(sensiSwapPv.combinedWith(sensiDf).build());
        }
        public virtual void test_of_withSensitivityCurrency()
        {
            Currency sensiCurrency = GBP;
            IssuerCurveZeroRateSensitivity test = IssuerCurveZeroRateSensitivity.of(CURRENCY, YEARFRAC, sensiCurrency, GROUP, VALUE);

            assertEquals(test.LegalEntityGroup, GROUP);
            assertEquals(test.CurveCurrency, CURRENCY);
            assertEquals(test.Currency, sensiCurrency);
            assertEquals(test.YearFraction, YEARFRAC);
            assertEquals(test.Sensitivity, VALUE);
        }
コード例 #14
0
        // computes the sensitivity of the payment period to the rate observations (not to the discount factors)
        private PointSensitivityBuilder unitNotionalSensitivityNoCompounding(RatePaymentPeriod period, RatesProvider provider)
        {
            Currency ccy = period.Currency;
            PointSensitivityBuilder sensi = PointSensitivityBuilder.none();

            foreach (RateAccrualPeriod accrualPeriod in period.AccrualPeriods)
            {
                sensi = sensi.combinedWith(unitNotionalSensitivityAccrual(accrualPeriod, ccy, provider));
            }
            return(sensi);
        }
        /// <summary>
        /// Calculates the par spread curve sensitivity.
        /// <para>
        /// The calculation is based on both of initial and final payments.
        /// Thus the number resulting may not be meaningful when deposit has already started and only the final
        /// payment remains (no initial payment).
        ///
        /// </para>
        /// </summary>
        /// <param name="deposit">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the par spread curve sensitivity </returns>
        public virtual PointSensitivities parSpreadSensitivity(ResolvedTermDeposit deposit, RatesProvider provider)
        {
            Currency                currency         = deposit.Currency;
            double                  accrualFactorInv = 1d / deposit.YearFraction;
            double                  dfStart          = provider.discountFactor(currency, deposit.StartDate);
            double                  dfEndInv         = 1d / provider.discountFactor(currency, deposit.EndDate);
            DiscountFactors         discountFactors  = provider.discountFactors(currency);
            PointSensitivityBuilder sensStart        = discountFactors.zeroRatePointSensitivity(deposit.StartDate).multipliedBy(dfEndInv * accrualFactorInv);
            PointSensitivityBuilder sensEnd          = discountFactors.zeroRatePointSensitivity(deposit.EndDate).multipliedBy(-dfStart * dfEndInv * dfEndInv * accrualFactorInv);

            return(sensStart.combinedWith(sensEnd).build());
        }
コード例 #16
0
        public virtual void test_of_zeroRateSensitivity()
        {
            Currency                     sensiCurrency = GBP;
            ZeroRateSensitivity          zeroSensi     = ZeroRateSensitivity.of(CURRENCY, YEARFRAC, sensiCurrency, VALUE);
            RepoCurveZeroRateSensitivity test          = RepoCurveZeroRateSensitivity.of(zeroSensi, GROUP);

            assertEquals(test.RepoGroup, GROUP);
            assertEquals(test.CurveCurrency, CURRENCY);
            assertEquals(test.Currency, sensiCurrency);
            assertEquals(test.YearFraction, YEARFRAC);
            assertEquals(test.Sensitivity, VALUE);
        }
コード例 #17
0
        public virtual void test_legInitialNotional()
        {
            ResolvedSwapLeg   firstLeg           = SWAP_TRADE.Product.Legs.get(0);
            ResolvedSwapLeg   secondLeg          = SWAP_TRADE.Product.Legs.get(1);
            Currency          ccy                = firstLeg.Currency;
            RatePaymentPeriod firstPaymentPeriod = (RatePaymentPeriod)firstLeg.PaymentPeriods.get(0);
            double            notional           = firstPaymentPeriod.Notional;

            LegAmounts expected = LegAmounts.of(SwapLegAmount.of(firstLeg, CurrencyAmount.of(ccy, notional)), SwapLegAmount.of(secondLeg, CurrencyAmount.of(ccy, notional)));

            assertEquals(SwapMeasureCalculations.DEFAULT.legInitialNotional(SWAP_TRADE), expected);
        }
        /// <summary>
        /// Calculates the present value sensitivity by discounting the final cash flow (nominal + interest)
        /// and the initial payment (initial amount).
        /// </summary>
        /// <param name="deposit">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the point sensitivity of the present value </returns>
        public virtual PointSensitivities presentValueSensitivity(ResolvedTermDeposit deposit, RatesProvider provider)
        {
            Currency currency = deposit.Currency;
            // backward sweep
            double dfEndBar   = deposit.Notional + deposit.Interest;
            double dfStartBar = -initialAmount(deposit, provider);
            // sensitivity
            DiscountFactors         discountFactors = provider.discountFactors(currency);
            PointSensitivityBuilder sensStart       = discountFactors.zeroRatePointSensitivity(deposit.StartDate).multipliedBy(dfStartBar);
            PointSensitivityBuilder sensEnd         = discountFactors.zeroRatePointSensitivity(deposit.EndDate).multipliedBy(dfEndBar);

            return(sensStart.combinedWith(sensEnd).build());
        }
コード例 #19
0
        /// <summary>
        /// Calculates the current cash of the NDF product.
        /// </summary>
        /// <param name="ndf">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the current cash of the product in the settlement currency </returns>
        public virtual CurrencyAmount currentCash(ResolvedFxNdf ndf, RatesProvider provider)
        {
            Currency ccySettle = ndf.SettlementCurrency;

            if (provider.ValuationDate.isEqual(ndf.PaymentDate))
            {
                Currency       ccyOther       = ndf.NonDeliverableCurrency;
                CurrencyAmount notionalSettle = ndf.SettlementCurrencyNotional;
                double         agreedRate     = ndf.AgreedFxRate.fxRate(ccySettle, ccyOther);
                double         rate           = provider.fxIndexRates(ndf.Index).rate(ndf.Observation, ccySettle);
                return(notionalSettle.multipliedBy(1d - agreedRate / rate));
            }
            return(CurrencyAmount.zero(ccySettle));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the Ibor fixing deposit product.
        /// <para>
        /// The present value of the product is the value on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="deposit">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value of the product </returns>
        public virtual CurrencyAmount presentValue(ResolvedIborFixingDeposit deposit, RatesProvider provider)
        {
            Currency currency = deposit.Currency;

            if (provider.ValuationDate.isAfter(deposit.EndDate))
            {
                return(CurrencyAmount.of(currency, 0.0d));
            }
            double forwardRate    = this.forwardRate(deposit, provider);
            double discountFactor = provider.discountFactor(currency, deposit.EndDate);
            double fv             = deposit.Notional * deposit.YearFraction * (deposit.FixedRate - forwardRate);
            double pv             = discountFactor * fv;

            return(CurrencyAmount.of(currency, pv));
        }
コード例 #21
0
        //-------------------------------------------------------------------------
        public virtual PointSensitivityBuilder presentValueSensitivity(RatePaymentPeriod period, RatesProvider provider)
        {
            Currency                ccy             = period.Currency;
            DiscountFactors         discountFactors = provider.discountFactors(ccy);
            LocalDate               paymentDate     = period.PaymentDate;
            double                  df = discountFactors.discountFactor(paymentDate);
            PointSensitivityBuilder forecastSensitivity = forecastValueSensitivity(period, provider);

            forecastSensitivity = forecastSensitivity.multipliedBy(df);
            double forecastValue = this.forecastValue(period, provider);
            PointSensitivityBuilder dscSensitivity = discountFactors.zeroRatePointSensitivity(paymentDate);

            dscSensitivity = dscSensitivity.multipliedBy(forecastValue);
            return(forecastSensitivity.combinedWith(dscSensitivity));
        }
コード例 #22
0
        // convention-based
        // ideally we'd use the trade date plus "period to start" to get the spot/payment date
        // but we don't have all the data and it gets complicated in places like TRY, RUB and AED
        private static FxSingleTrade parseConvention(CsvRow row, TradeInfo info)
        {
            CurrencyPair pair        = CurrencyPair.parse(row.getValue(CONVENTION_FIELD));
            BuySell      buySell     = LoaderUtils.parseBuySell(row.getValue(BUY_SELL_FIELD));
            Currency     currency    = Currency.parse(row.getValue(CURRENCY_FIELD));
            double       notional    = LoaderUtils.parseDouble(row.getValue(NOTIONAL_FIELD));
            double       fxRate      = LoaderUtils.parseDouble(row.getValue(FX_RATE_FIELD));
            LocalDate    paymentDate = LoaderUtils.parseDate(row.getValue(PAYMENT_DATE_FIELD));
            Optional <BusinessDayAdjustment> paymentAdj = parsePaymentDateAdjustment(row);

            CurrencyAmount amount = CurrencyAmount.of(currency, buySell.normalize(notional));
            FxSingle       fx     = paymentAdj.map(adj => FxSingle.of(amount, FxRate.of(pair, fxRate), paymentDate, adj)).orElseGet(() => FxSingle.of(amount, FxRate.of(pair, fxRate), paymentDate));

            return(FxSingleTrade.of(info, fx));
        }
コード例 #23
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the currency exposure by discounting each payment in its own currency.
        /// </summary>
        /// <param name="ndf">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the currency exposure </returns>
        public virtual MultiCurrencyAmount currencyExposure(ResolvedFxNdf ndf, RatesProvider provider)
        {
            if (provider.ValuationDate.isAfter(ndf.PaymentDate))
            {
                return(MultiCurrencyAmount.empty());
            }
            Currency       ccySettle      = ndf.SettlementCurrency;
            CurrencyAmount notionalSettle = ndf.SettlementCurrencyNotional;
            double         dfSettle       = provider.discountFactor(ccySettle, ndf.PaymentDate);
            Currency       ccyOther       = ndf.NonDeliverableCurrency;
            double         agreedRate     = ndf.AgreedFxRate.fxRate(ccySettle, ccyOther);
            double         dfOther        = provider.discountFactor(ccyOther, ndf.PaymentDate);

            return(MultiCurrencyAmount.of(notionalSettle.multipliedBy(dfSettle)).plus(CurrencyAmount.of(ccyOther, -notionalSettle.Amount * agreedRate * dfOther)));
        }
コード例 #24
0
        // spread exclusive compounding
        private PointSensitivityBuilder compoundedSpreadExclusiveSensitivity(RatePaymentPeriod paymentPeriod, RatesProvider provider)
        {
            double   notionalAccrued      = 1d;
            Currency ccy                  = paymentPeriod.Currency;
            PointSensitivityBuilder sensi = PointSensitivityBuilder.none();

            foreach (RateAccrualPeriod accrualPeriod in paymentPeriod.AccrualPeriods)
            {
                double investFactor = 1 + unitNotionalAccrual(accrualPeriod, 0, provider);
                notionalAccrued *= investFactor;
                PointSensitivityBuilder investFactorSensi = unitNotionalSensitivityAccrual(accrualPeriod, ccy, provider).multipliedBy(1d / investFactor);
                sensi = sensi.combinedWith(investFactorSensi);
            }
            return(sensi.multipliedBy(notionalAccrued));
        }
コード例 #25
0
        // parses the additional GenericSecurityPosition information
        internal static Position parseNonEtdPosition(CsvRow row, PositionInfo info, PositionCsvInfoResolver resolver)
        {
            SecurityPosition    @base        = parseSecurityPosition(row, info, resolver);
            double?             tickSizeOpt  = row.findValue(TICK_SIZE).map(str => LoaderUtils.parseDouble(str));
            Optional <Currency> currencyOpt  = row.findValue(CURRENCY).map(str => Currency.of(str));
            double?             tickValueOpt = row.findValue(TICK_VALUE).map(str => LoaderUtils.parseDouble(str));
            double              contractSize = row.findValue(CONTRACT_SIZE).map(str => LoaderUtils.parseDouble(str)).orElse(1d);

            if (tickSizeOpt.HasValue && currencyOpt.Present && tickValueOpt.HasValue)
            {
                SecurityPriceInfo priceInfo = SecurityPriceInfo.of(tickSizeOpt.Value, CurrencyAmount.of(currencyOpt.get(), tickValueOpt.Value), contractSize);
                GenericSecurity   sec       = GenericSecurity.of(SecurityInfo.of(@base.SecurityId, priceInfo));
                return(GenericSecurityPosition.ofLongShort(@base.Info, sec, @base.LongQuantity, @base.ShortQuantity));
            }
            return(@base);
        }
コード例 #26
0
 /// <summary>
 /// Get the curve name of the curve for a given currency.
 /// </summary>
 /// <param name="currency"> the currency </param>
 /// <returns> the curve name </returns>
 public static CurveName getCurveName(Currency currency)
 {
     if (currency.Equals(EUR))
     {
         return(EUR_DSC.Name);
     }
     if (currency.Equals(USD))
     {
         return(USD_DSC.Name);
     }
     if (currency.Equals(GBP))
     {
         return(GBP_DSC.Name);
     }
     throw new System.ArgumentException();
 }
コード例 #27
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the NDF product.
        /// <para>
        /// The present value of the product is the value on the valuation date.
        /// The present value is returned in the settlement currency.
        ///
        /// </para>
        /// </summary>
        /// <param name="ndf">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value of the product in the settlement currency </returns>
        public virtual CurrencyAmount presentValue(ResolvedFxNdf ndf, RatesProvider provider)
        {
            Currency ccySettle = ndf.SettlementCurrency;

            if (provider.ValuationDate.isAfter(ndf.PaymentDate))
            {
                return(CurrencyAmount.zero(ccySettle));
            }
            Currency       ccyOther       = ndf.NonDeliverableCurrency;
            CurrencyAmount notionalSettle = ndf.SettlementCurrencyNotional;
            double         agreedRate     = ndf.AgreedFxRate.fxRate(ccySettle, ccyOther);
            double         forwardRate    = provider.fxIndexRates(ndf.Index).rate(ndf.Observation, ccySettle);
            double         dfSettle       = provider.discountFactor(ccySettle, ndf.PaymentDate);

            return(notionalSettle.multipliedBy(dfSettle * (1d - agreedRate / forwardRate)));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value by discounting the final cash flow (nominal + interest)
        /// and the initial payment (initial amount).
        /// <para>
        /// The present value of the product is the value on the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="deposit">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value of the product </returns>
        public virtual CurrencyAmount presentValue(ResolvedTermDeposit deposit, RatesProvider provider)
        {
            Currency currency = deposit.Currency;

            if (provider.ValuationDate.isAfter(deposit.EndDate))
            {
                return(CurrencyAmount.of(currency, 0.0d));
            }
            DiscountFactors discountFactors = provider.discountFactors(currency);
            double          dfStart         = discountFactors.discountFactor(deposit.StartDate);
            double          dfEnd           = discountFactors.discountFactor(deposit.EndDate);
            double          pvStart         = initialAmount(deposit, provider) * dfStart;
            double          pvEnd           = (deposit.Notional + deposit.Interest) * dfEnd;
            double          pv = pvEnd - pvStart;

            return(CurrencyAmount.of(currency, pv));
        }
コード例 #29
0
        // parses a trade from the CSV row
        internal static SecurityQuantityTrade parseTrade(CsvRow row, TradeInfo info, TradeCsvInfoResolver resolver)
        {
            SecurityTrade trade = parseSecurityTrade(row, info, resolver);
            SecurityTrade @base = resolver.completeTrade(row, trade);

            double?tickSizeOpt = row.findValue(TICK_SIZE).map(str => LoaderUtils.parseDouble(str));
            Optional <Currency> currencyOpt = row.findValue(CURRENCY).map(str => Currency.of(str));
            double?tickValueOpt             = row.findValue(TICK_VALUE).map(str => LoaderUtils.parseDouble(str));
            double contractSize             = row.findValue(CONTRACT_SIZE).map(str => LoaderUtils.parseDouble(str)).orElse(1d);

            if (tickSizeOpt.HasValue && currencyOpt.Present && tickValueOpt.HasValue)
            {
                SecurityPriceInfo priceInfo = SecurityPriceInfo.of(tickSizeOpt.Value, CurrencyAmount.of(currencyOpt.get(), tickValueOpt.Value), contractSize);
                GenericSecurity   sec       = GenericSecurity.of(SecurityInfo.of(@base.SecurityId, priceInfo));
                return(GenericSecurityTrade.of(@base.Info, sec, @base.Quantity, @base.Price));
            }
            return(@base);
        }
コード例 #30
0
        // flat compounding
        private PointSensitivityBuilder compoundedFlatSensitivity(RatePaymentPeriod paymentPeriod, RatesProvider provider)
        {
            double   cpaAccumulated = 0d;
            Currency ccy            = paymentPeriod.Currency;
            PointSensitivityBuilder sensiAccumulated = PointSensitivityBuilder.none();

            foreach (RateAccrualPeriod accrualPeriod in paymentPeriod.AccrualPeriods)
            {
                double rate = rawRate(accrualPeriod, provider);
                double accrualZeroSpread        = unitNotionalAccrualRaw(accrualPeriod, rate, 0);
                PointSensitivityBuilder sensiCp = sensiAccumulated.cloned();
                sensiCp = sensiCp.multipliedBy(accrualZeroSpread);
                PointSensitivityBuilder sensi2 = unitNotionalSensitivityAccrual(accrualPeriod, ccy, provider).multipliedBy(1d + cpaAccumulated);
                cpaAccumulated  += cpaAccumulated * accrualZeroSpread + unitNotionalAccrualRaw(accrualPeriod, rate, accrualPeriod.Spread);
                sensiCp          = sensiCp.combinedWith(sensi2);
                sensiAccumulated = sensiAccumulated.combinedWith(sensiCp).normalize();
            }
            return(sensiAccumulated);
        }