示例#1
0
        public void Bootstrap_WithZeroWeightedContract_ThrowsArgumentException()
        {
            var builder = new Bootstrapper <Day>()
                          .AddContract(new Day(2019, 1, 7), new Day(2019, 1, 13), 58.45)
                          .AddContract(new Day(2019, 1, 12), new Day(2019, 1, 13), 60.87)
                          .WithAverageWeighting(Weighting.BusinessDayCount <Day>(new List <Day>()));

            Assert.Throws(Is.TypeOf <ArgumentException>().And.Message.EqualTo(
                              "sum of weighting evaluated to non-positive number for the following contract: Start: 2019-01-12, End: 2019-01-13, Price: 60.87"),
                          () => builder.Bootstrap());
        }
示例#2
0
        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);
        }
示例#3
0
        public void PriceStartAndEndParameters_MonthlyCurveBusinessDayWeight_EqualsWeightedAverage()
        {
            var curve = new DoubleCurve <Month>(Month.CreateJanuary(2020), new [] { 56.54, 54.15, 51.14 },
                                                Weighting.BusinessDayCount <Month>(new Day[0]));

            double febMarPrice = curve.Price(Month.CreateFebruary(2020), Month.CreateMarch(2020));

            const double expectedFebMarPrice = (54.15 * 20.0 + 51.14 * 22.0) / 42.0;

            Assert.AreEqual(expectedFebMarPrice, febMarPrice);
        }
示例#4
0
        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();
        }
示例#5
0
        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();
        }