public void StepNext(TimeInterval timeStep) { int timeIndex = timeStep.Index; var S = NArray.CreateScalar(0); double tenor = timeStep.IntervalInYears; for (int factorIndex = 0; factorIndex < _factors.Length; ++factorIndex) { S += (Sigma(factorIndex) / Lambda(factorIndex)) * (_factorPaths[factorIndex][timeIndex] + _weinerPaths[factorIndex][timeIndex]); } double drift = GetDrift(timeIndex); _state[timeIndex] = NMath.Exp(-0.5 * drift + S); }
/// <summary> /// Calculates discount factor for payment at time t2 at the supplied simulation time index /// </summary> /// <param name="timeIndex"></param> /// <param name="t2"></param> /// <returns></returns> public NArray DiscountFactor(int timeIndex, DateTime t2) { var B = NArray.CreateScalar(0); var simulationT0 = _timePoints.First().DateTime; double tenor = IntervalInYears(_timePoints[timeIndex].DateTime, t2); for (int factorIndex = 0; factorIndex < _factors.Length; ++factorIndex) { B += Sigma(factorIndex) * E(Lambda(factorIndex), tenor) * _factorPaths[factorIndex][timeIndex]; } var lnDF0t2 = -ZeroRatesT0.GetValue(t2) * IntervalInYears(simulationT0, t2); var lnDF0t1 = -ZeroRatesT0.GetValue(_timePoints[timeIndex].DateTime) * _timePoints[timeIndex].YearsFromBaseDate; double drift = GetDrift(timeIndex, tenor); return(NMath.Exp(lnDF0t2 - lnDF0t1 - 0.5 * drift + B)); }
public static IList <NArray> Evaluate(Func <NArray> function, IList <NArray> independentVariables, StringBuilder expressionsOut = null, Aggregator aggregator = Aggregator.ElementwiseAdd, IList <NArray> existingStorage = null, VectorExecutionOptions vectorOptions = null) { if (existingStorage != null && existingStorage.Count != independentVariables.Count + 1) { throw new ArgumentException(string.Format("storage provided does not match requirement for 1 result and {0} derivatives", independentVariables.Count)); } var timer = new ExecutionTimer(); timer.Start(); NArray[] outputs = new NArray[independentVariables.Count + 1]; var context = new DeferredExecutionContext(new VectorExecutionOptions(), independentVariables); NArray dependentVariable; try { // execute function as deferred operations and obtain reference to the dependentVariable dependentVariable = function(); } finally { context.Finish(); } timer.MarkFunctionComplete(); for (int i = 0; i < outputs.Length; ++i) { // if new storage is required, we create scalars in the first instance outputs[i] = (existingStorage == null) ? NArray.CreateScalar(0) : existingStorage[i]; } context._executor.Evaluate(context._options, outputs, dependentVariable, independentVariables, timer, expressionsOut, aggregator); //Console.WriteLine(timer.Report()); return(outputs); }
/// <summary> /// Calculate forward rate that applies between times t1 and t2 (t2 > t1) /// </summary> /// <param name="timeIndex"></param> /// <param name="t1"></param> /// <param name="t2"></param> /// <returns></returns> public NArray ForwardRate(int timeIndex, DateTime t1, DateTime t2) { var B = NArray.CreateScalar(0); var simulationT0 = _timePoints.First().DateTime; double tenor1 = IntervalInYears(_timePoints[timeIndex].DateTime, t1); double tenor2 = IntervalInYears(_timePoints[timeIndex].DateTime, t2); for (int factorIndex = 0; factorIndex < _factors.Length; ++factorIndex) { B += Sigma(factorIndex) * (E(Lambda(factorIndex), tenor1) - E(Lambda(factorIndex), tenor2)) * _factorPaths[factorIndex][timeIndex]; } var lnDF0t1 = -ZeroRatesT0.GetValue(t1) * IntervalInYears(simulationT0, t1); var lnDF0t2 = -ZeroRatesT0.GetValue(t2) * IntervalInYears(simulationT0, t2); double drift = GetDrift(timeIndex, tenor1) - GetDrift(timeIndex, tenor2); var dfRatio = NMath.Exp(lnDF0t1 - lnDF0t2 - 0.5 * drift + B); // df(t, t1) / df(t, t2) double alpha = IntervalInYears(t1, t2); return((dfRatio - 1) / alpha); }
/// <summary> /// Test of efficiency for a large number of simple vector operations. /// In particular, tests enhanced recycling of locals. /// </summary> public void SimpleTest() { // create 500 random vectors var vectorLength = 5000; var vectors = new NArray[500]; using (var randomStream = new RandomNumberStream(StorageLocation.Host, RandomNumberGeneratorType.MRG32K3A, 111)) { var normalDistribution = new Normal(randomStream, 0, 1); for (int i = 0; i < vectors.Length; ++i) { vectors[i] = NArray.CreateRandom(vectorLength, normalDistribution); } } var watch = new System.Diagnostics.Stopwatch(); watch.Start(); var result = NArray.CreateLike(vectors.First()); for (int i = 0; i < vectors.Length; ++i) { for (int j = 0; j < vectors.Length; ++j) { result.Add(vectors[i] * vectors[j] * 123); //result = result + vectors[i] * vectors[j] * 123; } } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); var arrays = vectors.Select(v => (v.Storage as ManagedStorage <double>).Array).ToArray(); watch.Restart(); var arrayResult = new double[vectors.First().Length]; for (int i = 0; i < vectors.Length; ++i) { for (int j = 0; j < vectors.Length; ++j) { for (int k = 0; k < arrayResult.Length; ++k) { arrayResult[k] += arrays[i][k] * arrays[j][k] * 123; } } } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); watch.Restart(); result = NArray.CreateLike(vectors.First()); for (int i = 0; i < vectors.Length; ++i) { var batch = NArray.Evaluate(() => { NArray res = NArray.CreateScalar(0); for (int j = 0; j < vectors.Length; ++j) { res = res + vectors[i] * vectors[j] * 123; } return(res); }); result += batch; } watch.Stop(); Console.WriteLine(watch.ElapsedMilliseconds); }
/// <summary> /// Simulate state variables needed for the pricing step of the exposure calculation. State variables /// are not independent variables of the adjoint algorithmic differentation, and therefore can be simulated in advance. /// </summary> /// <param name="model"></param> /// <param name="allZeroRatesT0"></param> /// <param name="timePoints"></param> /// <param name="graph"></param> /// <param name="pricers"></param> public void SimulateModel(out LinearGaussianModel model, out IEnumerable <NArray> allZeroRatesT0, out TimePoint[] timePoints, out SimulationGraph graph, out List <IPricer> pricers) { var testDate = new DateTime(2015, 12, 1); graph = new SimulationGraph(StorageLocation.Host, testDate); var context = graph.Context; context.Settings.SimulationCount = 5000; var fixedLeg = Enumerable.Range(0, 40).Select(i => new FixedCashflowDeal() { Notional = -1e6, Rate = 0.002, Currency = Currency.EUR, StartDate = testDate.AddMonths(3 * i), EndDate = testDate.AddMonths(3 * (i + 1)) }); var floatingLeg = Enumerable.Range(0, 40).Select(i => new FloatingCashflowDeal() { Notional = 1e6, Currency = Currency.EUR, StartDate = testDate.AddMonths(3 * i), EndDate = testDate.AddMonths(3 * (i + 1)) }); var correlationMatrix = context.Factory.CreateNArray(new double[, ] { { 1.0, -0.92, 0.5 }, { -0.92, 1.0, -0.8 }, { 0.5, -0.8, 1.0 } }); var identifiers = new string[] { "IR_DiscountFactor_EUR_Factor0", "IR_DiscountFactor_EUR_Factor1", "IR_DiscountFactor_EUR_Factor2" }; CorrelationHelper.AddMultivariateModelWeightsProvider(context, identifiers, correlationMatrix); pricers = fixedLeg.Select(d => new FixedCashflowPricer(d) as IPricer) .Concat(floatingLeg.Select(d => new FloatingCashflowPricer(d) as IPricer)).ToList(); foreach (var pricer in pricers) { pricer.Register(graph); } var testVariates0 = graph.RegisterFactor <NormalVariates>("IR_DiscountFactor_EUR_Factor0"); var testVariates1 = graph.RegisterFactor <NormalVariates>("IR_DiscountFactor_EUR_Factor1"); var testVariates2 = graph.RegisterFactor <NormalVariates>("IR_DiscountFactor_EUR_Factor2"); var testFactor = graph.RegisterModel <MeanRevertingNormalPathModel>("IR_DiscountFactor_EUR_Factor0"); model = graph.RegisterModel <LinearGaussianModel>("EUR"); var numeraire = graph.RegisterModel <NumeraireModel>("EUR"); model.Factors[0].Sigma = 0.02; model.Factors[0].Lambda = 0.05; model.Factors[1].Sigma = 0.03; model.Factors[1].Lambda = 0.2; model.Factors[2].Sigma = 0.01; model.Factors[2].Lambda = 1.0; var years = new double[] { 0, 1 / 365.35, 7 / 365.25, 14 / 365.25, 1 / 12, 2 / 12, 0.25, 0.5, 0.75, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60 }; var zeroRatesInPercent = new double[] { -0.3, -0.3, -0.29, -0.29, -0.3, -0.31, -0.31, -0.32, -0.32, -0.33, -0.34, -0.35, -0.35, -0.33, -0.28, -0.2, -0.11, -0.01, 0.1, 0.2, 0.37, 0.56, 0.71, 0.75, 0.76, 0.75, 0.75, 0.72, 0.7, 0.67, 0.64 }; model.ZeroRatesT0 = new Curve(years.Zip(zeroRatesInPercent, (y, r) => new DataPoint( testDate.AddDays(y * 365.25), NArray.CreateScalar(r / 100) )).ToArray()); var runner = graph.ToSimulationRunner(); runner.Prepare(); runner.Simulate(); timePoints = graph.Context.Settings.SimulationTimePoints; allZeroRatesT0 = model.ZeroRatesT0.Data.Select(d => d.Value); }