コード例 #1
0
ファイル: Coordinator.cs プロジェクト: zhangz/QuantSA
        private static MarketObservable GetCcyPair(NumeraireSimulator numeraireSimulator, Currency ccy)
        {
            // TODO: Currency pair should be passed in somehow rather than constructed here so that there is no risk of names not coinciding.
            MarketObservable index = new CurrencyPair($"{ccy}{numeraireSimulator.GetNumeraireCurrency()}",
                                                      ccy, numeraireSimulator.GetNumeraireCurrency());

            return(index);
        }
コード例 #2
0
 /// <summary>
 /// The main constructor for the Coordinator.
 /// </summary>
 /// <param name="numeraire">A special simulator that also includes the numeraire. There is only one of these.</param>
 /// <param name="simulators">Optionally any extra simulators independent of the first.  Can be an empty list.</param>
 public Coordinator(NumeraireSimulator numeraire, List <Simulator> simulators, int N)
 {
     this.numeraire  = numeraire;
     this.simulators = simulators;
     this.simulators.Insert(0, numeraire);
     this.N        = N;
     valueCurrency = numeraire.GetNumeraireCurrency();
 }
コード例 #3
0
ファイル: Coordinator.cs プロジェクト: zhangz/QuantSA
        /// <summary>
        /// Creates a lookup so that the coordinator knows which simulator provides each required index.
        /// </summary>
        /// <exception cref="System.ArgumentException">
        /// Cannot use 'ANY' as the valuation currency when the portfolio includes cashflows in multiple currencies.
        /// </exception>
        /// <exception cref="System.IndexOutOfRangeException">
        /// Required index: " + index.ToString() + " is not provided by any of the simulators.
        /// or
        /// Required currency pair: " + index.ToString() + " is not provided by any of the simulators
        /// </exception>
        private static Dictionary <MarketObservable, Simulator> AssociateFactorsWithSimulators(
            IEnumerable <IProduct> portfolio,
            NumeraireSimulator numeraireSimulator,
            List <Simulator> availableSimulators)
        {
            // Find which simulator will provide each of the potentially required MarketObservables.
            var mappedSimulators = new Dictionary <MarketObservable, Simulator>();
            var indices          = new HashSet <MarketObservable>();

            foreach (var product in portfolio)
            {
                foreach (var index in product.GetRequiredIndices())
                {
                    indices.Add(index);
                }
                foreach (var ccy in product.GetCashflowCurrencies().Where(c => c != numeraireSimulator.GetNumeraireCurrency()))
                {
                    indices.Add(GetCcyPair(numeraireSimulator, ccy));
                }
            }

            foreach (var index in indices)
            {
                if (mappedSimulators.ContainsKey(index))
                {
                    continue;
                }
                var found = false;
                foreach (var sim in availableSimulators)
                {
                    if (!sim.ProvidesIndex(index))
                    {
                        continue;
                    }
                    if (!found)
                    {
                        mappedSimulators[index] = sim;
                        found = true;
                    }
                    else
                    {
                        throw new ArgumentException(index + " is provided by more than one simulator.");
                    }
                }

                if (found)
                {
                    continue;
                }
                throw new IndexOutOfRangeException("Required index: " + index +
                                                   " is not provided by any of the simulators.");
            }

            return(mappedSimulators);
        }
コード例 #4
0
        /// <summary>
        /// Initializes the simulators by telling them at which dates they will need to provide which market indices.
        /// </summary>
        /// <param name="extraDates">Extra dates over and above the contract dates where the simulators will need to
        /// provide their indices.</param>
        private void InitializeSimulators(List <Product> portfolio, List <Date> extraDates)
        {
            // Reset all the simulators
            foreach (Simulator simulator in simulators)
            {
                simulator.Reset();
            }

            // Set up the simulators for the times at which they will be queried
            foreach (Product product in portfolio)
            {
                product.SetValueDate(valueDate);
                // Tell the simulators at what times indices will be required.
                foreach (MarketObservable index in product.GetRequiredIndices())
                {
                    List <Date> requiredTimes = product.GetRequiredIndexDates(index);
                    simulators[indexSources[index]].SetRequiredDates(index, requiredTimes);
                    simulators[indexSources[index]].SetRequiredDates(index, extraDates);
                }
                // Tell the nummeraire simulator at what times it will be required.
                // Tell the FX simulators at what times they will be required.
                foreach (Currency ccy in product.GetCashflowCurrencies())
                {
                    List <Date> requiredDates = product.GetCashflowDates(ccy);
                    numeraire.SetNumeraireDates(requiredDates);
                    numeraire.SetNumeraireDates(extraDates);
                    if (ccy != numeraire.GetNumeraireCurrency())
                    {
                        MarketObservable index = new CurrencyPair(ccy, numeraire.GetNumeraireCurrency());
                        simulators[indexSources[index]].SetRequiredDates(index, requiredDates);
                        simulators[indexSources[index]].SetRequiredDates(index, extraDates);
                    }
                }
            }

            // Prepare all the simulators
            foreach (Simulator simulator in simulators)
            {
                simulator.Prepare();
            }
        }
コード例 #5
0
ファイル: Coordinator.cs プロジェクト: zhangz/QuantSA
        /// <summary>
        /// Initializes the simulators by telling them at which dates they will need to provide which market indices.
        /// </summary>
        /// <param name="valueDate"></param>
        /// <param name="portfolio"></param>
        /// <param name="fwdDates">Extra dates over and above the contract dates where the simulators will need to
        /// provide their indices.  This is likely to be forward values required in EPE and PFE profiles.</param>
        /// <param name="numeraireSimulator"></param>
        /// <param name="mappedSimulators"></param>
        /// <param name="availableSimulators"></param>
        private static void PrepareSimulators(Date valueDate, List <IProduct> portfolio, List <Date> fwdDates,
                                              NumeraireSimulator numeraireSimulator, Dictionary <MarketObservable, Simulator> mappedSimulators,
                                              List <Simulator> availableSimulators)
        {
            // Reset all the simulators
            foreach (var simulator in availableSimulators)
            {
                simulator.Reset();
            }

            // Set up the simulators for the times at which they will be queried
            foreach (var product in portfolio)
            {
                product.SetValueDate(valueDate);
                // Tell the simulators at what times indices will be required.
                foreach (var index in product.GetRequiredIndices())
                {
                    var requiredTimes = product.GetRequiredIndexDates(index);
                    mappedSimulators[index].SetRequiredDates(index, requiredTimes);
                    mappedSimulators[index].SetRequiredDates(index, fwdDates);
                }

                // Tell the numeraire simulator at what times it will be required.
                // Tell the FX simulators at what times they will be required.
                foreach (var ccy in product.GetCashflowCurrencies())
                {
                    var requiredDates = product.GetCashflowDates(ccy);
                    numeraireSimulator.SetNumeraireDates(requiredDates);
                    numeraireSimulator.SetNumeraireDates(fwdDates);
                    if (ccy != numeraireSimulator.GetNumeraireCurrency())
                    {
                        var ccyPair = GetCcyPair(numeraireSimulator, ccy);
                        mappedSimulators[ccyPair].SetRequiredDates(ccyPair, requiredDates);
                        mappedSimulators[ccyPair].SetRequiredDates(ccyPair, fwdDates);
                    }
                }

                foreach (var simulator in availableSimulators)
                {
                    simulator.Prepare(valueDate);
                }
                numeraireSimulator.Prepare(valueDate);
            }

            // Prepare all the simulators
            foreach (var simulator in availableSimulators)
            {
                simulator.Prepare(valueDate);
            }
        }
コード例 #6
0
ファイル: Coordinator.cs プロジェクト: zhangz/QuantSA
        /// <summary>
        /// Performs the simulation chunk that updates
        ///     the cashflows per product and per path.
        ///     the
        /// </summary>
        /// <param name="portfolio"></param>
        /// <param name="allDates">The dates at which the underlying factors will be saved for later regression.</param>
        /// <param name="simulatedCFs">The cashflows converted to the value currency and deflated with the numeraire. Updated
        /// by this function.</param>
        /// <param name="simulatedRegs">The values of the regressors by path and date.</param>
        /// <param name="pathStart">The path start.</param>
        /// <param name="pathEnd">The path end.</param>
        private void PerformSimulationChunk(List <IProduct> portfolio, List <Date> allDates,
                                            SimulatedCashflows simulatedCFs, SimulatedRegressors simulatedRegs, int pathStart, int pathEnd)
        {
            // clone the simulators and portfolio if this is running multi threaded
            var localPortfolio = portfolio.Clone();

            var(localNumeraire, localSimulators) = GetCopyOfSimulators();
            var mappedSimulators = AssociateFactorsWithSimulators(localPortfolio, localNumeraire, localSimulators);

            PrepareSimulators(_valueDate, localPortfolio, allDates, localNumeraire, mappedSimulators,
                              localSimulators);

            foreach (var product in localPortfolio)
            {
                product.SetValueDate(_valueDate);
            }

            for (var pathCounter = pathStart; pathCounter < pathEnd; pathCounter++)
            {
                var numeraireAtValue = localNumeraire.Numeraire(_valueDate);
                // Run the simulation
                foreach (var simulator in localSimulators)
                {
                    simulator.RunSimulation(pathCounter);
                }

                // get the underlying factors
                for (var fwdDateCounter = 0; fwdDateCounter < allDates.Count; fwdDateCounter++)
                {
                    var independentCounter = 0;
                    foreach (var simulator in localSimulators)
                    {
                        var underlyingFactors = simulator.GetUnderlyingFactors(allDates[fwdDateCounter]);
                        foreach (var factor in underlyingFactors)
                        {
                            simulatedRegs.Add(pathCounter, fwdDateCounter, independentCounter, factor);
                            independentCounter++;
                        }
                    }
                }

                // use the simulators that now contain a simulation to provide market observables to the
                // products.
                for (var productCounter = 0; productCounter < localPortfolio.Count; productCounter++)
                {
                    var product = localPortfolio[productCounter];
                    product.Reset();
                    foreach (var index in product.GetRequiredIndices())
                    {
                        var simulator     = mappedSimulators[index];
                        var requiredDates = product.GetRequiredIndexDates(index);
                        var indices       = simulator.GetIndices(index, requiredDates);
                        product.SetIndexValues(index, indices);
                    }

                    var timesAndCfs = product.GetCFs();
                    foreach (var cf in timesAndCfs)
                    {
                        if (cf.Currency.Equals(_numeraireSimulator.GetNumeraireCurrency()))
                        {
                            var cfValue = cf.Amount * numeraireAtValue / localNumeraire.Numeraire(cf.Date);
                            simulatedCFs.Add(productCounter, pathCounter, new Cashflow(cf.Date, cfValue, cf.Currency));
                        }
                        else
                        {
                            var currencyPair = GetCcyPair(localNumeraire, cf.Currency);
                            var simulator    = mappedSimulators[currencyPair];
                            var fxRate       = simulator.GetIndices(currencyPair, new List <Date> {
                                cf.Date
                            })[0];
                            var cfValue = fxRate * cf.Amount * numeraireAtValue / localNumeraire.Numeraire(cf.Date);
                            simulatedCFs.Add(productCounter, pathCounter, new Cashflow(cf.Date, cfValue, cf.Currency));
                        }
                    }
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Performs the simulation chunk that updates
        ///     the cashflows per product and per path.
        ///     the
        /// </summary>
        /// <param name="portfolio"></param>
        /// <param name="fwdValueDates">The dates at which the underlying factors will be saved for later regression.</param>
        /// <param name="simulatedCFs">The cashflows converted to the value currency and deflated witht he numeaire. Updated
        /// by this function.</param>
        /// <param name="simulatedRegs">The valuesor the regressors by path and date.</param>
        /// <param name="pathStart">The path start.</param>
        /// <param name="pathEnd">The path end.</param>
        private void PerformSimulationChunk(List <Product> portfolio, List <Date> fwdValueDates,
                                            SimulatedCashflows simulatedCFs, SimulatedRegressors simulatedRegs, int pathStart, int pathEnd)
        {
            // clone the simulators and portfolio if this is running multi threaded
            List <Product>     localPortfolio;
            NumeraireSimulator localNumeraire  = null;
            List <Simulator>   localSimulators = null;

            if (useThreads)
            {
                localPortfolio = portfolio.Clone();
                CopySimulators(out localNumeraire, out localSimulators);
            }
            else
            {
                localPortfolio  = portfolio;
                localNumeraire  = numeraire;
                localSimulators = simulators;
            }

            for (int pathCounter = pathStart; pathCounter < pathEnd; pathCounter++)
            {
                double numeraireAtValue = localNumeraire.Numeraire(valueDate);
                // Run the simulation
                foreach (Simulator simulator in localSimulators)
                {
                    simulator.RunSimulation(pathCounter);
                }
                // get the underlying factors
                for (int fwdDateCounter = 0; fwdDateCounter < fwdValueDates.Count; fwdDateCounter++)
                {
                    int independentCounter = 0;
                    foreach (Simulator simulator in localSimulators)
                    {
                        double[] underlyingFactors = simulator.GetUnderlyingFactors(fwdValueDates[fwdDateCounter]);
                        for (int thisIndependentCounter = 0; thisIndependentCounter < underlyingFactors.Length; thisIndependentCounter++)
                        {
                            simulatedRegs.Add(pathCounter, fwdDateCounter, independentCounter, underlyingFactors[thisIndependentCounter]);
                            independentCounter++;
                        }
                    }
                }
                // use the simulators that now contain a simulation to provide market observables to the
                // products.
                for (int productCounter = 0; productCounter < localPortfolio.Count; productCounter++)
                {
                    Product product = localPortfolio[productCounter];
                    product.Reset();
                    foreach (MarketObservable index in product.GetRequiredIndices())
                    {
                        Simulator   simulator     = localSimulators[indexSources[index]];
                        List <Date> requiredDates = product.GetRequiredIndexDates(index);
                        double[]    indices       = simulator.GetIndices(index, requiredDates);
                        product.SetIndexValues(index, indices);
                    }
                    List <Cashflow> timesAndCFS = product.GetCFs();
                    foreach (Cashflow cf in timesAndCFS)
                    {
                        if (cf.currency.Equals(valueCurrency))
                        {
                            double cfValue = cf.amount * numeraireAtValue / localNumeraire.Numeraire(cf.date);
                            simulatedCFs.Add(productCounter, pathCounter, new Cashflow(cf.date, cfValue, cf.currency));
                        }
                        else
                        {
                            MarketObservable currencyPair = new CurrencyPair(cf.currency, localNumeraire.GetNumeraireCurrency());
                            Simulator        simulator    = localSimulators[indexSources[currencyPair]];
                            double           fxRate       = simulator.GetIndices(currencyPair, new List <Date> {
                                cf.date
                            })[0];
                            double cfValue = fxRate * cf.amount * numeraireAtValue / localNumeraire.Numeraire(cf.date);
                            simulatedCFs.Add(productCounter, pathCounter, new Cashflow(cf.date, cfValue, cf.currency));
                        }
                    }
                }
            }
        }