// calculates market quote sum PV01 for one scenario
        internal MultiCurrencyAmount pv01MarketQuoteSum(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            PointSensitivities             pointSensitivity     = tradePricer.presentValueSensitivity(trade, ratesProvider, refData);
            CurrencyParameterSensitivities parameterSensitivity = ratesProvider.parameterSensitivity(pointSensitivity);
            CurrencyParameterSensitivities quoteSensitivity     = MARKET_QUOTE_SENS.sensitivity(parameterSensitivity, ratesProvider);

            return(quoteSensitivity.total().multipliedBy(ONE_BASIS_POINT));
        }
        // calculates market quote bucketed IR01 for one scenario
        internal CurrencyParameterSensitivities ir01MarketQuoteBucketed(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            PointSensitivities             pointSensitivity     = tradePricer.presentValueOnSettleSensitivity(trade, ratesProvider, refData);
            CurrencyParameterSensitivity   parameterSensitivity = ratesProvider.singleDiscountCurveParameterSensitivity(pointSensitivity, trade.Product.Currency);
            CurrencyParameterSensitivities irSensitivity        = MARKET_QUOTE_SENS.sensitivity(CurrencyParameterSensitivities.of(parameterSensitivity), ratesProvider);

            return(irSensitivity.multipliedBy(ONE_BASIS_POINT));
        }
        /// <summary>
        /// Calculates the present value sensitivity of the trade.
        /// <para>
        /// The present value sensitivity of the trade is the sensitivity of present value to the underlying curves.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the present value sensitivity </returns>
        public virtual PointSensitivities presentValueSensitivity(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            PointSensitivityBuilder pvSensiProduct = productPricer.presentValueSensitivity(trade.Product, ratesProvider, ratesProvider.ValuationDate, refData);

            if (!trade.UpfrontFee.Present)
            {
                return(pvSensiProduct.build());
            }
            Payment upfront = trade.UpfrontFee.get();
            PointSensitivityBuilder pvUpfront = upfrontPricer.presentValueSensitivity(upfront, ratesProvider.discountFactors(upfront.Currency).toDiscountFactors());

            return(pvSensiProduct.combinedWith(pvUpfront).build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the trade.
        /// <para>
        /// The present value of the product is based on the valuation date.
        /// </para>
        /// <para>
        /// This method can calculate the clean or dirty present value, see <seealso cref="PriceType"/>.
        /// If calculating the clean value, the accrued interest is calculated based on the step-in date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="priceType">  the price type </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the price </returns>
        public virtual CurrencyAmount presentValue(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, PriceType priceType, ReferenceData refData)
        {
            CurrencyAmount pvProduct = productPricer.presentValue(trade.Product, ratesProvider, ratesProvider.ValuationDate, priceType, refData);

            if (!trade.UpfrontFee.Present)
            {
                return(pvProduct);
            }
            Payment        upfront   = trade.UpfrontFee.get();
            CurrencyAmount pvUpfront = upfrontPricer.presentValue(upfront, ratesProvider.discountFactors(upfront.Currency).toDiscountFactors());

            return(pvProduct.plus(pvUpfront));
        }
 //-------------------------------------------------------------------------
 private LocalDate calculateSettlementDate(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(trade.Info.SettlementDate.orElse(trade.Product.calculateSettlementDateFromValuation(ratesProvider.ValuationDate, refData)));
 }
 //-------------------------------------------------------------------------
 // calculates market quote sum PV01 for all scenarios
 internal MultiCurrencyScenarioArray pv01MarketQuoteSum(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(MultiCurrencyScenarioArray.of(marketData.ScenarioCount, i => pv01MarketQuoteSum(trade, marketData.scenario(i).creditRatesProvider(), refData)));
 }
 //-------------------------------------------------------------------------
 // calculates principal for all scenarios
 internal CurrencyScenarioArray principal(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(CurrencyScenarioArray.of(marketData.ScenarioCount, i => principal(trade, marketData.scenario(i).creditRatesProvider(), refData)));
 }
 //-------------------------------------------------------------------------
 // calculates present value for all scenarios
 internal CurrencyScenarioArray presentValue(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(CurrencyScenarioArray.of(marketData.ScenarioCount, i => presentValue(trade, marketData.scenario(i).creditRatesProvider(), PriceType.DIRTY, refData)));
 }
 //-------------------------------------------------------------------------
 // calculates expected loss for all scenarios
 internal CurrencyScenarioArray expectedLoss(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(CurrencyScenarioArray.of(marketData.ScenarioCount, i => expectedLoss(trade, marketData.scenario(i).creditRatesProvider())));
 }
 //-------------------------------------------------------------------------
 // calculates jump-to-default for all scenarios
 internal ScenarioArray <JumpToDefault> jumpToDefault(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(ScenarioArray.of(marketData.ScenarioCount, i => jumpToDefault(trade, marketData.scenario(i).creditRatesProvider(), refData)));
 }
 // calculates bucketed CS01 for one scenario
 internal CurrencyParameterSensitivity cs01Bucketed(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(cs01Calculator.bucketedCs01(trade, ratesProvider, refData));
 }
 // calculates parallel CS01 for one scenario
 internal CurrencyAmount cs01Parallel(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(cs01Calculator.parallelCs01(trade, ratesProvider, refData));
 }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the expected loss of the underlying product.
 /// <para>
 /// The expected loss is the (undiscounted) expected default settlement value paid by the protection seller.
 /// The resulting value is always positive.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <returns> the expected loss </returns>
 public virtual CurrencyAmount expectedLoss(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider)
 {
     return(productPricer.expectedLoss(trade.Product, ratesProvider));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the jump-to-default of the underlying product.
        /// <para>
        /// The jump-to-default is the value of the product in case of immediate default.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the jump-to-default </returns>
        public virtual JumpToDefault jumpToDefault(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.jumpToDefault(trade.Product, ratesProvider, settlementDate, refData));
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the recovery01 of the underlying product.
        /// <para>
        /// The recovery01 is defined as the present value sensitivity to the recovery rate.
        /// Since the ISDA standard model requires the recovery rate to be constant throughout the lifetime of the CDS,
        /// one currency amount is returned by this method.
        /// </para>
        /// <para>
        /// This is computed based on the settlement date rather than the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the recovery01 </returns>
        public virtual CurrencyAmount recovery01OnSettle(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.recovery01(trade.Product, ratesProvider, settlementDate, refData));
        }
        /// <summary>
        /// Calculates the present value sensitivity of the underlying product.
        /// <para>
        /// The present value sensitivity of the product is the sensitivity of present value to the underlying curves.
        /// The present value sensitivity is computed based on the settlement date rather than the valuation date.
        /// </para>
        /// <para>
        /// This is coherent to <seealso cref="#presentValueOnSettle(ResolvedCdsTrade, CreditRatesProvider, PriceType, ReferenceData)"/>.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the present value sensitivity </returns>
        public virtual PointSensitivities presentValueOnSettleSensitivity(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.presentValueSensitivity(trade.Product, ratesProvider, settlementDate, refData).build());
        }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the present value of the underlying product.
        /// <para>
        /// The present value is computed based on the settlement date rather than the valuation date.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="priceType">  the price type </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the price </returns>
        public virtual CurrencyAmount presentValueOnSettle(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, PriceType priceType, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.presentValue(trade.Product, ratesProvider, settlementDate, priceType, refData));
        }
 //-------------------------------------------------------------------------
 // calculates bucketed CS01 for all scenarios
 internal ScenarioArray <CurrencyParameterSensitivity> cs01Bucketed(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(ScenarioArray.of(marketData.ScenarioCount, i => cs01Bucketed(trade, marketData.scenario(i).creditRatesProvider(), refData)));
 }
 //-------------------------------------------------------------------------
 /// <summary>
 /// Calculates the price of the underlying product, which is the present value per unit notional.
 /// <para>
 /// This method can calculate the clean or dirty price, see <seealso cref="PriceType"/>.
 /// If calculating the clean price, the accrued interest is calculated based on the step-in date.
 /// </para>
 /// <para>
 /// This is coherent to <seealso cref="#presentValueOnSettle(ResolvedCdsTrade, CreditRatesProvider, PriceType, ReferenceData)"/>.
 ///
 /// </para>
 /// </summary>
 /// <param name="trade">  the trade </param>
 /// <param name="ratesProvider">  the rates provider </param>
 /// <param name="priceType">  the price type </param>
 /// <param name="refData">  the reference data </param>
 /// <returns> the price </returns>
 public virtual double price(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, PriceType priceType, ReferenceData refData)
 {
     return(price(trade, ratesProvider, trade.Product.FixedRate, priceType, refData));
 }
 // calculates recovery01 for one scenario
 internal CurrencyAmount recovery01(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(tradePricer.recovery01OnSettle(trade, ratesProvider, refData));
 }
        // internal price computation with specified coupon rate
        internal virtual double price(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, double fractionalSpread, PriceType priceType, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.price(trade.Product, ratesProvider, fractionalSpread, settlementDate, priceType, refData));
        }
 // calculates jump-to-default for one scenario
 internal JumpToDefault jumpToDefault(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(tradePricer.jumpToDefault(trade, ratesProvider, refData));
 }
 //-------------------------------------------------------------------------
 // calculates price for all scenarios
 internal DoubleScenarioArray unitPrice(ResolvedCdsTrade trade, CreditRatesScenarioMarketData marketData, ReferenceData refData)
 {
     return(DoubleScenarioArray.of(marketData.ScenarioCount, i => unitPrice(trade, marketData.scenario(i).creditRatesProvider(), refData)));
 }
 // calculates expected loss for one scenario
 internal CurrencyAmount expectedLoss(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider)
 {
     return(tradePricer.expectedLoss(trade, ratesProvider));
 }
        // calculates price for one scenario
        internal double unitPrice(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            double puf = tradePricer.price(trade, ratesProvider, PriceType.CLEAN, refData);

            return(converter.cleanPriceFromPointsUpfront(puf));
        }
 // calculates present value for one scenario
 internal CurrencyAmount presentValue(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, PriceType priceType, ReferenceData refData)
 {
     return(tradePricer.presentValue(trade, ratesProvider, priceType, refData));
 }
        // calculates calibrated bucketed PV01 for one scenario
        internal CurrencyParameterSensitivities pv01CalibratedBucketed(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            PointSensitivities pointSensitivity = tradePricer.presentValueSensitivity(trade, ratesProvider, refData);

            return(ratesProvider.parameterSensitivity(pointSensitivity).multipliedBy(ONE_BASIS_POINT));
        }
 // calculates principal for one scenario
 internal CurrencyAmount principal(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
 {
     return(tradePricer.presentValueOnSettle(trade, ratesProvider, PriceType.CLEAN, refData));
 }
        //-------------------------------------------------------------------------
        /// <summary>
        /// Calculates the par spread of the underlying product.
        /// <para>
        /// The par spread is a coupon rate such that the clean price is 0.
        /// The result is represented in decimal form.
        /// </para>
        /// <para>
        /// This is coherent to <seealso cref="#price(ResolvedCdsTrade, CreditRatesProvider, PriceType, ReferenceData)"/>.
        ///
        /// </para>
        /// </summary>
        /// <param name="trade">  the trade </param>
        /// <param name="ratesProvider">  the rates provider </param>
        /// <param name="refData">  the reference data </param>
        /// <returns> the par spread </returns>
        public virtual double parSpread(ResolvedCdsTrade trade, CreditRatesProvider ratesProvider, ReferenceData refData)
        {
            LocalDate settlementDate = calculateSettlementDate(trade, ratesProvider, refData);

            return(productPricer.parSpread(trade.Product, ratesProvider, settlementDate, refData));
        }