public SimulationManager(DataModel dataModel) { // Set up simulations // Stocks stocksSimulation = new StocksSimulation(); stocksProfile = new RunProfile(InvestmentType.Stocks, dataModel); // Bonds bondsSimulation = new BondsSimulation(); bondsProfile = new RunProfile(InvestmentType.Bonds, dataModel); // Savings savingsSimulation = new SavingsSimulation(); savingsProfile = new RunProfile(InvestmentType.Savings, dataModel); }
public Trial[] Run(RunProfile withProfile) { if (withProfile.StepDistribution.Type == Distribution.DiracDelta || withProfile.StepDistribution.Type == Distribution.Testable) { RunTrial(0, withProfile); var trial = trials[0]; for (var i = 1; i < NUM_TRIALS; i++) { trials[i] = trial; } } else { Parallel.For(0, NUM_TRIALS, i => { RunTrial(i, withProfile); }); } return(trials); }
protected override void RunTrial(int trialNumber, RunProfile profile) { Trial trial = new Trial(); var addAmt = profile.ContributionAmount; var withdrawAmt = profile.WithdrawalAmount; var trialLength = profile.TrialLength; var contribLength = profile.ContributionLength; var stepSampler = profile.StepDistribution; var sigma = profile.Volatility; var mu = profile.Drift; double[] balances = new double[trialLength]; double[] unitValues = new double[trialLength]; double[] returnRates = new double[trialLength - 1]; unitValues[0] = 1.0; // Populate trial data double step = 0; balances[0] = profile.InitialAmount + addAmt; for (var i = 1; i < trialLength; i++) { // Discretized Levy process (random walk with steps distributed as stepDistribution) step += stepSampler.NextDouble(); // Discretized geometric Brownian motion using the Milstein method var unitValue = (1 + mu + sigma * step + 0.5 * sigma * sigma * (step * step - 1)) * unitValues[i - 1]; // Get return rate var returnRate = unitValue / unitValues[i - 1]; var prevBalance = balances[i - 1]; var balance = prevBalance > 0 ? (i < contribLength ? // Contribution period (prevBalance + addAmt) * returnRate : // Withdrawal period (prevBalance - withdrawAmt) * returnRate) : 0; if (i == contribLength - 1) { trial.Peak = balance; } balances[i] = balance > 0 ? balance : 0; unitValues[i] = unitValue; returnRates[i - 1] = Math.Log(returnRate); if (balance == 0) { break; } } trial.Final = balances[trialLength - 1]; trial.Balances = balances; trial.ReturnRates = returnRates; // Add data to return value mutex.WaitOne(); trials[trialNumber] = trial; mutex.ReleaseMutex(); }
protected abstract void RunTrial(int trialNumber, RunProfile profile);