Exemple #1
0
        public LsmcBenchmarks()
        {
            var valDate = new Day(2019, 8, 29);

            #region Set Up Simple Storage
            var          storageStart           = new Day(2019, 12, 1);
            var          storageEnd             = new Day(2020, 4, 1);
            const double maxWithdrawalRate      = 850.0;
            const double maxInjectionRate       = 625.0;
            const double maxInventory           = 52_500.0;
            const double constantInjectionCost  = 1.25;
            const double constantWithdrawalCost = 0.93;

            var simpleDailyStorage = CmdtyStorage <Day> .Builder
                                     .WithActiveTimePeriod(storageStart, storageEnd)
                                     .WithConstantInjectWithdrawRange(-maxWithdrawalRate, maxInjectionRate)
                                     .WithZeroMinInventory()
                                     .WithConstantMaxInventory(maxInventory)
                                     .WithPerUnitInjectionCost(constantInjectionCost, injectionDate => injectionDate)
                                     .WithNoCmdtyConsumedOnInject()
                                     .WithPerUnitWithdrawalCost(constantWithdrawalCost, withdrawalDate => withdrawalDate)
                                     .WithNoCmdtyConsumedOnWithdraw()
                                     .WithNoCmdtyInventoryLoss()
                                     .WithNoInventoryCost()
                                     .MustBeEmptyAtEnd()
                                     .Build();

            #endregion Set Up Simple Storage

            const double oneFactorMeanReversion     = 12.5;
            const double oneFactorSpotVol           = 0.95;
            var          oneFDailyMultiFactorParams = MultiFactorParameters.For1Factor(oneFactorMeanReversion,
                                                                                       TimeSeriesFactory.ForConstantData(valDate, storageEnd, oneFactorSpotVol));
            const double flatInterestRate = 0.055;

            const int numInventorySpacePoints = 100;

            const double baseForwardPrice      = 53.5;
            const double forwardSeasonalFactor = 24.6;
            var          forwardCurve          = TimeSeriesFactory.FromMap(valDate, storageEnd, day =>
            {
                int daysForward = day.OffsetFrom(valDate);
                return(baseForwardPrice + Math.Sin(2.0 * Math.PI / 365.0 * daysForward) * forwardSeasonalFactor);
            });

            _valuationParameters = new LsmcValuationParameters <Day> .Builder
            {
                BasisFunctions = BasisFunctionsBuilder.Ones +
                                 BasisFunctionsBuilder.AllMarkovFactorAllPositiveIntegerPowersUpTo(RegressMaxDegree, 1),
                CurrentPeriod   = new Day(2019, 8, 29),
                DiscountFactors = StorageHelper.CreateAct65ContCompDiscounter(flatInterestRate),
                ForwardCurve    = forwardCurve,
                GridCalc        = FixedSpacingStateSpaceGridCalc.CreateForFixedNumberOfPointsOnGlobalInventoryRange(simpleDailyStorage, numInventorySpacePoints),
                Inventory       = 5_685,
                Storage         = simpleDailyStorage,
                SettleDateRule  = deliveryDate => Month.FromDateTime(deliveryDate.Start).Offset(1).First <Day>() + 19,               // Settlement on 20th of following month
            }
        public void GetGridPoints_StateSpaceLowerBoundHigherThanUpperBound_ThrowsArgumentException()
        {
            const double spacing = 15.0;
            const double stateSpaceLowerBound = 121.2;
            const double stateSpaceUpperBound = 121.19;

            var gridCalc = new FixedSpacingStateSpaceGridCalc(spacing);

            Assert.Throws <ArgumentException>(() =>
                                              gridCalc.GetGridPoints(stateSpaceLowerBound, stateSpaceUpperBound).ToArray());
        }
        public void GetGridPoints_StateSpaceLessThanSpacing_ReturnsStateSpaceLowerAndUpperBounds()
        {
            const double spacing = 50.0;
            const double stateSpaceLowerBound = 120.55;
            const double stateSpaceUpperBound = 161.89;

            var gridCalc = new FixedSpacingStateSpaceGridCalc(spacing);

            var gridPoints = gridCalc.GetGridPoints(stateSpaceLowerBound, stateSpaceUpperBound);

            var expectedGridPoints = new[] { stateSpaceLowerBound, stateSpaceUpperBound };

            Assert.Equal(expectedGridPoints, gridPoints);
        }
        public void GetGridPoints_StateSpaceLowerBoundEqualToUpperBound_ReturnsSinglePoint()
        {
            const double spacing = 15.0;
            const double stateSpaceLowerBound = 121.2;
            const double stateSpaceUpperBound = stateSpaceLowerBound;

            var gridCalc = new FixedSpacingStateSpaceGridCalc(spacing);

            var gridPoints = gridCalc.GetGridPoints(stateSpaceLowerBound, stateSpaceUpperBound);

            var expectedGridPoints = new[]
            {
                stateSpaceLowerBound
            };

            Assert.Equal(expectedGridPoints, gridPoints);
        }
        public void GetGridPoints_StateSpaceUpperEqualsLowerPlusSpacing_ReturnsStateSpaceLowerAndUpperBounds()
        {
            const double spacing = 15.0;
            const double stateSpaceLowerBound = 121.2;
            const double stateSpaceUpperBound = stateSpaceLowerBound + spacing;

            var gridCalc = new FixedSpacingStateSpaceGridCalc(spacing);

            var gridPoints = gridCalc.GetGridPoints(stateSpaceLowerBound, stateSpaceUpperBound);

            var expectedGridPoints = new[]
            {
                stateSpaceLowerBound,
                stateSpaceUpperBound
            };

            Assert.Equal(expectedGridPoints, gridPoints);
        }
        public void GetGridPoints_ReturnsStateSpaceLowerAndUpperBoundsSeparatedBySpacing()
        {
            const double spacing = 15.0;
            const double stateSpaceLowerBound = 121.2;
            const double stateSpaceUpperBound = 174.89;

            var gridCalc = new FixedSpacingStateSpaceGridCalc(spacing);

            var gridPoints = gridCalc.GetGridPoints(stateSpaceLowerBound, stateSpaceUpperBound);

            var expectedGridPoints = new[]
            {
                stateSpaceLowerBound,
                136.2,
                151.2,
                166.2,
                stateSpaceUpperBound,
            };

            Assert.Equal(expectedGridPoints, gridPoints);
        }
Exemple #7
0
                       Category = AddIn.ExcelFunctionCategory, IsThreadSafe = false, IsVolatile = false, IsExceptionSafe = true)] // TODO turn IsThreadSafe to true and use ConcurrentDictionary?
        public static object StorageValueThreeFactor(
            [ExcelArgument(Name = "Name", Description = "Name of cached object to create.")] string name,
            [ExcelArgument(Name = ExcelArg.StorageHandle.Name, Description = ExcelArg.StorageHandle.Description)] string storageHandle,
            [ExcelArgument(Name = ExcelArg.ValDate.Name, Description = ExcelArg.ValDate.Description)] DateTime valuationDate,
            [ExcelArgument(Name = ExcelArg.Inventory.Name, Description = ExcelArg.Inventory.Description)] double currentInventory,
            [ExcelArgument(Name = ExcelArg.ForwardCurve.Name, Description = ExcelArg.ForwardCurve.Description)] object forwardCurve,
            [ExcelArgument(Name = ExcelArg.InterestRateCurve.Name, Description = ExcelArg.InterestRateCurve.Description)] object interestRateCurve,
            [ExcelArgument(Name = ExcelArg.SpotVol.Name, Description = ExcelArg.SpotVol.Description)] double spotVol,
            [ExcelArgument(Name = ExcelArg.SpotMeanReversion.Name, Description = ExcelArg.SpotMeanReversion.Description)] double spotMeanReversion,
            [ExcelArgument(Name = ExcelArg.LongTermVol.Name, Description = ExcelArg.LongTermVol.Description)] double longTermVol,
            [ExcelArgument(Name = ExcelArg.SeasonalVol.Name, Description = ExcelArg.SeasonalVol.Description)] double seasonalVol,
            [ExcelArgument(Name = ExcelArg.DiscountDeltas.Name, Description = ExcelArg.DiscountDeltas.Description)] bool discountDeltas,
            [ExcelArgument(Name = ExcelArg.SettleDates.Name, Description = ExcelArg.SettleDates.Description)] object settleDatesIn,
            [ExcelArgument(Name = ExcelArg.NumSims.Name, Description = ExcelArg.NumSims.Description)] int numSims,
            [ExcelArgument(Name = ExcelArg.BasisFunctions.Name, Description = ExcelArg.BasisFunctions.Description)] string basisFunctionsIn,
            [ExcelArgument(Name = ExcelArg.Seed.Name, Description = ExcelArg.Seed.Description)] object seedIn,
            [ExcelArgument(Name = ExcelArg.ForwardSimSeed.Name, Description = ExcelArg.ForwardSimSeed.Description)] object fwdSimSeedIn,
            [ExcelArgument(Name = ExcelArg.NumGridPoints.Name, Description = ExcelArg.NumGridPoints.Description)] object numGlobalGridPointsIn,
            [ExcelArgument(Name = ExcelArg.NumericalTolerance.Name, Description = ExcelArg.NumericalTolerance.Description)] object numericalTolerance,
            [ExcelArgument(Name = ExcelArg.ExtraDecisions.Name, Description = ExcelArg.ExtraDecisions.Description)] object extraDecisions)
        {
            return(StorageExcelHelper.ExecuteExcelFunction(() =>
            {
                _calcWrappers[name] = ExcelCalcWrapper.CreateCancellable((cancellationToken, onProgress) =>
                {
                    // TODO provide alternative method for interpolating interest rates
                    Func <Day, double> interpolatedInterestRates =
                        StorageExcelHelper.CreateLinearInterpolatedInterestRateFunc(interestRateCurve, ExcelArg.InterestRateCurve.Name);

                    Func <Day, Day, double> discountFunc = StorageHelper.CreateAct65ContCompDiscounter(interpolatedInterestRates);
                    Day valDate = Day.FromDateTime(valuationDate);
                    Func <Day, Day> settleDateRule = StorageExcelHelper.CreateSettlementRule(settleDatesIn, ExcelArg.SettleDates.Name);

                    CmdtyStorage <Day> storage = _storageObjects[storageHandle];
                    int numGlobalGridPoints = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(numGlobalGridPointsIn, ExcelArg.NumGridPoints.Default,
                                                                                              ExcelArg.NumGridPoints.Name);

                    string basisFunctionsText = basisFunctionsIn.Replace("x_st", "x0").Replace("x_lt", "x1").Replace("x_sw", "x2");

                    var lsmcParamsBuilder = new LsmcValuationParameters <Day> .Builder
                    {
                        Storage = storage,
                        CurrentPeriod = valDate,
                        Inventory = currentInventory,
                        ForwardCurve = StorageExcelHelper.CreateDoubleTimeSeries <Day>(forwardCurve, ExcelArg.ForwardCurve.Name),
                        DiscountFactors = discountFunc,

                        DiscountDeltas = discountDeltas,
                        BasisFunctions = BasisFunctionsBuilder.Parse(basisFunctionsText),

                        ExtraDecisions = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(extraDecisions, 0, ExcelArg.ExtraDecisions.Name),
                        CancellationToken = cancellationToken,
                        OnProgressUpdate = onProgress,
                        GridCalc = FixedSpacingStateSpaceGridCalc.CreateForFixedNumberOfPointsOnGlobalInventoryRange(storage, numGlobalGridPoints),
                        NumericalTolerance = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(numericalTolerance, LsmcValuationParameters <Day> .Builder.DefaultNumericalTolerance, ExcelArg.NumericalTolerance.Description),
                        SettleDateRule = settleDateRule
                    };

                    // TODO test that this works with expired storage
                    Day endDate = new[] { valDate, storage.EndPeriod }.Max();
                    var threeFactorParams =
                        MultiFactorParameters.For3FactorSeasonal(spotMeanReversion, spotVol, longTermVol, seasonalVol, valDate, endDate);

                    // TODO better error messages if seedIn and fwdSimSeedIn cannot be cast
                    int?seed = StorageExcelHelper.IsExcelEmptyOrMissing(seedIn) ? (int?)null : (int)(double)seedIn;
                    int?fwdSimSeed = StorageExcelHelper.IsExcelEmptyOrMissing(fwdSimSeedIn) ? (int?)null : (int)(double)fwdSimSeedIn;

                    lsmcParamsBuilder.SimulateWithMultiFactorModelAndMersenneTwister(threeFactorParams, numSims, seed, fwdSimSeed);

                    return LsmcStorageValuation.WithNoLogger.Calculate(lsmcParamsBuilder.Build());
                });
                return name;
            }));
        }