private static void Creating() { #region creating TimeSeries <Quarter, decimal> timeSeriesFromConstructor1 = new TimeSeries <Quarter, decimal>( Quarter.CreateQuarter1(2020), new [] { 21.3M, 42.4M, 42.5M }); Console.WriteLine(timeSeriesFromConstructor1); Console.WriteLine(); var timeSeriesFromConstructor2 = new TimeSeries <Day, double>( new [] { new Day(2019, 9, 17), new Day(2019, 9, 18), new Day(2019, 9, 19) }, new [] { 242.4, 224.42, 262.04 }); Console.WriteLine(timeSeriesFromConstructor2); Console.WriteLine(); var builder = new TimeSeries <Month, int> .Builder { { Month.CreateJanuary(2019), 1 }, { Month.CreateFebruary(2019), 2 }, { Month.CreateMarch(2019), 3 } }; builder.Add(Month.CreateApril(2019), 4); TimeSeries <Month, int> timeSeriesFromBuilder = builder.Build(); Console.WriteLine(timeSeriesFromBuilder); Console.WriteLine(); TimeSeries <Day, string> emptyTimeSeries = TimeSeries <Day, String> .Empty; Console.WriteLine(emptyTimeSeries); #endregion }
private static TimeSeries <Day, double> GenerateBackwardatedCurve(Day storageStart, Day storageEnd) { var forwardCurveBuilder = new TimeSeries <Day, double> .Builder(); double forwardPrice = 59.95; foreach (Day forwardCurvePoint in storageStart.EnumerateTo(storageEnd)) { forwardCurveBuilder.Add(forwardCurvePoint, forwardPrice); forwardPrice -= 0.58; } return(forwardCurveBuilder.Build()); }
public static TimeSeries <TIndex, TData> CreateTimeSeries <TIndex, TData>(object excelValues, string excelArgumentName, TryCreateData <TData> tryCreateData) where TIndex : ITimePeriod <TIndex> { if (excelValues is ExcelMissing || excelValues is ExcelEmpty) { throw new ArgumentException(excelArgumentName + " hasn't been specified."); } if (!(excelValues is object[,] excelValuesArray)) { throw new ArgumentException(excelArgumentName + " has been incorrectly entered. Argument value should be of a range with 2 columns, the first containing dates, the second containing numbers."); } if (excelValuesArray.GetLength(1) != 2) { throw new ArgumentException(excelArgumentName + " has been incorrectly entered. Argument value should be a range with 2 columns."); } var builder = new TimeSeries <TIndex, TData> .Builder(); for (int i = 0; i < excelValuesArray.GetLength(0); i++) { if (excelValuesArray[i, 0] is ExcelEmpty || excelValuesArray[i, 0] is ExcelError) { break; } object dataValueIn = excelValuesArray[i, 1]; if (!tryCreateData(dataValueIn, out TData dataValue)) { throw new ArgumentException($"Value in the second column of row {i} for argument {excelArgumentName} cannot be converted to type {typeof(TData).Name}."); } DateTime curvePointDateTime = ObjectToDateTime(excelValuesArray[i, 0], $"Cannot create DateTime from value in first row of argument {excelArgumentName}."); TIndex curvePointPeriod = TimePeriodFactory.FromDateTime <TIndex>(curvePointDateTime); builder.Add(curvePointPeriod, dataValue); } return(builder.Build()); }
private static IntrinsicStorageValuationResults <Day> IntrinsicValuationZeroInventoryForwardCurveWithSpread(double forwardSpread) { var currentPeriod = new Day(2019, 9, 15); const double lowerForwardPrice = 56.6; 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, 9, 30))) { forwardCurveBuilder.Add(day, higherForwardPrice); } IntrinsicStorageValuationResults <Day> valuationResults = GenerateValuationResults(0.0, forwardCurveBuilder.Build(), currentPeriod); return(valuationResults); }
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(); }