Пример #1
0
        private static TreeStorageValuationResults <T> TrinomialStorageValuation <T>(
            DateTime valuationDateTime,
            DateTime storageStartDateTime,
            DateTime storageEndDateTime,
            object ratchets,
            string injectWithdrawInterpolation,
            double injectionCostRate,
            double cmdtyConsumedOnInjection,
            double withdrawalCostRate,
            double cmdtyConsumedOnWithdrawal,
            double currentInventory,
            object forwardCurveIn,
            object spotVolatilityCurveIn,
            double meanReversion,
            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, ratchets, injectWithdrawInterpolation, injectionCostRate, cmdtyConsumedOnInjection,
                                                                                   withdrawalCostRate, cmdtyConsumedOnWithdrawal, numericalTolerance);

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

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

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

            double timeDelta = 1.0 / 365.0; // TODO remove this hard coding

            Func <Day, double> interpolatedInterestRates =
                StorageExcelHelper.CreateLinearInterpolatedInterestRateFunc(interestRateCurve, ExcelArg.InterestRateCurve.Name);

            TreeStorageValuationResults <T> valuationResults = TreeStorageValuation <T>
                                                               .ForStorage(storage)
                                                               .WithStartingInventory(currentInventory)
                                                               .ForCurrentPeriod(currentPeriod)
                                                               .WithForwardCurve(forwardCurve)
                                                               .WithOneFactorTrinomialTree(spotVolatilityCurve, meanReversion, timeDelta)
                                                               .WithCmdtySettlementRule(period => period.First <Day>()) // TODO get rid if this
                                                               .WithAct365ContinuouslyCompoundedInterestRate(interpolatedInterestRates)
                                                               .WithFixedNumberOfPointsOnGlobalInventoryRange(numGridPoints)
                                                               .WithLinearInventorySpaceInterpolation()
                                                               .WithNumericalTolerance(numericalTolerance)
                                                               .Calculate();

            return(valuationResults);
        }
Пример #2
0
        public void Calculate_StorageLooksLikeCallOptions_NpvEqualsBlack76()
        {
            const double percentTolerance = 0.005; // 0.5% tolerance
            var          currentDate      = new Day(2019, 8, 29);

            (DoubleTimeSeries <Day> forwardCurve, DoubleTimeSeries <Day> spotVolCurve) =
                TestHelper.CreateDailyTestForwardAndSpotVolCurves(currentDate, new Day(2020, 4, 1));
            const double meanReversion = 16.5;
            const double timeDelta     = 1.0 / 365.0;
            const double interestRate  = 0.09;

            TestHelper.CallOptionLikeTestData testData = TestHelper.CreateThreeCallsLikeStorageTestData(forwardCurve);

            TreeStorageValuationResults <Day> valuationResults =
                TreeStorageValuation <Day> .ForStorage(testData.Storage)
                .WithStartingInventory(testData.Inventory)
                .ForCurrentPeriod(currentDate)
                .WithForwardCurve(forwardCurve)
                .WithOneFactorTrinomialTree(spotVolCurve, meanReversion, timeDelta)
                .WithMonthlySettlement(testData.SettleDates)
                .WithAct365ContinuouslyCompoundedInterestRate(day => interestRate) // Constant interest rate
                .WithFixedNumberOfPointsOnGlobalInventoryRange(100)
                .WithLinearInventorySpaceInterpolation()
                .WithNumericalTolerance(1E-10)
                .Calculate();

            // Calculate value of equivalent call options
            double expectStorageValue = 0.0;

            foreach (TestHelper.CallOption option in testData.CallOptions)
            {
                double impliedVol   = TestHelper.OneFactorImpliedVol(currentDate, option.ExpiryDate, spotVolCurve, meanReversion);
                double forwardPrice = forwardCurve[option.ExpiryDate];
                double black76Value = TestHelper.Black76CallOptionValue(currentDate, forwardPrice,
                                                                        impliedVol, interestRate, option.StrikePrice, option.ExpiryDate,
                                                                        option.SettleDate) * option.NotionalVolume;
                expectStorageValue += black76Value;
            }

            double percentError = (valuationResults.NetPresentValue - expectStorageValue) / expectStorageValue;

            Assert.InRange(percentError, -percentTolerance, percentTolerance);
        }
Пример #3
0
 internal DecisionSimulator(TreeStorageValuationResults <T> valuationResults, TreeStorageValuation <T> storageValuation)
 {
     ValuationResults  = valuationResults;
     _storageValuation = storageValuation;
 }