/// <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)); } } } } }
/// <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)); } } } } }