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);
        }
Example #2
0
        /// <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));
        }
Example #3
0
        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);
        }
Example #4
0
        /// <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);
        }