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(); } }