예제 #1
0
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case 1574023291:         // securityId
                    this.securityId_Renamed = (SecurityId)newValue;
                    break;

                case 1585636160:         // notional
                    this.notional_Renamed = (double?)newValue.Value;
                    break;

                case 681469378:         // deliveryDate
                    this.deliveryDate_Renamed = (LocalDate)newValue;
                    break;

                case -1041950404:         // lastTradeDate
                    this.lastTradeDate_Renamed = (LocalDate)newValue;
                    break;

                case 1497421456:         // underlyingSwap
                    this.underlyingSwap_Renamed = (ResolvedSwap)newValue;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
예제 #2
0
        /// <summary>
        /// Calculates the present value of the swaption product.
        /// <para>
        /// The result is expressed using the currency of the swapion.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value </returns>
        public virtual CurrencyAmount presentValue(ResolvedSwaption swaption, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            validate(swaption, ratesProvider, hwProvider);
            ResolvedSwap swap       = swaption.Underlying;
            LocalDate    expiryDate = swaption.ExpiryDate;

            if (expiryDate.isBefore(ratesProvider.ValuationDate))
            {     // Option has expired already
                return(CurrencyAmount.of(swap.Legs.get(0).Currency, 0d));
            }
            ResolvedSwapLeg cashFlowEquiv = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, ratesProvider);
            int             nPayments     = cashFlowEquiv.PaymentEvents.size();

            double[] alpha = new double[nPayments];
            double[] discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                NotionalExchange payment      = (NotionalExchange)cashFlowEquiv.PaymentEvents.get(loopcf);
                LocalDate        maturityDate = payment.PaymentDate;
                alpha[loopcf] = hwProvider.alpha(ratesProvider.ValuationDate, expiryDate, expiryDate, maturityDate);
                discountedCashFlow[loopcf] = paymentPricer.presentValueAmount(payment.Payment, ratesProvider);
            }
            double omega = (swap.getLegs(SwapLegType.FIXED).get(0).PayReceive.Pay ? -1d : 1d);
            double kappa = computeKappa(hwProvider, discountedCashFlow, alpha, omega);
            double pv    = 0.0;

            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                pv += discountedCashFlow[loopcf] * NORMAL.getCDF(omega * (kappa + alpha[loopcf]));
            }
            return(CurrencyAmount.of(cashFlowEquiv.Currency, pv * (swaption.LongShort.Long ? 1d : -1d)));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption to the rate curves.
        /// <para>
        /// The present value sensitivity is computed in a "sticky strike" style, i.e. the sensitivity to the
        /// curve nodes with the volatility at the swaption strike unchanged. This sensitivity does not include a potential
        /// change of volatility due to the implicit change of forward rate or moneyness.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the swaption </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="swaptionVolatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyStrike(ResolvedSwaption swaption, RatesProvider ratesProvider, SwaptionVolatilities swaptionVolatilities)
        {
            validate(swaption, ratesProvider, swaptionVolatilities);
            double          expiry     = swaptionVolatilities.relativeTime(swaption.Expiry);
            ResolvedSwap    underlying = swaption.Underlying;
            ResolvedSwapLeg fixedLeg   = this.fixedLeg(underlying);

            if (expiry < 0d)
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            double  forward    = SwapPricer.parRate(underlying, ratesProvider);
            double  pvbp       = SwapPricer.LegPricer.pvbp(fixedLeg, ratesProvider);
            double  strike     = SwapPricer.LegPricer.couponEquivalent(fixedLeg, ratesProvider, pvbp);
            double  tenor      = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate);
            double  volatility = swaptionVolatilities.volatility(expiry, tenor, strike, forward);
            PutCall putCall    = PutCall.ofPut(fixedLeg.PayReceive.Receive);
            double  price      = swaptionVolatilities.price(expiry, tenor, putCall, strike, forward, volatility);
            double  delta      = swaptionVolatilities.priceDelta(expiry, tenor, putCall, strike, forward, volatility);
            // Backward sweep
            PointSensitivityBuilder pvbpDr    = SwapPricer.LegPricer.pvbpSensitivity(fixedLeg, ratesProvider);
            PointSensitivityBuilder forwardDr = SwapPricer.parRateSensitivity(underlying, ratesProvider);
            double sign = swaption.LongShort.sign();

            return(pvbpDr.multipliedBy(price * sign * Math.Sign(pvbp)).combinedWith(forwardDr.multipliedBy(delta * Math.Abs(pvbp) * sign)));
        }
            public override Builder set(string propertyName, object newValue)
            {
                switch (propertyName.GetHashCode())
                {
                case 116685664:         // longShort
                    this.longShort_Renamed = (LongShort)newValue;
                    break;

                case -1937554512:         // swaptionSettlement
                    this.swaptionSettlement_Renamed = (SwaptionSettlement)newValue;
                    break;

                case -1289159373:         // expiry
                    this.expiry_Renamed = (ZonedDateTime)newValue;
                    break;

                case -1770633379:         // underlying
                    this.underlying_Renamed = (ResolvedSwap)newValue;
                    break;

                default:
                    throw new NoSuchElementException("Unknown property: " + propertyName);
                }
                return(this);
            }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption product to the rate curves.
        /// <para>
        /// The present value sensitivity is computed in a "sticky model parameter" style, i.e. the sensitivity to the
        /// curve nodes with the SABR model parameters unchanged. This sensitivity does not include a potential
        /// re-calibration of the model parameters to the raw market data.
        ///
        /// </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 rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyModel(ResolvedSwaption swaption, RatesProvider ratesProvider, SabrSwaptionVolatilities swaptionVolatilities)
        {
            validate(swaption, ratesProvider, swaptionVolatilities);
            ZonedDateTime   expiryDateTime = swaption.Expiry;
            double          expiry         = swaptionVolatilities.relativeTime(expiryDateTime);
            ResolvedSwap    underlying     = swaption.Underlying;
            ResolvedSwapLeg fixedLeg       = this.fixedLeg(underlying);

            if (expiry < 0d)
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            double           forward       = SwapPricer.parRate(underlying, ratesProvider);
            double           pvbp          = SwapPricer.LegPricer.pvbp(fixedLeg, ratesProvider);
            double           strike        = SwapPricer.LegPricer.couponEquivalent(fixedLeg, ratesProvider, pvbp);
            double           tenor         = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate);
            double           shift         = swaptionVolatilities.shift(expiry, tenor);
            ValueDerivatives volatilityAdj = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward);
            bool             isCall        = fixedLeg.PayReceive.Pay;
            // Payer at strike is exercise when rate > strike, i.e. call on rate
            // Backward sweep
            PointSensitivityBuilder pvbpDr    = SwapPricer.LegPricer.pvbpSensitivity(fixedLeg, ratesProvider);
            PointSensitivityBuilder forwardDr = SwapPricer.parRateSensitivity(underlying, ratesProvider);
            double shiftedForward             = forward + shift;
            double shiftedStrike = strike + shift;
            double price         = BlackFormulaRepository.price(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value, isCall);
            double delta         = BlackFormulaRepository.delta(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value, isCall);
            double vega          = BlackFormulaRepository.vega(shiftedForward, shiftedStrike, expiry, volatilityAdj.Value);
            double sign          = swaption.LongShort.sign();

            return(pvbpDr.multipliedBy(price * sign * Math.Sign(pvbp)).combinedWith(forwardDr.multipliedBy((delta + vega * volatilityAdj.getDerivative(0)) * Math.Abs(pvbp) * sign)));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity of the swaption to the rate curves.
        /// <para>
        /// The present value sensitivity is computed in a "sticky strike" style, i.e. the sensitivity to the
        /// curve nodes with the volatility at the swaption strike unchanged. This sensitivity does not include a potential
        /// change of volatility due to the implicit change of forward rate or moneyness.
        ///
        /// </para>
        /// </summary>
        /// <param name="swaption">  the swaption </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="swaptionVolatilities">  the volatilities </param>
        /// <returns> the point sensitivity to the rate curves </returns>
        public virtual PointSensitivityBuilder presentValueSensitivityRatesStickyStrike(ResolvedSwaption swaption, RatesProvider ratesProvider, SwaptionVolatilities swaptionVolatilities)
        {
            validate(swaption, ratesProvider, swaptionVolatilities);
            double          expiry     = swaptionVolatilities.relativeTime(swaption.Expiry);
            ResolvedSwap    underlying = swaption.Underlying;
            ResolvedSwapLeg fixedLeg   = this.fixedLeg(underlying);

            if (expiry < 0d)
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            double           forward           = SwapPricer.parRate(underlying, ratesProvider);
            ValueDerivatives annuityDerivative = SwapPricer.LegPricer.annuityCashDerivative(fixedLeg, forward);
            double           annuityCash       = annuityDerivative.Value;
            double           annuityCashDr     = annuityDerivative.getDerivative(0);
            LocalDate        settlementDate    = ((CashSwaptionSettlement)swaption.SwaptionSettlement).SettlementDate;
            double           discountSettle    = ratesProvider.discountFactor(fixedLeg.Currency, settlementDate);
            double           strike            = calculateStrike(fixedLeg);
            double           tenor             = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate);
            double           volatility        = swaptionVolatilities.volatility(expiry, tenor, strike, forward);
            PutCall          putCall           = PutCall.ofPut(fixedLeg.PayReceive.Receive);
            double           price             = swaptionVolatilities.price(expiry, tenor, putCall, strike, forward, volatility);
            double           delta             = swaptionVolatilities.priceDelta(expiry, tenor, putCall, strike, forward, volatility);
            // Backward sweep
            PointSensitivityBuilder forwardSensi        = SwapPricer.parRateSensitivity(underlying, ratesProvider);
            PointSensitivityBuilder discountSettleSensi = ratesProvider.discountFactors(fixedLeg.Currency).zeroRatePointSensitivity(settlementDate);
            double sign = swaption.LongShort.sign();

            return(forwardSensi.multipliedBy(sign * discountSettle * (annuityCash * delta + annuityCashDr * price)).combinedWith(discountSettleSensi.multipliedBy(sign * annuityCash * price)));
        }
 /// <summary>
 /// Restricted copy constructor. </summary>
 /// <param name="beanToCopy">  the bean to copy from, not null </param>
 internal Builder(ResolvedSwaption beanToCopy)
 {
     this.longShort_Renamed          = beanToCopy.LongShort;
     this.swaptionSettlement_Renamed = beanToCopy.SwaptionSettlement;
     this.expiry_Renamed             = beanToCopy.Expiry;
     this.underlying_Renamed         = beanToCopy.Underlying;
 }
예제 #8
0
        /// <summary>
        /// Calculates the par spread curve sensitivity for a swap.
        /// <para>
        /// The par spread is the common spread on all payments of the first leg for which the total swap present value is 0.
        /// </para>
        /// <para>
        /// The par spread is computed with respect to the first leg. For that leg, all the payments have a unique
        /// accrual period (no compounding) and no FX reset.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the par spread curve sensitivity of the swap product </returns>
        public virtual PointSensitivityBuilder parSpreadSensitivity(ResolvedSwap swap, RatesProvider provider)
        {
            ResolvedSwapLeg         referenceLeg    = swap.Legs.get(0);
            Currency                ccyReferenceLeg = referenceLeg.Currency;
            double                  convertedPv     = presentValue(swap, ccyReferenceLeg, provider).Amount;
            PointSensitivityBuilder convertedPvDr   = presentValueSensitivity(swap, ccyReferenceLeg, provider);
            // try one payment compounding, typically for inflation swaps
            Triple <bool, int, double> fixedCompounded = checkFixedCompounded(referenceLeg);

            if (fixedCompounded.First)
            {
                double df = provider.discountFactor(ccyReferenceLeg, referenceLeg.PaymentPeriods.get(0).PaymentDate);
                PointSensitivityBuilder dfDr = provider.discountFactors(ccyReferenceLeg).zeroRatePointSensitivity(referenceLeg.PaymentPeriods.get(0).PaymentDate);
                double referenceConvertedPv  = legPricer.presentValue(referenceLeg, provider).Amount;
                PointSensitivityBuilder referenceConvertedPvDr = legPricer.presentValueSensitivity(referenceLeg, provider);
                double notional = ((RatePaymentPeriod)referenceLeg.PaymentPeriods.get(0)).Notional;
                PointSensitivityBuilder dParSpreadDr = convertedPvDr.combinedWith(referenceConvertedPvDr.multipliedBy(-1)).multipliedBy(-1.0d / (df * notional)).combinedWith(dfDr.multipliedBy((convertedPv - referenceConvertedPv) / (df * df * notional))).multipliedBy(1.0d / fixedCompounded.Second * Math.Pow(-(convertedPv - referenceConvertedPv) / (df * notional) + 1.0d, 1.0d / fixedCompounded.Second - 1.0d));
                return(dParSpreadDr);
            }
            double pvbp = legPricer.pvbp(referenceLeg, provider);
            // Backward sweep
            double convertedPvBar          = -1d / pvbp;
            double pvbpBar                 = convertedPv / (pvbp * pvbp);
            PointSensitivityBuilder pvbpDr = legPricer.pvbpSensitivity(referenceLeg, provider);

            return(convertedPvDr.multipliedBy(convertedPvBar).combinedWith(pvbpDr.multipliedBy(pvbpBar)));
        }
        //-------------------------------------------------------------------------
        /// <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          pvbp       = SwapPricer.LegPricer.pvbp(fixedLeg, ratesProvider);
            double          strike     = SwapPricer.LegPricer.couponEquivalent(fixedLeg, ratesProvider, pvbp);

            if (expiry < 0d)
            {     // Option has expired already
                return(PointSensitivityBuilder.none());
            }
            double      forward    = SwapPricer.parRate(underlying, ratesProvider);
            double      volatility = swaptionVolatilities.volatility(expiry, tenor, strike, forward);
            DoubleArray derivative = swaptionVolatilities.volatilityAdjoint(expiry, tenor, strike, forward).Derivatives;
            // Backward sweep
            double vega = Math.Abs(pvbp) * BlackFormulaRepository.vega(forward + shift, strike + shift, expiry, volatility) * swaption.LongShort.sign();
            // 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))));
        }
예제 #10
0
 /// <summary>
 /// Restricted copy constructor. </summary>
 /// <param name="beanToCopy">  the bean to copy from, not null </param>
 internal Builder(ResolvedDsf beanToCopy)
 {
     this.securityId_Renamed     = beanToCopy.SecurityId;
     this.notional_Renamed       = beanToCopy.Notional;
     this.deliveryDate_Renamed   = beanToCopy.DeliveryDate;
     this.lastTradeDate_Renamed  = beanToCopy.LastTradeDate;
     this.underlyingSwap_Renamed = beanToCopy.UnderlyingSwap;
 }
예제 #11
0
        /// <summary>
        /// Computes cash flow equivalent of swap.
        /// <para>
        /// The swap should be a fix-for-Ibor swap without compounding, and its swap legs
        /// should not involve {@code PaymentEvent}.
        /// </para>
        /// <para>
        /// The return type is {@code ResolvedSwapLeg} in which individual payments are
        /// represented in terms of {@code NotionalExchange}.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the swap product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <returns> the cash flow equivalent </returns>
        public static ResolvedSwapLeg cashFlowEquivalentSwap(ResolvedSwap swap, RatesProvider ratesProvider)
        {
            validateSwap(swap);
            ResolvedSwapLeg cfFixed = cashFlowEquivalentFixedLeg(swap.getLegs(SwapLegType.FIXED).get(0), ratesProvider);
            ResolvedSwapLeg cfIbor  = cashFlowEquivalentIborLeg(swap.getLegs(SwapLegType.IBOR).get(0), ratesProvider);
            ResolvedSwapLeg leg     = ResolvedSwapLeg.builder().paymentEvents(Stream.concat(cfFixed.PaymentEvents.stream(), cfIbor.PaymentEvents.stream()).collect(Collectors.toList())).payReceive(PayReceive.RECEIVE).type(SwapLegType.OTHER).build();

            return(leg);
        }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes:
//ORIGINAL LINE: @Test(dataProvider = "stubOn") public void test_stub_overnight(OvernightIborSwapConvention convention, com.opengamma.strata.basics.date.Tenor tenor)
        public virtual void test_stub_overnight(OvernightIborSwapConvention convention, Tenor tenor)
        {
            LocalDate    tradeDate    = LocalDate.of(2015, 10, 20);
            SwapTrade    swap         = convention.createTrade(tradeDate, tenor, BuySell.BUY, 1, 0.01, REF_DATA);
            ResolvedSwap swapResolved = swap.Product.resolve(REF_DATA);
            LocalDate    endDate      = swapResolved.getLeg(PayReceive.PAY).get().EndDate;

            assertTrue(endDate.isAfter(tradeDate.plus(tenor).minusDays(7)));
            assertTrue(endDate.isBefore(tradeDate.plus(tenor).plusDays(7)));
        }
예제 #13
0
        //-------------------------------------------------------------------------
        // checking that at least one leg is a fixed leg and returning the first one
        private ResolvedSwapLeg fixedLeg(ResolvedSwap swap)
        {
            IList <ResolvedSwapLeg> fixedLegs = swap.getLegs(SwapLegType.FIXED);

            if (fixedLegs.Count == 0)
            {
                throw new System.ArgumentException("Swap must contain a fixed leg");
            }
            return(fixedLegs[0]);
        }
예제 #14
0
        /// <summary>
        /// Calculates the current cash of the swap product.
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the current cash of the swap product </returns>
        public virtual MultiCurrencyAmount currentCash(ResolvedSwap swap, RatesProvider provider)
        {
            MultiCurrencyAmount ce = MultiCurrencyAmount.empty();

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                ce = ce.plus(legPricer.currentCash(leg, provider));
            }
            return(ce);
        }
예제 #15
0
        // calculate present or forecast value sensitivity for the swap
        private static PointSensitivityBuilder swapValueSensitivity(ResolvedSwap swap, RatesProvider provider, System.Func <ResolvedSwapLeg, RatesProvider, PointSensitivityBuilder> legFn)
        {
            PointSensitivityBuilder builder = PointSensitivityBuilder.none();

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                builder = builder.combinedWith(legFn(leg, provider));
            }
            return(builder);
        }
예제 #16
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the accrued interest since the last payment.
        /// <para>
        /// This determines the payment period applicable at the valuation date and calculates
        /// the accrued interest since the last payment.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the accrued interest of the swap product </returns>
        public virtual MultiCurrencyAmount accruedInterest(ResolvedSwap swap, RatesProvider provider)
        {
            MultiCurrencyAmount result = MultiCurrencyAmount.empty();

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                result = result.plus(legPricer.accruedInterest(leg, provider));
            }
            return(result);
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the present value curve sensitivity by simple forward rate estimation.
        /// </summary>
        /// <param name="cmsPeriod">  the CMS </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value sensitivity </returns>
        public virtual PointSensitivityBuilder presentValueSensitivity(CmsPeriod cmsPeriod, RatesProvider provider)
        {
            Currency  ccy           = cmsPeriod.Currency;
            LocalDate valuationDate = provider.ValuationDate;

            if (valuationDate.isAfter(cmsPeriod.PaymentDate))
            {
                return(PointSensitivityBuilder.none());
            }
            LocalDate fixingDate = cmsPeriod.FixingDate;
            double    dfPayment  = provider.discountFactor(ccy, cmsPeriod.PaymentDate);

            if (!fixingDate.isAfter(valuationDate))
            {     // Using fixing
                double?fixedRate = provider.timeSeries(cmsPeriod.Index).get(fixingDate);
                if (fixedRate.HasValue)
                {
                    double payoff = 0d;
                    switch (cmsPeriod.CmsPeriodType)
                    {
                    case CAPLET:
                        payoff = Math.Max(fixedRate.Value - cmsPeriod.Strike, 0d);
                        break;

                    case FLOORLET:
                        payoff = Math.Max(cmsPeriod.Strike - fixedRate.Value, 0d);
                        break;

                    case COUPON:
                        payoff = fixedRate.Value;
                        break;

                    default:
                        throw new System.ArgumentException("unsupported CMS type");
                    }
                    return(provider.discountFactors(ccy).zeroRatePointSensitivity(cmsPeriod.PaymentDate).multipliedBy(payoff * cmsPeriod.Notional * cmsPeriod.YearFraction));
                }
                else if (fixingDate.isBefore(valuationDate))
                {
                    throw new System.ArgumentException(Messages.format("Unable to get fixing for {} on date {}, no time-series supplied", cmsPeriod.Index, fixingDate));
                }
            }
            if (!cmsPeriod.CmsPeriodType.Equals(CmsPeriodType.COUPON))
            {
                throw new System.ArgumentException("Unable to price cap or floor in this pricer");
            }
            // Using forward
            ResolvedSwap        swap        = cmsPeriod.UnderlyingSwap;
            ZeroRateSensitivity dfPaymentdr = provider.discountFactors(ccy).zeroRatePointSensitivity(cmsPeriod.PaymentDate);
            double forward = swapPricer.parRate(swap, provider);
            PointSensitivityBuilder forwardSensi = swapPricer.parRateSensitivity(swap, provider);

            return(forwardSensi.multipliedBy(dfPayment).combinedWith(dfPaymentdr.multipliedBy(forward)).multipliedBy(cmsPeriod.Notional * cmsPeriod.YearFraction));
        }
예제 #18
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Explains the present value of the swap product.
        /// <para>
        /// This returns explanatory information about the calculation.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the explanatory information </returns>
        public virtual ExplainMap explainPresentValue(ResolvedSwap swap, RatesProvider provider)
        {
            ExplainMapBuilder builder = ExplainMap.builder();

            builder.put(ExplainKey.ENTRY_TYPE, "Swap");
            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                builder.addListEntryWithIndex(ExplainKey.LEGS, child => legPricer.explainPresentValueInternal(leg, provider, child));
            }
            return(builder.build());
        }
예제 #19
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the swap product, converted to the specified currency.
        /// <para>
        /// The present value of the product is the value on the valuation date.
        /// This is the discounted forecast value.
        /// The result is converted to the specified currency.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="currency">  the currency to convert to </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value of the swap product in the specified currency </returns>
        public virtual CurrencyAmount presentValue(ResolvedSwap swap, Currency currency, RatesProvider provider)
        {
            double totalPv = 0;

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                double pv = legPricer.presentValueInternal(leg, provider);
                totalPv += (pv * provider.fxRate(leg.Currency, currency));
            }
            return(CurrencyAmount.of(currency, totalPv));
        }
 private ResolvedSwaption(LongShort longShort, SwaptionSettlement swaptionSettlement, ZonedDateTime expiry, ResolvedSwap underlying)
 {
     JodaBeanUtils.notNull(longShort, "longShort");
     JodaBeanUtils.notNull(swaptionSettlement, "swaptionSettlement");
     JodaBeanUtils.notNull(expiry, "expiry");
     JodaBeanUtils.notNull(underlying, "underlying");
     this.longShort          = longShort;
     this.swaptionSettlement = swaptionSettlement;
     this.expiry             = expiry;
     this.underlying         = underlying;
 }
예제 #21
0
        /// <summary>
        /// Calculates the present value sensitivity of the swap product converted in a given currency.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of the present value to
        /// the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="currency">  the currency to convert to </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the present value curve sensitivity of the swap product converted in the given currency </returns>
        public virtual PointSensitivityBuilder presentValueSensitivity(ResolvedSwap swap, Currency currency, RatesProvider provider)
        {
            PointSensitivityBuilder builder = PointSensitivityBuilder.none();

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                PointSensitivityBuilder ls          = legPricer.presentValueSensitivity(leg, provider);
                PointSensitivityBuilder lsConverted = ls.withCurrency(currency).multipliedBy(provider.fxRate(leg.Currency, currency));
                builder = builder.combinedWith(lsConverted);
            }
            return(builder);
        }
        /// <summary>
        /// Checks that there is exactly one fixed leg and returns it.
        /// </summary>
        /// <param name="swap">  the swap </param>
        /// <returns> the fixed leg </returns>
        protected internal virtual ResolvedSwapLeg fixedLeg(ResolvedSwap swap)
        {
            ArgChecker.isFalse(swap.CrossCurrency, "Swap must be single currency");
            // find fixed leg
            IList <ResolvedSwapLeg> fixedLegs = swap.getLegs(SwapLegType.FIXED);

            if (fixedLegs.Count == 0)
            {
                throw new System.ArgumentException("Swap must contain a fixed leg");
            }
            return(fixedLegs[0]);
        }
        /// <summary>
        /// Computes the forward rate associated to the swap underlying the CMS period.
        /// <para>
        /// Returns a value only if the period has not fixed yet. If the fixing date is on or before the valuation date,
        /// an <seealso cref="IllegalArgumentException"/> is thrown.
        ///
        /// </para>
        /// </summary>
        /// <param name="cmsPeriod">  the CMS </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the forward rate </returns>
        public virtual double forwardRate(CmsPeriod cmsPeriod, RatesProvider provider)
        {
            LocalDate fixingDate    = cmsPeriod.FixingDate;
            LocalDate valuationDate = provider.ValuationDate;

            if (!fixingDate.isAfter(valuationDate))
            {     // Using fixing
                throw new System.ArgumentException("Forward rate is availaible only for valuation date after the fixing date");
            }
            ResolvedSwap swap = cmsPeriod.UnderlyingSwap;

            return(swapPricer.parRate(swap, provider));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the implied volatility of the swaption.
        /// </summary>
        /// <param name="swaption">  the swaption </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="swaptionVolatilities">  the volatilities </param>
        /// <returns> the implied volatility associated with the swaption </returns>
        public virtual double impliedVolatility(ResolvedSwaption swaption, RatesProvider ratesProvider, SwaptionVolatilities swaptionVolatilities)
        {
            validate(swaption, ratesProvider, swaptionVolatilities);
            double          expiry     = swaptionVolatilities.relativeTime(swaption.Expiry);
            ResolvedSwap    underlying = swaption.Underlying;
            ResolvedSwapLeg fixedLeg   = this.fixedLeg(underlying);

            ArgChecker.isTrue(expiry >= 0d, "Option must be before expiry to compute an implied volatility");
            double forward = SwapPricer.parRate(underlying, ratesProvider);
            double strike  = calculateStrike(fixedLeg);
            double tenor   = swaptionVolatilities.tenor(fixedLeg.StartDate, fixedLeg.EndDate);

            return(swaptionVolatilities.volatility(expiry, tenor, strike, forward));
        }
예제 #25
0
 /// <summary>
 /// Creates an instance. </summary>
 /// <param name="securityId">  the value of the property, not null </param>
 /// <param name="notional">  the value of the property </param>
 /// <param name="deliveryDate">  the value of the property, not null </param>
 /// <param name="lastTradeDate">  the value of the property, not null </param>
 /// <param name="underlyingSwap">  the value of the property, not null </param>
 internal ResolvedDsf(SecurityId securityId, double notional, LocalDate deliveryDate, LocalDate lastTradeDate, ResolvedSwap underlyingSwap)
 {
     JodaBeanUtils.notNull(securityId, "securityId");
     ArgChecker.notNegativeOrZero(notional, "notional");
     JodaBeanUtils.notNull(deliveryDate, "deliveryDate");
     JodaBeanUtils.notNull(lastTradeDate, "lastTradeDate");
     JodaBeanUtils.notNull(underlyingSwap, "underlyingSwap");
     this.securityId     = securityId;
     this.notional       = notional;
     this.deliveryDate   = deliveryDate;
     this.lastTradeDate  = lastTradeDate;
     this.underlyingSwap = underlyingSwap;
     validate();
 }
예제 #26
0
        private void calibration_market_quote_sensitivity_check(System.Func <MarketData, RatesProvider> calibrator, double shift)
        {
            double                         notional = 100_000_000.0;
            double                         spread   = 0.0050;
            SwapTrade                      trade    = IborIborSwapConventions.USD_LIBOR_3M_LIBOR_6M.createTrade(VAL_DATE, Period.ofMonths(8), Tenor.TENOR_7Y, BuySell.BUY, notional, spread, REF_DATA);
            RatesProvider                  result   = calibrator(ALL_QUOTES);
            ResolvedSwap                   product  = trade.Product.resolve(REF_DATA);
            PointSensitivityBuilder        pts      = SWAP_PRICER.presentValueSensitivity(product, result);
            CurrencyParameterSensitivities ps       = result.parameterSensitivity(pts.build());
            CurrencyParameterSensitivities mqs      = MQC.sensitivity(ps, result);
            double                         pv0      = SWAP_PRICER.presentValue(product, result).getAmount(USD).Amount;

            double[] mqsDscComputed = mqs.getSensitivity(DSCON_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < DSC_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, DSC_ID_VALUE[i]))] = DSC_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsDscComputed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "DSC - node " + i);
            }
            double[] mqsFwd3Computed = mqs.getSensitivity(FWD3_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < FWD3_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, FWD3_ID_VALUE[i]))] = FWD3_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsFwd3Computed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "FWD3 - node " + i);
            }
            double[] mqsFwd6Computed = mqs.getSensitivity(FWD6_CURVE_NAME, USD).Sensitivity.toArray();
            for (int i = 0; i < FWD6_NB_NODES; i++)
            {
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Map<com.opengamma.strata.data.MarketDataId<?>, Object> map = new java.util.HashMap<>(ALL_QUOTES.getValues());
                IDictionary <MarketDataId <object>, object> map = new Dictionary <MarketDataId <object>, object>(ALL_QUOTES.Values);
                map[QuoteId.of(StandardId.of(SCHEME, FWD6_ID_VALUE[i]))] = FWD6_MARKET_QUOTES[i] + shift;
                ImmutableMarketData marketData = ImmutableMarketData.of(VAL_DATE, map);
                RatesProvider       rpShifted  = calibrator(marketData);
                double pvS = SWAP_PRICER.presentValue(product, rpShifted).getAmount(USD).Amount;
                assertEquals(mqsFwd6Computed[i], (pvS - pv0) / shift, TOLERANCE_PV_DELTA, "FWD6 - node " + i);
            }
        }
예제 #27
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Computes the par rate for swaps with a fixed leg.
        /// <para>
        /// The par rate is the common rate on all payments of the fixed leg for which the total swap present value is 0.
        /// </para>
        /// <para>
        /// At least one leg must be a fixed leg. The par rate will be computed with respect to the first fixed leg
        /// in which all the payments are fixed payments with a unique accrual period (no compounding) and no FX reset.
        /// If the fixed leg is compounding, the par rate is computed only when the number of fixed coupon payments is 1 and
        /// accrual factor of each sub-period is 1
        ///
        /// </para>
        /// </summary>
        /// <param name="swap">  the product </param>
        /// <param name="provider">  the rates provider </param>
        /// <returns> the par rate </returns>
        public virtual double parRate(ResolvedSwap swap, RatesProvider provider)
        {
            // find fixed leg
            ResolvedSwapLeg fixedLeg    = this.fixedLeg(swap);
            Currency        ccyFixedLeg = fixedLeg.Currency;
            // other payments (not fixed leg coupons) converted in fixed leg currency
            double otherLegsConvertedPv = 0.0;

            foreach (ResolvedSwapLeg leg in swap.Legs)
            {
                if (leg != fixedLeg)
                {
                    double pvLocal = legPricer.presentValueInternal(leg, provider);
                    otherLegsConvertedPv += (pvLocal * provider.fxRate(leg.Currency, ccyFixedLeg));
                }
            }
            double fixedLegEventsPv = legPricer.presentValueEventsInternal(fixedLeg, provider);

            if (fixedLeg.PaymentPeriods.size() > 1)
            {     // try multiperiod par-rate
                  // PVBP
                double pvbpFixedLeg = legPricer.pvbp(fixedLeg, provider);
                // Par rate
                return(-(otherLegsConvertedPv + fixedLegEventsPv) / pvbpFixedLeg);
            }
            SwapPaymentPeriod firstPeriod = fixedLeg.PaymentPeriods.get(0);

            ArgChecker.isTrue(firstPeriod is RatePaymentPeriod, "PaymentPeriod must be instance of RatePaymentPeriod");
            RatePaymentPeriod payment = (RatePaymentPeriod)firstPeriod;

            if (payment.AccrualPeriods.size() == 1)
            {     // no compounding
                  // PVBP
                double pvbpFixedLeg = legPricer.pvbp(fixedLeg, provider);
                // Par rate
                return(-(otherLegsConvertedPv + fixedLegEventsPv) / pvbpFixedLeg);
            }
            // try Compounding
            Triple <bool, int, double> fixedCompounded = checkFixedCompounded(fixedLeg);

            ArgChecker.isTrue(fixedCompounded.First, "Swap should have a fixed leg and for one payment it should be based on compunding witout spread.");
            double notional = payment.Notional;
            double df       = provider.discountFactor(ccyFixedLeg, payment.PaymentDate);

            return(Math.Pow(-(otherLegsConvertedPv + fixedLegEventsPv) / (notional * df) + 1.0d, 1.0 / fixedCompounded.Second) - 1.0d);
        }
예제 #28
0
        //-------------------------------------------------------------------------
        // calculate present or forecast value for the swap
        private static MultiCurrencyAmount swapValue(RatesProvider provider, ResolvedSwap swap, System.Func <ResolvedSwapLeg, RatesProvider, double> legFn)
        {
            if (swap.CrossCurrency)
            {
//JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter:
                return(swap.Legs.Select(leg => CurrencyAmount.of(leg.Currency, legFn(leg, provider))).collect(toMultiCurrencyAmount()));
            }
            else
            {
                Currency currency = swap.Legs.GetEnumerator().next().Currency;
                double   total    = 0d;
                foreach (ResolvedSwapLeg leg in swap.Legs)
                {
                    total += legFn(leg, provider);
                }
                return(MultiCurrencyAmount.of(currency, total));
            }
        }
예제 #29
0
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value sensitivity to piecewise constant volatility parameters of the Hull-White model.
        /// </summary>
        /// <param name="swaption">  the product </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="hwProvider">  the Hull-White model parameter provider </param>
        /// <returns> the present value Hull-White model parameter sensitivity of the swaption product </returns>
        public virtual DoubleArray presentValueSensitivityModelParamsHullWhite(ResolvedSwaption swaption, RatesProvider ratesProvider, HullWhiteOneFactorPiecewiseConstantParametersProvider hwProvider)
        {
            validate(swaption, ratesProvider, hwProvider);
            ResolvedSwap swap       = swaption.Underlying;
            LocalDate    expiryDate = swaption.ExpiryDate;

            if (expiryDate.isBefore(ratesProvider.ValuationDate))
            {     // Option has expired already
                return(DoubleArray.EMPTY);
            }
            ResolvedSwapLeg cashFlowEquiv = CashFlowEquivalentCalculator.cashFlowEquivalentSwap(swap, ratesProvider);
            int             nPayments     = cashFlowEquiv.PaymentEvents.size();

            double[]   alpha              = new double[nPayments];
            double[][] alphaAdjoint       = new double[nPayments][];
            double[]   discountedCashFlow = new double[nPayments];
            for (int loopcf = 0; loopcf < nPayments; loopcf++)
            {
                NotionalExchange payment    = (NotionalExchange)cashFlowEquiv.PaymentEvents.get(loopcf);
                ValueDerivatives valueDeriv = hwProvider.alphaAdjoint(ratesProvider.ValuationDate, expiryDate, expiryDate, payment.PaymentDate);
                alpha[loopcf]              = valueDeriv.Value;
                alphaAdjoint[loopcf]       = valueDeriv.Derivatives.toArray();
                discountedCashFlow[loopcf] = paymentPricer.presentValueAmount(payment.Payment, ratesProvider);
            }
            double omega   = (swap.getLegs(SwapLegType.FIXED).get(0).PayReceive.Pay ? -1d : 1d);
            double kappa   = computeKappa(hwProvider, discountedCashFlow, alpha, omega);
            int    nParams = alphaAdjoint[0].Length;

            if (Math.Abs(kappa) > 1d / SMALL)
            {     // decays exponentially
                return(DoubleArray.filled(nParams));
            }
            double[] pvSensi = new double[nParams];
            double   sign    = (swaption.LongShort.Long ? 1d : -1d);

            for (int i = 0; i < nParams; ++i)
            {
                for (int loopcf = 0; loopcf < nPayments; loopcf++)
                {
                    pvSensi[i] += sign * discountedCashFlow[loopcf] * NORMAL.getPDF(omega * (kappa + alpha[loopcf])) * omega * alphaAdjoint[loopcf][i];
                }
            }
            return(DoubleArray.ofUnsafe(pvSensi));
        }
예제 #30
0
        // semi-parallel gamma PV01 for one scenario
        private CurrencyParameterSensitivities pv01SemiParallelGammaBucketed(ResolvedSwapTrade trade, RatesMarketData marketData)
        {
            // find the curve identifiers and resolve to a single curve
            ResolvedSwap product = trade.Product;

            if (product.CrossCurrency)
            {
                throw new System.ArgumentException("Implementation only supports a single curve, but swap is cross-currency");
            }
            Currency     currency = product.Legs.get(0).Currency;
            ISet <Index> indices  = product.allIndices();
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: com.google.common.collect.ImmutableSet<com.opengamma.strata.data.MarketDataId<?>> discountIds = marketData.getLookup().getDiscountMarketDataIds(currency);
            ImmutableSet <MarketDataId <object> > discountIds = marketData.Lookup.getDiscountMarketDataIds(currency);
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: com.google.common.collect.ImmutableSet<com.opengamma.strata.data.MarketDataId<?>> forwardIds = indices.stream().flatMap(idx -> marketData.getLookup().getForwardMarketDataIds(idx).stream()).collect(toImmutableSet());
            ImmutableSet <MarketDataId <object> > forwardIds = indices.stream().flatMap(idx => marketData.Lookup.getForwardMarketDataIds(idx).stream()).collect(toImmutableSet());
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: java.util.Set<com.opengamma.strata.data.MarketDataId<?>> allIds = com.google.common.collect.Sets.union(discountIds, forwardIds);
            ISet <MarketDataId <object> > allIds = Sets.union(discountIds, forwardIds);

            if (allIds.Count != 1)
            {
                throw new System.ArgumentException(Messages.format("Implementation only supports a single curve, but lookup refers to more than one: {}", allIds));
            }
//JAVA TO C# CONVERTER WARNING: Java wildcard generics have no direct equivalent in .NET:
//ORIGINAL LINE: com.opengamma.strata.data.MarketDataId<?> singleId = allIds.iterator().next();
            MarketDataId <object> singleId = allIds.GetEnumerator().next();

            if (!(singleId is CurveId))
            {
//JAVA TO C# CONVERTER WARNING: The .NET Type.FullName property will not always yield results identical to the Java Class.getName method:
                throw new System.ArgumentException(Messages.format("Implementation only supports a single curve, but lookup does not refer to a curve: {} {}", singleId.GetType().FullName, singleId));
            }
            CurveId curveId = (CurveId)singleId;
            Curve   curve   = marketData.MarketData.getValue(curveId);

            // calculate gamma
            CurrencyParameterSensitivity gamma = CurveGammaCalculator.DEFAULT.calculateSemiParallelGamma(curve, currency, c => calculateCurveSensitivity(trade, marketData, curveId, c));

            return(CurrencyParameterSensitivities.of(gamma).multipliedBy(ONE_BASIS_POINT * ONE_BASIS_POINT));
        }