GenerateValuationResults_CurrentPeriodEqualToStorageEndStorageInventoryHasTerminalValue(double startingInventory,
                                                                                                double forwardPrice)
        {
            var storageStart = new Day(2019, 9, 1);
            var storageEnd   = new Day(2019, 9, 30);

            TimeSeries <Month, Day> settlementDates = new TimeSeries <Month, Day> .Builder
            {
                { new Month(2019, 9), new Day(2019, 10, 5) }
            }.Build();

            CmdtyStorage <Day> storage = CmdtyStorage <Day> .Builder
                                         .WithActiveTimePeriod(storageStart, storageEnd)
                                         .WithConstantInjectWithdrawRange(-45.5, 56.6)
                                         .WithConstantMinInventory(0.0)
                                         .WithConstantMaxInventory(1000.0)
                                         .WithPerUnitInjectionCost(0.8, injectionDate => injectionDate)
                                         .WithNoCmdtyConsumedOnInject()
                                         .WithPerUnitWithdrawalCost(1.2, withdrawalDate => withdrawalDate)
                                         .WithNoCmdtyConsumedOnWithdraw()
                                         .WithNoCmdtyInventoryLoss()
                                         .WithNoInventoryCost()
                                         .WithTerminalInventoryNpv((cmdtyPrice, terminalInventory) => cmdtyPrice * terminalInventory - 999.0)
                                         .Build();

            var forwardCurve = new TimeSeries <Day, double> .Builder(1)
            {
                { storageEnd, forwardPrice }
            }

            .Build();

            IntrinsicStorageValuationResults <Day> valuationResults = IntrinsicStorageValuation <Day>
                                                                      .ForStorage(storage)
                                                                      .WithStartingInventory(startingInventory)
                                                                      .ForCurrentPeriod(storageEnd)
                                                                      .WithForwardCurve(forwardCurve)
                                                                      .WithMonthlySettlement(settlementDates)
                                                                      .WithDiscountFactorFunc((valuationDate, cashFlowDate) => 1.0) // No discounting
                                                                      .WithFixedGridSpacing(10.0)
                                                                      .WithLinearInventorySpaceInterpolation()
                                                                      .WithNumericalTolerance(1E-10)
                                                                      .Calculate();

            return(valuationResults);
        }
Exemple #2
0
        private static IntrinsicStorageValuationResults <T> IntrinsicStorageVal <T>(
            DateTime valuationDateTime,
            DateTime storageStartDateTime,
            DateTime storageEndDateTime,
            object injectWithdrawConstraints,
            string injectWithdrawInterpolation,
            double injectionCostRate,
            double cmdtyConsumedOnInjection,
            double withdrawalCostRate,
            double cmdtyConsumedOnWithdrawal,
            double currentInventory,
            object forwardCurveIn,
            object interestRateCurve,
            object numGlobalGridPointsIn,
            object numericalToleranceIn)
            where T : ITimePeriod <T>
        {
            double numericalTolerance = StorageExcelHelper.DefaultIfExcelEmptyOrMissing(numericalToleranceIn, 1E-10,
                                                                                        "Numerical_tolerance");

            var storage = StorageExcelHelper.CreateCmdtyStorageFromExcelInputs <T>(storageStartDateTime,
                                                                                   storageEndDateTime, injectWithdrawConstraints, injectWithdrawInterpolation, injectionCostRate, cmdtyConsumedOnInjection,
                                                                                   withdrawalCostRate, cmdtyConsumedOnWithdrawal, numericalTolerance);

            T currentPeriod = TimePeriodFactory.FromDateTime <T>(valuationDateTime);

            TimeSeries <T, double> forwardCurve = StorageExcelHelper.CreateDoubleTimeSeries <T>(forwardCurveIn, "Forward_curve");

            // TODO input settlement dates and use interest rates
            int numGridPoints =
                StorageExcelHelper.DefaultIfExcelEmptyOrMissing <int>(numGlobalGridPointsIn, 100, "Num_global_grid_points");

            IntrinsicStorageValuationResults <T> valuationResults = IntrinsicStorageValuation <T>
                                                                    .ForStorage(storage)
                                                                    .WithStartingInventory(currentInventory)
                                                                    .ForCurrentPeriod(currentPeriod)
                                                                    .WithForwardCurve(forwardCurve)
                                                                    .WithCmdtySettlementRule(period => period.First <Day>())    // TODO get rid if this
                                                                    .WithDiscountFactorFunc((currentDate, cashFlowDate) => 1.0) // TODO add proper discounting
                                                                    .WithFixedNumberOfPointsOnGlobalInventoryRange(numGridPoints)
                                                                    .WithLinearInventorySpaceInterpolation()
                                                                    .WithNumericalTolerance(numericalTolerance)
                                                                    .Calculate();

            return(valuationResults);
        }
Exemple #3
0
        static void Main(string[] args)
        {
            const double constantMaxInjectRate   = 5.26;
            const double constantMaxWithdrawRate = 14.74;
            const double constantMaxInventory    = 1100.74;
            const double constantMinInventory    = 0.0;
            const double constantInjectionCost   = 0.48;
            const double constantWithdrawalCost  = 0.74;

            CmdtyStorage <Day> storage = CmdtyStorage <Day> .Builder
                                         .WithActiveTimePeriod(new Day(2019, 9, 1), new Day(2019, 10, 1))
                                         .WithConstantInjectWithdrawRange(-constantMaxWithdrawRate, constantMaxInjectRate)
                                         .WithConstantMinInventory(constantMinInventory)
                                         .WithConstantMaxInventory(constantMaxInventory)
                                         .WithPerUnitInjectionCost(constantInjectionCost, injectionDate => injectionDate)
                                         .WithNoCmdtyConsumedOnInject()
                                         .WithPerUnitWithdrawalCost(constantWithdrawalCost, withdrawalDate => withdrawalDate)
                                         .WithNoCmdtyConsumedOnWithdraw()
                                         .WithNoCmdtyInventoryLoss()
                                         .WithNoCmdtyInventoryCost()
                                         .MustBeEmptyAtEnd()
                                         .Build();

            var currentPeriod = new Day(2019, 9, 15);

            const double lowerForwardPrice = 56.6;
            const double forwardSpread     = 87.81;

            double higherForwardPrice = lowerForwardPrice + forwardSpread;

            var forwardCurveBuilder = new TimeSeries <Day, double> .Builder();

            foreach (var day in new Day(2019, 9, 15).EnumerateTo(new Day(2019, 9, 22)))
            {
                forwardCurveBuilder.Add(day, lowerForwardPrice);
            }

            foreach (var day in new Day(2019, 9, 23).EnumerateTo(new Day(2019, 10, 1)))
            {
                forwardCurveBuilder.Add(day, higherForwardPrice);
            }

            const double startingInventory = 50.0;

            IntrinsicStorageValuationResults <Day> valuationResults = IntrinsicStorageValuation <Day>
                                                                      .ForStorage(storage)
                                                                      .WithStartingInventory(startingInventory)
                                                                      .ForCurrentPeriod(currentPeriod)
                                                                      .WithForwardCurve(forwardCurveBuilder.Build())
                                                                      .WithCmdtySettlementRule(day => day.First <Month>().Offset(1).First <Day>().Offset(5)) // Commodity is settled on the 5th day of the next month
                                                                      .WithDiscountFactorFunc(day => 1.0)                                                    // Assumes to discounting
                                                                      .WithFixedGridSpacing(10.0)
                                                                      .WithLinearInventorySpaceInterpolation()
                                                                      .WithNumericalTolerance(1E-12)
                                                                      .Calculate();

            Console.WriteLine("Calculated intrinsic storage NPV: " + valuationResults.NetPresentValue.ToString("F2"));
            Console.WriteLine();
            Console.WriteLine("Decision profile:");
            Console.WriteLine(valuationResults.DecisionProfile.FormatData("F2", -1));

            Console.WriteLine("Press any key to exit");
            Console.ReadKey();
        }