/// <inheritdoc />
        public override void HeadNodeInitialize(PriceFactorList factors, BaseTimeGrid baseTimes, RequiredResults requiredResults)
        {
            base.HeadNodeInitialize(factors, baseTimes, requiredResults);

            BaseCliquetOption deal = (BaseCliquetOption)fDeal;

            DateList accrualDates = CashflowGeneration.GenerateStripOfDates(deal.Effective_Date, deal.Maturity_Date, deal.Frequency, deal.GetHolidayCalendar());

            fTimes = new double[accrualDates.Count];
            for (int i = 0; i < accrualDates.Count; ++i)
            {
                fTimes[i] = CalcUtils.DaysToYears(accrualDates[i] - factors.BaseDate);
            }

            // Get the asset price from the deal helper
            var         dealHelper = (BaseAssetFxDealHelper)deal.GetDealHelper();
            IAssetPrice assetPrice = dealHelper.GetAssetPrice(factors);

            fKnownPrices = deal.GetKnownPrices(accrualDates, factors, assetPrice);

            // Add expiry dates to valuation time grid.
            if (accrualDates.Count > 1)
            {
                DateList expiryDates = new DateList(accrualDates);
                expiryDates.RemoveAt(0);

                fT.AddPayDates(expiryDates, requiredResults.CashRequired());
            }
        }
        /// <summary>
        /// Calculate a valuation profile for a range of scenarios.
        /// </summary>
        public override void Value(ValuationResults valuationResults, PriceFactorList factors, BaseTimeGrid baseTimes)
        {
            IAssetPrice price  = GetAssetPrice(factors);
            PVProfiles  result = valuationResults.Profile;

            double scale = fDeal.Units * (fDeal.Buy_Sell == BuySell.Buy ? +1 : -1);

            var tgi = new TimeGridIterator(fT);

            VectorEngine.For(tgi, () => result.AppendVector(tgi.Date, scale * price.Get(tgi.T)));

            result.Complete(fT);

            CashAccumulators cashAccumulators = valuationResults.Cash;
            double           endDate          = Deal.EndDate();

            if (!cashAccumulators.Ignore && endDate <= fT.fHorizon)
            {
                double  tEnd   = CalcUtils.DaysToYears(endDate - factors.BaseDate);
                IFxRate fxRate = factors.GetInterface <IFxRate>(fDeal.Currency);
                cashAccumulators.Accumulate(fxRate, endDate, scale * price.Get(tEnd) / fxRate.Get(tEnd));
            }
        }
        /// <summary>
        /// Construct the array of known prices.
        /// </summary>
        public override double[] GetKnownPrices(DateList resetDates, PriceFactorList factors, IAssetPrice assetPrice)
        {
            bool   isCompo       = !string.IsNullOrEmpty(fPayoffCurrency) && fPayoffCurrency != Currency && Payoff_Type == PayoffType.Compo;
            string assetCurrency = isCompo ? fPayoffCurrency : Currency;

            double[] knownPrices;
            double[] knownFxRates;
            AssetPriceFxRateList.GetRates(resetDates, factors.BaseDate, Known_Prices, out knownPrices, out knownFxRates);
            if (isCompo)
            {
                for (int i = 0; i < knownPrices.Length; ++i)
                {
                    knownPrices[i] *= knownFxRates[i];
                }
            }

            FillMissingKnownPricesFromRateFixings(knownPrices, resetDates, factors, assetPrice, assetCurrency);

            return(knownPrices);
        }
        /// <summary>
        /// Fills missing known prices with values from the rate fixings.
        /// </summary>
        protected void FillMissingKnownPricesFromRateFixings(double[] knownPrices, DateList resetDates, PriceFactorList factors, IAssetPrice assetPrice, string assetCurrency)
        {
            List <int>      missingIndices;
            List <DateTime> missingDates;

            if (!GetMissingIndicesAndDates(knownPrices, resetDates, factors.BaseDate, out missingIndices, out missingDates))
            {
                return;
            }

            var rateFixings = factors.RateFixings.GetAssetPriceFixings(factors, assetPrice, assetCurrency, missingDates, factors.BaseDate, this, string.Empty).ToList();

            ApplyFixings(missingIndices, rateFixings, knownPrices);
        }
 /// <summary>
 /// Construct the array of known prices.
 /// </summary>
 public abstract double[] GetKnownPrices(DateList resetDates, PriceFactorList factors, IAssetPrice assetPrice);