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 }
public void CreateQuarter1_AsExpected(int year) { var quarter = Quarter.CreateQuarter1(year); var expected = new Quarter(year, 1); Assert.AreEqual(expected, quarter); }
private static void ConvertingGranularity() { #region converting_granularity var qu119 = Quarter.CreateQuarter1(2019); Console.WriteLine("The first month in Q1-19 is " + qu119.First <Month>()); Console.WriteLine("The last month in Q1-19 is " + qu119.Last <Month>()); Console.WriteLine(); #endregion converting_granularity }
public void Price_MonthlyCurveBusinessDayWeight_EqualsWeightedAverage() { var curve = new DoubleCurve <Month>(Month.CreateJanuary(2020), new[] { 56.54, 54.15, 51.14 }, Weighting.BusinessDayCount <Month>(new Day[0])); double q1Price = curve.Price(Quarter.CreateQuarter1(2020)); const double expectedQ1Price = (56.54 * 23.0 + 54.15 * 20.0 + 51.14 * 22.0) / 65.0; Assert.AreEqual(expectedQ1Price, q1Price); }
public void Bootstrap_WithContractsAndSpreadJointlyRedundant_ThrowsArgumentException() { var feb20 = Month.CreateFebruary(2020); var mar20 = Month.CreateMarch(2020); IBootstrapperAddOptionalParameters <Month> bootstrapper = new Bootstrapper <Month>() .AddContract(Month.CreateJanuary(2020), 22.95) .AddContract(feb20, 21.05) .AddContract(Quarter.CreateQuarter1(2020), 19.05) .AddShaping(Shaping <Month> .Spread.Between(feb20).And(mar20).Is(0.21)); Assert.Throws(Is.TypeOf <ArgumentException>().And.Message.EqualTo("Redundant contracts and shapings are present"), () => bootstrapper.Bootstrap()); }
public void BuilderWithData_ConstructedWithCapacityParameter_AddsPointsToBuiltSeries() { var curve = new DoubleCurve <Month> .Builder(1, month => 1.0) .WithData(Month.CreateJanuary(2019), 1.0) .WithData(Month.CreateFebruary(2019), 2.0) .WithData(Month.CreateMarch(2019), 3.0) .Build(); Assert.AreEqual(3, curve.Count); Assert.AreEqual(1.0, curve[Month.CreateJanuary(2019)]); Assert.AreEqual(2.0, curve[Month.CreateFebruary(2019)]); Assert.AreEqual(3.0, curve[Month.CreateMarch(2019)]); Assert.AreEqual(2.0, curve.Price(Quarter.CreateQuarter1(2019))); }
private static void Creating() { #region creating var mar19 = new Month(2019, 3); Console.WriteLine(mar19); var aug19 = Month.CreateAugust(2019); Console.WriteLine(aug19); var qu119 = Quarter.CreateQuarter1(2019); Console.WriteLine(qu119); Day christmas2020 = Day.FromDateTime(new DateTime(2020, 12, 25)); Console.WriteLine(christmas2020); Console.WriteLine(); #endregion }
public void BuilderBuild_ConstructedWithCapacityParameter_AsExpected() { var curve = new DoubleCurve <Month> .Builder(2, month => 1.0) { { Month.CreateJanuary(2019), 1.0 }, { Month.CreateFebruary(2019), 2.0 }, { Month.CreateMarch(2019), 3.0 } } .Build(); Assert.AreEqual(3, curve.Count); Assert.AreEqual(1.0, curve[Month.CreateJanuary(2019)]); Assert.AreEqual(2.0, curve[Month.CreateFebruary(2019)]); Assert.AreEqual(3.0, curve[Month.CreateMarch(2019)]); Assert.AreEqual(2.0, curve.Price(Quarter.CreateQuarter1(2019))); }
public void Bootstrap_AverageWeightingNotAdded_ResultsConsistentWithPeriodLengthWeight() { const double janPrice = 85.69; const double febPrice = 88.000085; const double q1Price = 90.1005968; DoubleCurve <Month> curve = new Bootstrapper <Month>() .AddContract(Month.CreateJanuary(2019), janPrice) .AddContract(Month.CreateFebruary(2019), febPrice) .AddContract(Quarter.CreateQuarter1(2019), q1Price) .Bootstrap() .Curve; double backCalculatedQ1Price = (curve[Month.CreateJanuary(2019)] * 31.0 + curve[Month.CreateFebruary(2019)] * 28.0 + curve[Month.CreateMarch(2019)] * 31.0) / (31.0 + 28.0 + 31.0); Assert.AreEqual(q1Price, backCalculatedQ1Price, Tolerance); }
static void Main() { //=============================================================================================== // BASIC BOOTSTRAPPING CALCULATION // Bootstrapping 1 quarterly price and 1 monthly price into a monthly curve BootstrapResults <Month> bootstrapResults = new Bootstrapper <Month>() .AddContract(Month.CreateJanuary(2020), 19.05) .AddContract(Quarter.CreateQuarter1(2020), 17.22) .Bootstrap(); Console.WriteLine("Derived piecewise flat curve:"); Console.WriteLine(bootstrapResults.Curve.FormatData("F5")); Console.WriteLine(); Console.WriteLine("Equivalent bootstrapped contracts:"); foreach (Contract <Month> contract in bootstrapResults.BootstrappedContracts) { Console.WriteLine(contract); } Console.WriteLine(); Console.WriteLine(); //=============================================================================================== // APPLYING SHAPING DURING BOOTSTRAPPING var jan20 = Month.CreateJanuary(2020); var feb20 = Month.CreateFebruary(2020); var mar20 = Month.CreateMarch(2020); // Shaping applied as a ratio between Feb and Mar const double ratio = 1.1; var(pieceWiseCurveWithRatio, _) = new Bootstrapper <Month>() .AddContract(jan20, 19.05) .AddContract(Quarter.CreateQuarter1(2020), 17.22) .AddShaping(Shaping <Month> .Ratio.Between(feb20).And(mar20).Is(ratio)) .Bootstrap(); Console.WriteLine($"Derived piecewise flat curve with {ratio} ratio applied between Feb and Mar:"); Console.WriteLine(pieceWiseCurveWithRatio.FormatData("F5")); Console.WriteLine(); Console.WriteLine("Ratio in derived curve: {0:F5}", pieceWiseCurveWithRatio[feb20] / pieceWiseCurveWithRatio[mar20]); Console.WriteLine(); Console.WriteLine(); // Shaping applied as a spread between Feb and Mar const double spread = 0.21; var(pieceWiseCurveWithSpread, _) = new Bootstrapper <Month>() .AddContract(jan20, 19.05) .AddContract(Quarter.CreateQuarter1(2020), 17.22) .AddShaping(Shaping <Month> .Spread.Between(feb20).And(mar20).Is(spread)) .Bootstrap(); Console.WriteLine($"Derived piecewise flat curve with {spread} spread applied between Feb and Mar:"); Console.WriteLine(pieceWiseCurveWithSpread.FormatData("F5")); Console.WriteLine(); Console.WriteLine("Spread in derived curve: {0:F5}", pieceWiseCurveWithSpread[feb20] - pieceWiseCurveWithSpread[mar20]); Console.WriteLine(); Console.WriteLine(); //=============================================================================================== // HANDLING REDUNDANCY OF CONTRACTS AND SHAPING FACTORS try { // If the price of Feb-20 is added, this essentially represents redundancy in the inputs, resulting in an exception new Bootstrapper <Month>() .AddContract(jan20, 22.95) .AddContract(feb20, 21.05) .AddContract(Quarter.CreateQuarter1(2020), 19.05) .AddShaping(Shaping <Month> .Spread.Between(feb20).And(mar20).Is(spread)) .Bootstrap(); } catch (ArgumentException e) { Console.WriteLine("Exception raised when redundancy inputs provided:"); Console.WriteLine(e); } Console.WriteLine(); Console.WriteLine(); // Using AllowRedundancy() allows the calculation to perform without checks on redundancy var(pieceWiseCurveWithRedundancy, _) = new Bootstrapper <Month>() .AddContract(jan20, 22.95) .AddContract(feb20, 21.05) .AddContract(Quarter.CreateQuarter1(2020), 19.05) .AddShaping(Shaping <Month> .Spread.Between(feb20).And(mar20).Is(spread)) .AllowRedundancy() .Bootstrap(); Console.WriteLine("Derived piecewise flat curve with redundant inputs, after AllowRedundancy() called:"); Console.WriteLine(pieceWiseCurveWithRedundancy.FormatData("F5")); Console.WriteLine(); Console.WriteLine(); //=============================================================================================== // APPLYING AN ALTERNATIVE WEIGHTING SCHEME // By default, the bootstrap calculations assume averages are weighted by the number of minutes in a contract period. // This assumption is fine for instruments where the commodity is delivered at a constant rate, e.g. natural gas forwards. // An alternative weighting scheme can be added by calling WithAverageWeighting and supplying a weighting scheme as a function. // The below example makes use of the Weighting helper class to provide the weighting function as the count of business days. // An example of when such a weighting scheme should be used is for oil swaps, based on an index which is only published on a business day. var holidays = new List <Day>() { new Day(2020, 1, 1) }; Func <Month, double> busDayWeight = Weighting.BusinessDayCount <Month>(holidays); var(pieceWiseCurveBusDayWeight, _) = new Bootstrapper <Month>() .AddContract(jan20, 19.05) .AddContract(Quarter.CreateQuarter1(2020), 17.22) .WithAverageWeighting(busDayWeight) .Bootstrap(); Console.WriteLine("Derived piecewise flat curve with business day weighting:"); Console.WriteLine(pieceWiseCurveBusDayWeight.FormatData("F5")); Console.ReadKey(); }
static void Main(string[] args) { // The following code shows how to use the spline to derive a smooth daily curve from // monthly and quarterly granularity input contract prices. Also demonstrated is the // optional seasonal adjustment factor, in this case used to apply day-of-week seasonality. var dayOfWeekAdjustment = new Dictionary <DayOfWeek, double> { [DayOfWeek.Monday] = 0.95, [DayOfWeek.Tuesday] = 0.99, [DayOfWeek.Wednesday] = 1.05, [DayOfWeek.Thursday] = 1.01, [DayOfWeek.Friday] = 0.98, [DayOfWeek.Saturday] = 0.92, [DayOfWeek.Sunday] = 0.91 }; DoubleCurve <Day> curve = new MaxSmoothnessSplineCurveBuilder <Day>() .AddContract(Month.CreateJuly(2019), 77.98) .AddContract(Month.CreateAugust(2019), 76.01) .AddContract(Month.CreateSeptember(2019), 78.74) .AddContract(Quarter.CreateQuarter4(2019), 85.58) .AddContract(Quarter.CreateQuarter1(2020), 87.01) .WithMultiplySeasonalAdjustment(day => dayOfWeekAdjustment[day.DayOfWeek]) .BuildCurve(); Console.WriteLine(curve.FormatData("F5")); Console.WriteLine(); Console.WriteLine(); //=============================================================================================== // APPLYING AN ALTERNATIVE WEIGHTING SCHEME // By default, the spline calculations assume averages are weighted by the number of minutes in a contract period. // This assumption is fine for instruments where the commodity is delivered at a constant rate, e.g. natural gas forwards. // An alternative weighting scheme can be added by calling WithAverageWeighting and supplying a weighting scheme as a function. // The below example makes use of the Weighting helper class to provide the weighting function as the count of business days. // An example of when such a weighting scheme should be used is for oil swaps, based on an index which is only published on a business day // to create a monthly curve from quarterly granularity inputs. var holidays = new List <Day>() { new Day(2020, 1, 1) }; Func <Month, double> busDayWeight = Weighting.BusinessDayCount <Month>(holidays); var contracts = new List <Contract <Month> >() { Contract <Month> .Create(Quarter.CreateQuarter4(2019), 76.58), Contract <Month> .Create(Quarter.CreateQuarter1(2020), 77.20), Contract <Month> .Create(Quarter.CreateQuarter2(2020), 76.01), Contract <Month> .Create(Quarter.CreateQuarter3(2020), 74.95), Contract <Month> .Create(Quarter.CreateQuarter4(2020), 74.92), }; DoubleCurve <Month> curveBusDayWeight = new MaxSmoothnessSplineCurveBuilder <Month>() .AddContracts(contracts) .WithWeighting(busDayWeight) .BuildCurve(); Console.WriteLine("Derived smooth curve with business day weighting:"); Console.WriteLine(curveBusDayWeight.FormatData("F5", -1)); Console.ReadKey(); }