Esempio n. 1
0
 /// <summary>
 /// The main constructor for the Coordinator.
 /// </summary>
 /// <param name="numeraireSimulator">A special simulator that also includes the numeraire. There is only one of these.</param>
 /// <param name="availableSimulators">Optionally any extra simulators independent of the first.  Can be an empty list.</param>
 /// <param name="numberOfPaths"></param>
 public Coordinator(NumeraireSimulator numeraireSimulator, List <Simulator> availableSimulators,
                    int numberOfPaths)
 {
     _numeraireSimulator  = numeraireSimulator;
     _availableSimulators = availableSimulators;
     _numberOfPaths       = numberOfPaths;
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
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();
 }
Esempio n. 4
0
 /// <summary>
 /// Copies the simulators into local variables so that they can be safely used on a thread
 /// without changing the originals.
 /// </summary>
 /// <param name="localNumeraire">The local numeraire.  The reference to this object is changed in the call.</param>
 /// <param name="localSimulators">The local simulators.</param>
 /// <exception cref="System.NotImplementedException"></exception>
 private void CopySimulators(out NumeraireSimulator localNumeraire, out List <Simulator> localSimulators)
 {
     localSimulators = new List <Simulator>();
     foreach (Simulator simulator in simulators)
     {
         localSimulators.Add(simulator.Clone());
     }
     localNumeraire = (NumeraireSimulator)localSimulators[0];
 }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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);
            }
        }
Esempio n. 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));
                        }
                    }
                }
            }
        }