public void Task_2_2_3() { // Variance Process Values double Kappa = 1.5768; double Theta = 0.0398; double Sigma = 0.5751; double V0 = 0.0175; double Rho = -0.5711; // Heston Model Params double InitialStockPrice = 100; double RiskFreeRate = 0.025; // Option Params double StrikePrice = 100; PayoffType Type = PayoffType.Call; double Maturity = 3; VarianceProcessParameters varParams = new VarianceProcessParameters(Kappa, Theta, Sigma, V0, Rho); HestonModelParameters hestonModel = new HestonModelParameters(InitialStockPrice, RiskFreeRate, varParams); EuropeanOption euOption = new EuropeanOption(StrikePrice, Type, Maturity); EuropeanOptionFormula euFormula = new EuropeanOptionFormula(hestonModel, euOption); Assert.AreEqual(15.4793, euFormula.Price(), 1e-4); }
public void TestEuropeanOpricePriceAndGreeks() { double strike = 100; Date exerciseDate = new Date(2017, 9, 30); var share = new Share("AAA", TestHelpers.ZAR); var option = new EuropeanOption(share, PutOrCall.Call, strike, exerciseDate); double spot = 100; double rate = 0.05; double div = 0.00; double vol = 0.20; Date valueDate = new Date(2016, 9, 30); var price = option.BlackScholesPrice(valueDate, spot, vol, rate, div); var delta = option.BlackScholesDelta(valueDate, spot, vol, rate, div); var gamma = option.BlackScholesGamma(valueDate, spot, vol, rate, div); var vega = option.BlackScholesVega(valueDate, spot, vol, rate, div); var theta = option.BlackScholesTheta(valueDate, spot, vol, rate, div); var rho = option.BlackScholesRho(valueDate, spot, vol, rate, div); Assert.AreEqual(10.4505835721856, price, 1e-8); Assert.AreEqual(0.636830651175619, delta, 1e-8); Assert.AreEqual(0.0187620173458469, gamma, 1e-8); Assert.AreEqual(37.5240346916938, vega, 1e-8); Assert.AreEqual(-6.4140275464382, theta, 1e-8); Assert.AreEqual(53.2324815453763, rho, 1e-8); }
public void TestIndexOnlyProvidedOnce() { var exerciseDate = new Date(2017, 08, 28); var shareCode = "AAA"; var strike = 100.0; Product p = new EuropeanOption(new Share(shareCode, Currency.ZAR), strike, exerciseDate); var shares = new[] { new Share("AAA", Currency.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); var coordinator = new Coordinator(sim, new List <Simulator> { sim }, 1000); var value = coordinator.Value(new[] { p }, valueDate); }
public static double BlackScholesPriceAndGreeks(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div, OptionPriceandGreeks greek) { double value = Double.NaN; if (greek == OptionPriceandGreeks.Price) { value = BlackScholesPrice(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Delta) { value = BlackScholesDelta(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Gamma) { value = BlackScholesGamma(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Vega) { value = BlackScholesVega(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Theta) { value = BlackScholesTheta(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Rho) { value = BlackScholesRho(option, valueDate, spot, vol, rate, div); } return(value); }
public void TestValuationCoordinator() { var exerciseDate = new Date(2017, 08, 28); var shareCode = "AAA"; var strike = 100.0; Product p = new EuropeanOption(new Share(shareCode, Currency.ZAR), strike, exerciseDate); var shares = new[] { new Share(shareCode, Currency.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(Currency.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); var coordinator = new Coordinator(sim, new List <Simulator>(), 10000); var value = coordinator.Value(new[] { p }, valueDate); var refValue = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - valueDate) / 365.0, spotPrice[0], vol[0], 0.07, divYield[0]); Assert.AreEqual(refValue, value, refValue * 0.05); }
/// <summary> /// Theta = first derivative of price with respect to time to expiration. /// </summary> /// <returns>theta of the option</returns> public static double BlackScholesTheta(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div) { var dist = new Normal(); var T = (double)(option._exerciseDate - valueDate) / 365; double d1 = D1(spot, option._strike, vol, rate, div, T); double d2 = D2(spot, option._strike, vol, rate, div, T); double theta; var flag = (double)option._putOrCall; double t1 = (Math.Exp(-div * T) * spot * dist.Density(d1) * vol * 0.5) / Math.Sqrt(T); double t2 = div * Math.Exp(-div * T) * spot * dist.CumulativeDistribution(flag * d1); double t3 = rate * option._strike * Math.Exp(-rate * T) * dist.CumulativeDistribution(flag * d2); if (option._putOrCall == PutOrCall.Call) { theta = -t1 + t2 - t3; } else { theta = -t1 - t2 + t3; } return(theta); }
private void optionTypeComboBox_SelectedIndexChanted(object sender, EventArgs e) { int index = optionTypeComboBox.SelectedIndex; switch (index) { case 2: amountLabel.Text = "Barrier Price"; amountTextBox.Visible = true; outputDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells; outputDataGridView.DataSource = BarrierOption.SetDataTable(); break; case 3: amountLabel.Text = "Rebate Price"; amountTextBox.Visible = true; outputDataGridView.DataSource = DigitalOption.SetDataTable(); break; case 5: outputDataGridView.DataSource = RangeOption.SetDataTable(); break; default: amountLabel.Text = ""; amountTextBox.Visible = false; outputDataGridView.DataSource = EuropeanOption.SetDataTable(); break; } }
/// <summary> /// Create European option pricer prior to valuation. /// </summary> protected override void CreateOption(double baseDate, VectorScopedCache.Scope cache) { var deal = (IDIOptionDeal)Deal; base.CreateOption(baseDate, cache); fEuroPricer = new EuropeanOption(deal.Option_Type, fStrike, deal.Expiry_Date, deal.Expiry_Date, deal.Expiry_Date, baseDate, cache, DayCount.BUS_252, deal.Calendar()); }
public static double BlackScholesImpliedVol(this EuropeanOption option, Date valueDate, double spot, double rate, double div, double price) { Func <double, double> option_price = x => BlackScholesPrice(option, valueDate, spot, x, rate, div) - price; double impliedvol = Brent.FindRoot(option_price, 1e-4, 1000, 1e-8, 1000); return(impliedvol); }
/// <summary> /// Initializes a new instance of the EuropeanOptionMC class. /// </summary> /// <param name="parameters">Interface holding Heston Model params.</param> /// <param name="monteCarloSimulationSettings">Interface holding Monte carlo simulation settings.</param> /// <param name="europeanOption">Interface holding European option params.</param> public EuropeanOptionMC(HestonModelParameters parameters, MonteCarloSettings monteCarloSimulationSettings, EuropeanOption europeanOption) : base(parameters, monteCarloSimulationSettings, europeanOption.Maturity) { _StrikePrice = europeanOption.StrikePrice; _Type = europeanOption.Type; }
/// <summary> /// Gereralized Black, Scholes, Merton formula for European options with dividend /// </summary> /// <returns>price of the option</returns> public static double BlackScholesPrice(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div) { var T = (double)(option._exerciseDate - valueDate) / 365; double price; price = BlackEtc.BlackScholes(option._putOrCall, option._strike, T, spot, vol, rate, div); return(price); }
/// <summary> /// Initializes a new instance of the European option /// </summary> /// <param name="parameters">Heston Model Parameter Object</param> /// <param name="europeanOption">European option Parameter Object</param> public EuropeanOptionFormula(HestonModelParameters parameters, EuropeanOption europeanOption) : base(parameters.InitialStockPrice, parameters.RiskFreeRate, parameters.GetVariance()) { _StrikePrice = europeanOption.StrikePrice; _Type = europeanOption.Type; _Maturity = europeanOption.Maturity; }
public void TestDynamicCallFromFile() { Stopwatch watch; // Make a product at runtime var runtimeProduct = RuntimeProduct.CreateFromScript(@"ScriptEuropeanOption.txt"); // Setup an appropriate simulation var shares = new[] { new Share("AAA", TestHelpers.ZAR) }; // One needs to know the index that will be required by the product to simulate it. var valueDate = new Date(2016, 08, 28); var divYield = new[] { 0.02 }; var vol = new[] { 0.22 }; var spotPrice = new[] { 100.0 }; var correlations = new[, ] { { 1.0 } }; IDiscountingSource discountCurve = new DatesAndRates(TestHelpers.ZAR, valueDate, new[] { valueDate, valueDate.AddMonths(120) }, new[] { 0.07, 0.07 }); var rateForecastCurves = new IFloatingRateSource[0]; var sim = new EquitySimulator(shares, spotPrice, vol, divYield, correlations, discountCurve, rateForecastCurves); // Value the runtime product Coordinator coordinator; coordinator = new Coordinator(sim, new List <Simulator>(), 100000); watch = Stopwatch.StartNew(); var valueRuntime = coordinator.Value(new[] { runtimeProduct }, valueDate); watch.Stop(); var timeRuntime = watch.ElapsedMilliseconds; // Setup the same product statically var exerciseDate = new Date(2017, 08, 28); var strike = 100.0; Product staticProduct = new EuropeanOption(new Share("AAA", TestHelpers.ZAR), strike, exerciseDate); // Value the static product coordinator = new Coordinator(sim, new List <Simulator>(), 100000); watch = Stopwatch.StartNew(); var valueStatic = coordinator.Value(new[] { staticProduct }, valueDate); watch.Stop(); var timeStatic = watch.ElapsedMilliseconds; var refValue = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - valueDate) / 365, spotPrice[0], vol[0], 0.07, divYield[0]); Assert.AreEqual(refValue, valueRuntime, refValue * 0.03); Assert.AreEqual(refValue, valueStatic, refValue * 0.03); }
public static void Task2() { // Task 2 // Variance Process Values Console.WriteLine("Task 2"); double Kappa = 1.5768; double Theta = 0.0398; double Sigma = 0.5751; double V0 = 0.0175; double Rho = -0.5711; // Heston Model Params double InitialStockPrice = 100; double RiskFreeRate = 0.025; // Option Params double StrikePrice = 100; PayoffType Type = PayoffType.Call; int[] Maturity = new int[5] { 1, 2, 3, 4, 15 }; VarianceProcessParameters varParams = new VarianceProcessParameters(Kappa, Theta, Sigma, V0, Rho); HestonModelParameters hestonModel = new HestonModelParameters(InitialStockPrice, RiskFreeRate, varParams); // ************Task 2.1 Print**************** System.Console.WriteLine("*********************"); HestonModelParamPrint(varParams, hestonModel); //Prepare csv var csv = new StringBuilder(); String newLine = string.Format("K, T, Price"); csv.AppendLine(newLine); for (int i = 0; i < 5; i++) { EuropeanOption euOption = new EuropeanOption(StrikePrice, Type, Maturity[i]); double price = Heston.HestonEuropeanOptionPrice(hestonModel, euOption); System.Console.WriteLine("K={0}, T={1}, C={2}", StrikePrice, Maturity[i], price); newLine = string.Format("{0}, {1}, {2}", StrikePrice, Maturity[i], price); csv.AppendLine(newLine); } //Write to csv File.WriteAllText(@"./task2.csv", csv.ToString()); System.Console.WriteLine("*********************"); System.Console.WriteLine("\n\n"); }
/// <summary> /// Vega = first derivative of price with respect to volatility. /// </summary> /// <returns>vega of the option</returns> public static double BlackScholesVega(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div) { var dist = new Normal(); var T = (double)(option._exerciseDate - valueDate) / 365; double d1 = D1(spot, option._strike, vol, rate, div, T); double vega; vega = spot * Math.Exp(-div * T) * dist.Density(d1) * Math.Sqrt(T); return(vega); }
public static string[,] BlackScholesPrice([QuantSAExcelArgument(Description = "The European Option.")] EuropeanOption option, [QuantSAExcelArgument(Description = "The valuation date of the option.")] Date valueDate, [QuantSAExcelArgument(Description = "The spot price of the underlying at the value date.")] double spot, [QuantSAExcelArgument(Description = "Annualized volatility.")] double vol, [QuantSAExcelArgument(Description = "Continuously compounded risk free rate.")] double rate, [QuantSAExcelArgument(Description = "Continuously compounded dividend yield.", Default = "0.0")] double div) { string[,] price = { { "Price", option.BlackScholesPrice(valueDate, spot, vol, rate, div).ToString() } }; return(price); }
public static string[,] MonteCarloPrice([QuantSAExcelArgument(Description = "The European Option.")] EuropeanOption option, [QuantSAExcelArgument(Description = "The valuation date of the option.")] Date valueDate, [QuantSAExcelArgument(Description = "The spot price of the underlying at the value date.")] double spot, [QuantSAExcelArgument(Description = "Annualized volatility.")] double vol, [QuantSAExcelArgument(Description = "Continuously compounded risk free rate.")] double rate, [QuantSAExcelArgument(Description = "Continuously compounded dividend yield.", Default = "0.0")] double div, [QuantSAExcelArgument(Description = "Continuously compounded risk free rate.")] int numOfSims) { string[,] price = { { "Price", option.MonteCarloPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Price, numOfSims).ToString() } }; return(price); }
private void Form_Load(object sender, EventArgs e) { disable_CalcuateButton(); optionTypeComboBox.SelectedIndex = 1; string type = optionTypeComboBox.SelectedItem.ToString(); outputDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; outputDataGridView.DataSource = EuropeanOption.SetDataTable(); amountLabel.Text = ""; amountTextBox.Visible = false; }
/// <summary> /// Rho = first derivative of price with respect to the risk-free rate. /// </summary> /// <returns>rho of the option</returns> public static double BlackScholesRho(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div) { var dist = new Normal(); var T = (double)(option._exerciseDate - valueDate) / 365; double d2 = D2(spot, option._strike, vol, rate, div, T); double rho; var flag = (double)option._putOrCall; rho = flag * T * option._strike * Math.Exp(-rate * T) * dist.CumulativeDistribution(flag * d2); return(rho); }
public void TestEquitySimulatorMultiAssetCall() { // The model var sim = new EquitySimulator(shares, prices, vols, divYields, correlations, discountCurve, new IFloatingRateSource[0]); var coordinator = new Coordinator(sim, new List <Simulator>(), 10000); // Products var exerciseDate = new Date(2017, 08, 28); int p; double strike; // ALSI p = 0; strike = prices[p] * 1.05; Product call0 = new EuropeanOption(shares[p], strike, exerciseDate); var value0 = coordinator.Value(new[] { call0 }, anchorDate); var refValue0 = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - anchorDate) / 365.0, prices[p], vols[p], 0.07, divYields[p]); Assert.AreEqual(refValue0, value0, refValue0 * 0.05); // AAA p = 1; strike = prices[p] * 1.05; Product call1 = new EuropeanOption(shares[p], strike, exerciseDate); var value1 = coordinator.Value(new[] { call1 }, anchorDate); var refValue1 = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - anchorDate) / 365.0, prices[p], vols[p], 0.07, divYields[p]); Assert.AreEqual(refValue1, value1, refValue1 * 0.05); // BBB p = 2; strike = prices[p] * 1.05; Product call2 = new EuropeanOption(shares[p], strike, exerciseDate); var value2 = coordinator.Value(new[] { call2 }, anchorDate); var refValue2 = BlackEtc.BlackScholes(PutOrCall.Call, strike, (exerciseDate - anchorDate) / 365.0, prices[p], vols[p], 0.07, divYields[p]); Assert.AreEqual(refValue1, value1, refValue1 * 0.05); // All at once var valueAll = coordinator.Value(new[] { call0, call1, call2 }, anchorDate); var refTotal = refValue0 + refValue1 + refValue2; Assert.AreEqual(refTotal, valueAll, refTotal * 0.05); }
public void EuropeanOptionFact() { var orgin = new DateTime(2019, 06, 12); var usd = TestProviderHelper.CurrencyProvider.GetCurrency("USD"); var fixDates = new[] { orgin }; var x = new EuropeanOption() { AssetId = "QS", DiscountCurve = "X", ExpiryDate = orgin, FxConversionType = FxConversionType.None, Notional = 1, PaymentCurrency = usd, PaymentDate = orgin, SpotLag = 0.Bd(), Strike = 1000, }; var fakeModel = new Mock <IAssetFxModel>(); var c = new ConstantPriceCurve(100, DateTime.Today, TestProviderHelper.CurrencyProvider) { Currency = usd }; fakeModel.Setup(xx => xx.GetPriceCurve(It.IsAny <string>(), null)).Returns(c); fakeModel.Setup(xx => xx.BuildDate).Returns(DateTime.Today); Assert.Equal(usd, x.Currency); Assert.Equal(usd, x.PaymentCurrency); var a = x.AssetIds; Assert.Contains("QS", a); Assert.Single(x.IrCurves(fakeModel.Object)); Assert.Equal(FxConversionType.None, x.FxType(fakeModel.Object)); Assert.Equal(orgin, x.LastSensitivityDate); var pf = x.PastFixingDates(orgin.AddDays(1)); Assert.Contains("QS", pf.Keys); var y = (EuropeanOption)x.Clone(); Assert.True(x.Equals(y)); y.TradeId = "xxx"; Assert.False(x.Equals(y)); var z = (EuropeanOption)x.SetStrike(0); Assert.Equal(0, z.Strike); }
public static string[,] BlackScholesGreeks([QuantSAExcelArgument(Description = "The European Option.")] EuropeanOption option, [QuantSAExcelArgument(Description = "The valuation date of the option.")] Date valueDate, [QuantSAExcelArgument(Description = "The spot price of the underlying at the value date.")] double spot, [QuantSAExcelArgument(Description = "Annualized volatility.")] double vol, [QuantSAExcelArgument(Description = "Continuously compounded risk free rate.")] double rate, [QuantSAExcelArgument(Description = "Continuously compounded dividend yield.", Default = "0.0")] double div) { var result = option.BlackScholesPrice(valueDate, spot, vol, rate, div); string[,] greeks = { { "Delta", option.BlackScholesPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Delta).ToString() }, { "Gamma", option.BlackScholesPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Gamma).ToString() }, { "Vega", option.BlackScholesPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Vega).ToString() }, { "Theta", option.BlackScholesPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Theta).ToString() }, { "Rho", option.BlackScholesPriceAndGreeks(valueDate, spot, vol, rate, div, EuropeanOptionEx.OptionPriceandGreeks.Rho).ToString() } }; return(greeks); }
public void TestEuropeanOpriceImpliedVol() { double strike = 100; Date exerciseDate = new Date(2017, 9, 30); var share = new Share("AAA", TestHelpers.ZAR); var option = new EuropeanOption(share, PutOrCall.Call, strike, exerciseDate); double spot = 100; double rate = 0.05; double div = 0.00; double price = 10.4505835721856; Date valueDate = new Date(2016, 9, 30); var impliedvol = option.BlackScholesImpliedVol(valueDate, spot, rate, div, price); Assert.AreEqual(0.20, impliedvol, 1e-4); }
/// <summary> /// Delta = first derivative of price with respect to underlying price. /// </summary> /// <returns>delta of the option</returns> public static double BlackScholesDelta(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div) { var T = (double)(option._exerciseDate - valueDate) / 365; double d1 = D1(spot, option._strike, vol, rate, div, T); double delta; double dtq = Math.Exp(-div * T); var dist = new Normal(); if (option._putOrCall == PutOrCall.Call) { delta = dtq * dist.CumulativeDistribution(d1); } else { delta = dtq * (dist.CumulativeDistribution(d1) - 1); } return(delta); }
public static double MonteCarloPriceAndGreeks(this EuropeanOption option, Date valueDate, double spot, double vol, double rate, double div, OptionPriceandGreeks greek, int numOfSims = 100000) { var T = (double)(option._exerciseDate - valueDate) / 365; var flag = (double)option._putOrCall; double bump = 0.01; var paths = GBMEquitySimulator.StockPathSimulator(spot, vol, div, rate, T, numOfSims, 1, bump); var stockpaths = paths[0]; var stockpaths_up = paths[1]; var stockpaths_down = paths[2]; double value = Double.NaN; if (greek == OptionPriceandGreeks.Price) { value = MonteCarloPrice(stockpaths, option._strike, flag, rate, T); } else if (greek == OptionPriceandGreeks.Delta) { value = (MonteCarloPrice(stockpaths_up, option._strike, flag, rate, T) - MonteCarloPrice(stockpaths, option._strike, flag, rate, T)) / bump; } else if (greek == OptionPriceandGreeks.Gamma) { value = (MonteCarloPrice(stockpaths_up, option._strike, flag, rate, T) - 2 * MonteCarloPrice(stockpaths, option._strike, flag, rate, T) + MonteCarloPrice(stockpaths_down, option._strike, flag, rate, T)) / (bump * bump); } // To do : create monte carlo vega, theta, and rho else if (greek == OptionPriceandGreeks.Vega) { value = BlackScholesVega(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Theta) { value = BlackScholesTheta(option, valueDate, spot, vol, rate, div); } else if (greek == OptionPriceandGreeks.Rho) { value = BlackScholesRho(option, valueDate, spot, vol, rate, div); } return(value); }
public void Test() { //Triple A == Arrange, Act, Assert //Arrange int iPrecision = 4; double dStockPrice = 50; double dStrikePrice = 55; double dTimeToMaturity = 1; double dStdDerivUnderlying = 0.2; double dRiskFreeInterestRate = 0.09; Constants.EuroOptionType euroOptionType = Constants.EuroOptionType.Call; //Act FinancialProduct product = new EuropeanOption(dStockPrice, dStrikePrice, dTimeToMaturity, dStdDerivUnderlying, dRiskFreeInterestRate, euroOptionType); var pricer = new EuropeanOptionPricer(iPrecision); double dResultPricing = pricer.Price(product); //Assert Assert.AreEqual(dResultPricing.ToString(), "3.8617"); }
public void Task_2_3_15() { // Variance Process Values double Kappa = 2; double Theta = 0.06; double Sigma = 0.4; double V0 = 0.04; double Rho = 0.5; // Heston Model Params double InitialStockPrice = 100; double RiskFreeRate = 0.1; // Option Params double StrikePrice = 100; PayoffType Type = PayoffType.Call; double Maturity = 15; // MC Simulation Params int NumberOfTrials = (int)1e5; int NumberOfTimeSteps = (int)Math.Ceiling(365 * Maturity); VarianceProcessParameters varParams = new VarianceProcessParameters(Kappa, Theta, Sigma, V0, Rho); HestonModelParameters hestonModel = new HestonModelParameters(InitialStockPrice, RiskFreeRate, varParams); EuropeanOption euOption = new EuropeanOption(StrikePrice, Type, Maturity); MonteCarloSettings monteCarloSettings = new MonteCarloSettings(NumberOfTrials, NumberOfTimeSteps); EuropeanOptionMC euOptionMC = new EuropeanOptionMC(hestonModel, monteCarloSettings, euOption); Assert.AreEqual(78.4306, euOptionMC.Price(1), 1e-1); }
public void CompositeSmimleFacts_LocalVol() { var origin = new DateTime(2017, 02, 07); var expiry = origin.AddMonths(2); var tExp = origin.CalculateYearFraction(expiry, DayCountBasis.Act365F); var fwdCurveAsset = new Func <double, double>(t => { return(100); }); var fwdCurveFx = new Func <double, double>(t => { return(15); }); var volAsset = 0.32; var volFx = 0.16; var correl = 0.25; var surfaceAsset = new RiskyFlySurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.GaussianKernel, Interpolator1DType.Linear) { FlatDeltaSmileInExtreme = true }; var surfaceFx = new RiskyFlySurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.GaussianKernel, Interpolator1DType.Linear) { FlatDeltaSmileInExtreme = true }; //var surfaceAsset = new SabrVolSurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceFx = new SabrVolSurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceAsset = new SVIVolSurface(origin, new[] { volAsset }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.02, 0.03 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 100.0 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); //var surfaceFx = new SVIVolSurface(origin, new[] { volFx }, new[] { expiry }, new[] { 0.25, 0.1 }, new[] { new[] { 0.015, 0.025 } }, new[] { new[] { 0.005, 0.007 } }, new[] { 0.1 }, WingQuoteType.Arithmatic, AtmVolType.ZeroDeltaStraddle, Interpolator1DType.Linear); var invFx = new InverseFxSurface("inv", surfaceFx, TestProviderHelper.CurrencyProvider); var surfaceCompo = surfaceAsset.GenerateCompositeSmile(invFx, 200, expiry, 100, 1.0 / 15, correl); //setup MC using var engine = new PathEngine(2.IntPow(IsCoverageOnly?5:15)); engine.AddPathProcess( new Qwack.Random.MersenneTwister.MersenneTwister64 { UseNormalInverse = true }); var correlMatrix = new double[][] { new double[] { 1.0, correl }, new double[] { correl, 1.0 }, }; engine.AddPathProcess(new Cholesky(correlMatrix)); var asset1 = new TurboSkewSingleAsset ( startDate: origin, expiryDate: expiry, volSurface: surfaceAsset, forwardCurve: fwdCurveAsset, nTimeSteps: 1, name: "Asset" ); var asset2 = new TurboSkewSingleAsset ( startDate: origin, expiryDate: expiry, volSurface: surfaceFx, forwardCurve: fwdCurveFx, nTimeSteps: 1, name: "USD/ZAR" ); engine.AddPathProcess(asset1); engine.AddPathProcess(asset2); var strike = 1500; var product = new EuropeanOption { AssetId = "Asset", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["ZAR"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = strike, FxConversionType = FxConversionType.ConvertThenAverage }; var productAsset = new EuropeanOption { AssetId = "Asset", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["USD"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = 100, FxConversionType = FxConversionType.None }; var productFx = new EuropeanOption { AssetId = "USD/ZAR", CallPut = OptionType.C, ExpiryDate = expiry, PaymentCurrency = TestProviderHelper.CurrencyProvider["ZAR"], PaymentDate = expiry, Notional = 1.0, SpotLag = new Frequency("0b"), Strike = 0.1, FxConversionType = FxConversionType.None }; var pathProduct = new AssetPathPayoff(product, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); var pathProductAsset = new AssetPathPayoff(productAsset, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); var pathProductFx = new AssetPathPayoff(productFx, TestProviderHelper.CurrencyProvider, TestProviderHelper.CalendarProvider, TestProviderHelper.CurrencyProvider["ZAR"]); engine.AddPathProcess(pathProduct); engine.AddPathProcess(pathProductAsset); engine.AddPathProcess(pathProductFx); engine.SetupFeatures(); engine.RunProcess(); var q = pathProduct.ResultsByPath; var qq = q.Average(); var productIv = BlackFunctions.BlackImpliedVol(1500, strike, 0.0, tExp, pathProduct.AverageResult, OptionType.C); var productAssetIv = BlackFunctions.BlackImpliedVol(100, 100, 0.0, tExp, pathProductAsset.AverageResult, OptionType.C); var productFxIv = BlackFunctions.BlackImpliedVol(10, 10, 0.0, tExp, pathProductFx.AverageResult, OptionType.C); Assert.True(Abs(productIv - surfaceCompo.Interpolate(strike)) < 0.01); }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(EuropeanOption obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
public void Task_2_5() { // Variance Process Values double Kappa = 1.5768; double Theta = 0.398; double Sigma = 0.5751; double V0 = 0.0175; double Rho = -0.5711; // Heston Model Params double InitialStockPrice = 100; double RiskFreeRate = 0.025; // Callibration Settings double accuracy = 0.001; int maxIter = 1000; VarianceProcessParameters varParams = new VarianceProcessParameters(Kappa, Theta, Sigma, V0, Rho); HestonModelParameters hestonModel = new HestonModelParameters(InitialStockPrice, RiskFreeRate, varParams); CalibrationSettings calibrationSettings = new CalibrationSettings(accuracy, maxIter); // Market Data LinkedList <OptionMarketData <EuropeanOption> > observedOptions = new LinkedList <OptionMarketData <EuropeanOption> >(); EuropeanOption eu1 = new EuropeanOption(80, PayoffType.Call, 1); OptionMarketData <EuropeanOption> marketData1 = new OptionMarketData <EuropeanOption>(eu1, 25.72); observedOptions.AddLast(marketData1); EuropeanOption eu2 = new EuropeanOption(90, PayoffType.Call, 1); OptionMarketData <EuropeanOption> marketData2 = new OptionMarketData <EuropeanOption>(eu2, 18.93); observedOptions.AddLast(marketData2); EuropeanOption eu3 = new EuropeanOption(80, PayoffType.Call, 2); OptionMarketData <EuropeanOption> marketData3 = new OptionMarketData <EuropeanOption>(eu3, 30.49); observedOptions.AddLast(marketData3); EuropeanOption eu4 = new EuropeanOption(100, PayoffType.Call, 2); OptionMarketData <EuropeanOption> marketData4 = new OptionMarketData <EuropeanOption>(eu4, 19.36); observedOptions.AddLast(marketData4); EuropeanOption eu5 = new EuropeanOption(100, PayoffType.Call, 1.5); OptionMarketData <EuropeanOption> marketData5 = new OptionMarketData <EuropeanOption>(eu5, 16.58); observedOptions.AddLast(marketData5); // Heston Calibrator HestonCalibrator calibrator = new HestonCalibrator(hestonModel, observedOptions, calibrationSettings); calibrator.Calibrate(); double error = 0; CalibrationOutcome outcome = CalibrationOutcome.NotStarted; calibrator.GetCalibrationStatus(ref outcome, ref error); Console.WriteLine("Calibration outcome: {0} and error: {1}", outcome, error); }
public void testDeltaPriceConsistency() { // Testing premium-adjusted delta price consistency // This function tests for price consistencies with the standard // Black Scholes calculator, since premium adjusted deltas can be calculated // from spot deltas by adding/subtracting the premium. SavedSettings backup = new SavedSettings(); // actually, value and tol won't be needed for testing EuropeanOptionData[] values = { // type, strike, spot, rd, rf, t, vol, value, tol new EuropeanOptionData(Option.Type.Call, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), new EuropeanOptionData(Option.Type.Call, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 0.9123, 1.2212, 0.0231, 0.0000, 0.25, 0.301, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 0.9234, 1.2212, 0.0231, 0.0000, 0.35, 0.111, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 0.9783, 1.2212, 0.0231, 0.0000, 0.45, 0.071, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.0000, 1.2212, 0.0231, 0.0000, 0.55, 0.082, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.1230, 1.2212, 0.0231, 0.0000, 0.65, 0.012, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.2212, 1.2212, 0.0231, 0.0000, 0.75, 0.129, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.3212, 1.2212, 0.0231, 0.0000, 0.85, 0.034, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.3923, 1.2212, 0.0131, 0.2344, 0.95, 0.001, 0.0, 0.0), new EuropeanOptionData(Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 1.00, 0.127, 0.0, 0.0), // extreme case: zero vol new EuropeanOptionData(Option.Type.Put, 1.3455, 1.2212, 0.0000, 0.0000, 0.50, 0.000, 0.0, 0.0), // extreme case: zero strike new EuropeanOptionData(Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.50, 0.133, 0.0, 0.0), // extreme case: zero strike+zero vol new EuropeanOptionData(Option.Type.Put, 0.0000, 1.2212, 0.0000, 0.0000, 1.00, 0.133, 0.0, 0.0), }; DayCounter dc = new Actual360(); Calendar calendar = new TARGET(); Date today = Date.Today; // Start setup of market data double discFor = 0.0; double discDom = 0.0; double implVol = 0.0; double expectedVal = 0.0; double calculatedVal = 0.0; double error = 0.0; SimpleQuote spotQuote = new SimpleQuote(0.0); Handle <Quote> spotHandle = new Handle <Quote>(spotQuote); SimpleQuote qQuote = new SimpleQuote(0.0); Handle <Quote> qHandle = new Handle <Quote>(qQuote); YieldTermStructure qTS = new FlatForward(today, qHandle, dc); SimpleQuote rQuote = new SimpleQuote(0.0); Handle <Quote> rHandle = new Handle <Quote>(qQuote); YieldTermStructure rTS = new FlatForward(today, rHandle, dc); SimpleQuote volQuote = new SimpleQuote(0.0); Handle <Quote> volHandle = new Handle <Quote>(volQuote); BlackVolTermStructure volTS = new BlackConstantVol(today, calendar, volHandle, dc); BlackScholesMertonProcess stochProcess; IPricingEngine engine; StrikedTypePayoff payoff; Date exDate; Exercise exercise; // Setup of market data finished double tolerance = 1.0e-10; for (int i = 0; i < values.Length; ++i) { payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); exDate = today + timeToDays(values[i].t); exercise = new EuropeanExercise(exDate); spotQuote.setValue(values[i].s); volQuote.setValue(values[i].v); rQuote.setValue(values[i].r); qQuote.setValue(values[i].q); discDom = rTS.discount(exDate); discFor = qTS.discount(exDate); implVol = Math.Sqrt(volTS.blackVariance(exDate, 0.0)); BlackDeltaCalculator myCalc = new BlackDeltaCalculator(values[i].type, DeltaVolQuote.DeltaType.PaSpot, spotQuote.value(), discDom, discFor, implVol); stochProcess = new BlackScholesMertonProcess(spotHandle, new Handle <YieldTermStructure>(qTS), new Handle <YieldTermStructure>(rTS), new Handle <BlackVolTermStructure>(volTS)); engine = new AnalyticEuropeanEngine(stochProcess); EuropeanOption option = new EuropeanOption(payoff, exercise); option.setPricingEngine(engine); calculatedVal = myCalc.deltaFromStrike(values[i].strike); expectedVal = option.delta() - option.NPV() / spotQuote.value(); error = Math.Abs(expectedVal - calculatedVal); if (error > tolerance) { QAssert.Fail("\n Premium-adjusted spot delta test failed. \n" + "Calculated Delta: " + calculatedVal + "\n" + "Expected Value: " + expectedVal + "\n" + "Error: " + error); } myCalc.setDeltaType(DeltaVolQuote.DeltaType.PaFwd); calculatedVal = myCalc.deltaFromStrike(values[i].strike); expectedVal = expectedVal / discFor; // Premium adjusted Fwd Delta is PA spot without discount error = Math.Abs(expectedVal - calculatedVal); if (error > tolerance) { QAssert.Fail("\n Premium-adjusted forward delta test failed. \n" + "Calculated Delta: " + calculatedVal + "\n" + "Expected Value: " + expectedVal + "\n" + "Error: " + error); } // Test consistency with BlackScholes Calculator for Spot Delta myCalc.setDeltaType(DeltaVolQuote.DeltaType.Spot); calculatedVal = myCalc.deltaFromStrike(values[i].strike); expectedVal = option.delta(); error = Math.Abs(calculatedVal - expectedVal); if (error > tolerance) { QAssert.Fail("\n spot delta in BlackDeltaCalculator differs from delta in BlackScholesCalculator. \n" + "Calculated Value: " + calculatedVal + "\n" + "Expected Value: " + expectedVal + "\n" + "Error: " + error); } } }