public void TestPriceCallOption()
        {
            // arrange
            var option           = GetEuropeanOption(true);
            var stochasticEngine = GetStochasticEngine(4321);
            var currentDate      = new DateTime(2019, 6, 30);
            var gbmParams        = new GbmParameters(0.02, 0.24, 51);

            // act
            var result = stochasticEngine.GetOptionValue(option, currentDate, gbmParams, 0.939413, 100000);

            // assert
            Assert.AreEqual(6.4418, result, 1e-4);
        }
        public void TestPriceDigitalPutCashSettled()
        {
            // arrange
            var option           = GetDigitalOption(false, false);
            var stochasticEngine = GetStochasticEngine(1221);
            var currentDate      = new DateTime(2019, 5, 31);
            var gbmParams        = new GbmParameters(0.01, 0.25, 84);

            // act
            var result = stochasticEngine.GetOptionValue(option, currentDate, gbmParams, 1, 100000);

            // assert
            Assert.AreEqual(0.4465, result, 1e-4);
        }
        public void TestPriceDigitalPutAssetSettled()
        {
            // arrange
            var option           = GetDigitalOption(false, true);
            var stochasticEngine = GetStochasticEngine(1243);
            var currentDate      = new DateTime(2019, 7, 20);
            var gbmParams        = new GbmParameters(0.04, 0.18, 75);

            // act
            var result = stochasticEngine.GetOptionValue(option, currentDate, gbmParams, 0.966378, 100000);

            // assert
            Assert.AreEqual(42.7009, result, 1e-4);
        }
        public void TestPricePutOption()
        {
            // arrange
            var option           = GetEuropeanOption(false);
            var stochasticEngine = GetStochasticEngine(1234);
            var currentDate      = new DateTime(2019, 6, 30);
            var gbmParams        = new GbmParameters(0.02, 0.20, 50);

            // act
            var result = stochasticEngine.GetOptionValue(option, currentDate, gbmParams, 0.939413, 100000);

            // assert
            Assert.AreEqual(3.7670, result, 1e-4);
        }
        public void TestGetGeometricBrownianMotion()
        {
            // arrange
            var stochasticEngine = GetStochasticEngine(1234);

            // act
            double timePeriod = 1.0 / 12.0;
            var    gbpParams  = new GbmParameters(0.05, 0.2, 50);
            var    result     = stochasticEngine.GetGeometricBrownianSeries(gbpParams, timePeriod, 7);

            // assert
            var expectedResult = new List <double> {
                50, 49.390526, 53.245843, 51.950346, 57.166804, 55.956294,
                61.642971
            };

            Assert.IsTrue(expectedResult.IsAlmostEqual(result, 1e-6));
        }
        public void TestGetStandardBrownianMotion()
        {
            // arrange
            var stochasticEngine = GetStochasticEngine(1234);

            // act
            double timePeriod = 1.0 / 12.0;
            var    gbmParams  = new GbmParameters(0.1, 0.18);
            var    result     = stochasticEngine.GetBrownianMotionSeries(gbmParams, timePeriod, 7);

            // assert
            var expectedResult = new List <double> {
                0, -0.004955, 0.068774, 0.052689, 0.144889, 0.131710,
                0.224903
            };

            Assert.IsTrue(expectedResult.IsAlmostEqual(result, 1e-6));
        }
        private SortedList <DateTime, OptionPricingData> GenerateOptionPricingData(DateTime startDate,
                                                                                   DateTime expiryDate,
                                                                                   GbmParameters gbmParams,
                                                                                   OptionPricingData basicPricingData,
                                                                                   int?seed)
        {
            int days        = startDate.GetWorkingDaysTo(expiryDate);
            var stockPrices = StochasticEngine.GetGeometricBrownianSeries(gbmParams, 1.0 / TimePeriods.BusinessDaysInYear, days, seed);
            var pricingData = new SortedList <DateTime, OptionPricingData>();
            var date        = startDate;

            if (!date.IsWorkingDay())
            {
                date = date.AddWorkingDay();
            }

            foreach (double price in stockPrices)
            {
                pricingData.Add(date, new OptionPricingData(price, basicPricingData.Vol, basicPricingData.InterestRate, basicPricingData.DivYield));
                date = date.AddWorkingDay();
            }

            return(pricingData);
        }
        public void PlotDailyPnL(DateTime startDate,
                                 OptionPricingData basicPricingData,
                                 List <HedgingStrategy> hedgingStrategies,
                                 int?seed = null)
        {
            ClearCharts();

            var gbmParameters = new GbmParameters(basicPricingData);
            var pricingData   = GenerateOptionPricingData(startDate, hedgingStrategies[0].ExpiryDate, gbmParameters, basicPricingData, seed);
            var minPrice      = double.PositiveInfinity;
            var maxPrice      = double.NegativeInfinity;

            var stockSeries = new LineSeries()
            {
                Title = @"Stock Price"
            };

            for (int i = 0; i < pricingData.Count; i++)
            {
                var stockPrice = pricingData.Values[i].CurrentPrice;
                stockSeries.Points.Add(new DataPoint(i, stockPrice));
                minPrice = Math.Min(minPrice, stockPrice);
                maxPrice = Math.Max(maxPrice, stockPrice);
            }

            PlotStockPrice.Axes.Add(new LinearAxis
            {
                Position  = AxisPosition.Bottom,
                Minimum   = 0,
                TextColor = OxyColors.Transparent
            });

            PlotStockPrice.Axes.Add(new OxyPlot.Axes.LinearAxis
            {
                Position = OxyPlot.Axes.AxisPosition.Left,
                Minimum  = (Math.Floor(minPrice / 5) - 1) * 5,
                Maximum  = (Math.Floor(maxPrice / 5) + 1) * 5
            });

            PlotStockPrice.Series.Add(stockSeries);

            var strike           = hedgingStrategies[0].Portfolio.Option.Strike;
            var strikeAnnotation = new LineAnnotation()
            {
                Y         = strike, MinimumX = 0, MaximumX = stockSeries.Points.Count, Color = OxyColors.Red,
                LineStyle = LineStyle.Solid, Type = LineAnnotationType.Horizontal
            };

            PlotStockPrice.Annotations.Add(strikeAnnotation);

            foreach (HedgingStrategy strategy in hedgingStrategies)
            {
                var pnl = strategy.GetDailyPnl(pricingData);

                var dailyPnlSeries = new ColumnSeries()
                {
                    Title = $"{strategy.Name} - Daily PnL"
                };
                var cumulativeSeries = new ColumnSeries()
                {
                    Title = $"{strategy.Name} - Cumulative PnL"
                };
                var cumulativePnl = new List <double>();

                foreach (KeyValuePair <DateTime, (double, double, double)> dailyPnl in pnl)
                {
                    // TODO: plot different PnL elements seperately
                    (double optionPnl, double hedgePnl, double cashPnl) = dailyPnl.Value;
                    var totalPnl = optionPnl + hedgePnl + cashPnl;
                    dailyPnlSeries.Items.Add(new ColumnItem(totalPnl));
                    if (cumulativePnl.Count == 0)
                    {
                        cumulativePnl.Add(totalPnl);
                    }
                    else
                    {
                        cumulativePnl.Add(cumulativePnl[cumulativePnl.Count - 1] + totalPnl);
                    }
                }

                foreach (double dailyVal in cumulativePnl)
                {
                    cumulativeSeries.Items.Add(new ColumnItem(dailyVal));
                }

                PlotModelDaily.Series.Add(dailyPnlSeries);
                PlotModelCumulative.Series.Add(cumulativeSeries);

                PlotModelDaily.Axes.Add(new CategoryAxis()
                {
                    Position      = AxisPosition.Bottom,
                    IsAxisVisible = false
                });

                PlotModelCumulative.Axes.Add(new CategoryAxis()
                {
                    Position      = AxisPosition.Bottom,
                    IsAxisVisible = false
                });

                RefreshCharts();
            }
        }