Example #1
0
        public static CmdtyStorage <T> CreateCmdtyStorageFromExcelInputs <T>(DateTime storageStartDateTime,
                                                                             DateTime storageEndDateTime,
                                                                             object injectWithdrawConstraintsIn,
                                                                             string injectWithdrawInterpolationIn,
                                                                             double injectionCostRate,
                                                                             double cmdtyConsumedOnInjection,
                                                                             double withdrawalCostRate,
                                                                             double cmdtyConsumedOnWithdrawal,
                                                                             double newtonRaphsonAccuracy)
            where T : ITimePeriod <T>
        {
            T storageStart = TimePeriodFactory.FromDateTime <T>(storageStartDateTime);
            T storageEnd   = TimePeriodFactory.FromDateTime <T>(storageEndDateTime);

            if (injectWithdrawConstraintsIn is ExcelMissing || injectWithdrawConstraintsIn is ExcelEmpty)
            {
                throw new ArgumentException("Inject/withdraw constraints haven't been specified.");
            }

            if (!(injectWithdrawConstraintsIn is object[,] injectWithdrawArray))
            {
                throw new ArgumentException("Inject/withdraw constraints have been incorrectly entered. Argument value should be of a range with 4 columns, the first containing dates, the rest containing numbers.");
            }

            if (injectWithdrawArray.GetLength(1) != 4)
            {
                throw new ArgumentException("Inject/withdraw constraints have been incorrectly entered. Argument value should be a range 4 columns.");
            }

            var injectWithdrawGrouped = TakeWhileNotEmptyOrError(injectWithdrawArray).Select((row, i) => new
            {
                period       = ObjectToDateTime(row[0], $"Row {i + 1} of inject/withdraw/inventory constrains contains invalid date time in 1st column."),
                inventory    = ObjectToDouble(row[1], $"Row {i + 1} of inject/withdraw/inventory constraints contains invalid inventory in 2nd column as is not a number."),
                injectRate   = ObjectToDouble(row[2], $"Row {i + 1} of inject/withdraw/inventory constraints contains invalid injection rate in 3rd column as is not a number."),
                withdrawRate = ObjectToDouble(row[3], $"Row {i + 1} of inject/withdraw/inventory constraints contains invalid withdrawal in 4th column as is not a number.")
            }).GroupBy(arg => arg.period);

            var injectWithdrawConstraints = new List <InjectWithdrawRangeByInventoryAndPeriod <T> >();

            foreach (var injectWithdrawGroup in injectWithdrawGrouped)
            {
                T period = TimePeriodFactory.FromDateTime <T>(injectWithdrawGroup.Key);
                IEnumerable <InjectWithdrawRangeByInventory> injectWithdrawByInventory = injectWithdrawGroup.Select(arg =>
                                                                                                                    new InjectWithdrawRangeByInventory(arg.inventory, new InjectWithdrawRange(-arg.withdrawRate, arg.injectRate)));
                injectWithdrawConstraints.Add(new InjectWithdrawRangeByInventoryAndPeriod <T>(period, injectWithdrawByInventory));
            }

            InterpolationType interpolationType;

            if (injectWithdrawInterpolationIn == "PiecewiseLinear")
            {
                interpolationType = InterpolationType.PiecewiseLinear;
            }
            else if (injectWithdrawInterpolationIn == "Polynomial")
            {
                interpolationType = InterpolationType.PolynomialWithParams(newtonRaphsonAccuracy);
            }
            else
            {
                throw new ArgumentException($"Value of Inject_withdraw_interpolation '{injectWithdrawInterpolationIn}' not recognised. Must be either 'PiecewiseLinear' or 'Polynomial'.");
            }

            CmdtyStorage <T> storage = CmdtyStorage <T> .Builder
                                       .WithActiveTimePeriod(storageStart, storageEnd)
                                       .WithTimeAndInventoryVaryingInjectWithdrawRates(injectWithdrawConstraints, interpolationType)
                                       .WithPerUnitInjectionCost(injectionCostRate)
                                       .WithFixedPercentCmdtyConsumedOnInject(cmdtyConsumedOnInjection)
                                       .WithPerUnitWithdrawalCost(withdrawalCostRate)
                                       .WithFixedPercentCmdtyConsumedOnWithdraw(cmdtyConsumedOnWithdrawal)
                                       .WithNoCmdtyInventoryLoss()
                                       .WithNoInventoryCost()
                                       .MustBeEmptyAtEnd()
                                       .Build();

            return(storage);
        }