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); }
public static object FormulaBlackScholes([ExcelArgument(Description = "Strike")] object[,] strike, [ExcelArgument(Description = "The value date as and Excel date.")] object[,] valueDate, [ExcelArgument(Description = "The exercise date of the option. Must be greater than the value date.")] object[,] exerciseDate, [ExcelArgument(Description = "The spot proce of the underlying at the value date.")] object[,] spotPrice, [ExcelArgument(Description = "Annualized volatility.")] object[,] vol, [ExcelArgument(Description = "Continuously compounded risk free rate.")] object[,] riskfreeRate, [ExcelArgument(Description = "Continuously compounded dividend yield.")] object[,] divYield) { try { return(BlackEtc.BlackScholes(PutOrCall.Call, XU.GetDouble0D(strike, "strike"), (XU.GetDate0D(exerciseDate, "exerciseDate") - XU.GetDate0D(valueDate, "valueDate")) / 365.0, XU.GetDouble0D(spotPrice, "spotPrice"), XU.GetDouble0D(vol, "vol"), XU.GetDouble0D(riskfreeRate, "riskfreeRate"), XU.GetDouble0D(divYield, "divYield"))); } catch (Exception e) { return(XU.Error0D(e)); } }
/// <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); }
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 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 TestDynamicCallFromString() { var source = @"Date exerciseDate = new Date(2017, 08, 28); Share share = new Share(""AAA"", new Currency(""ZAR"")); double strike = 100.0; public override List<Cashflow> GetCFs() { double amount = Math.Max(0, Get(share, exerciseDate) - strike); return new List<Cashflow> { new Cashflow(exerciseDate, amount, share.Currency) }; }"; // Make a product at runtime var runtimeProduct = RuntimeProduct.CreateFromString("MyEuropeanOption", source); // Setup an approriate 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); var valueRuntime = coordinator.Value(new[] { runtimeProduct }, valueDate); var exerciseDate = new Date(2017, 08, 28); var strike = 100.0; 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); }
public static double FormulaBlack([ExcelArgument(Description = "put or call.")] PutOrCall putOrCall, [ExcelArgument(Description = "The strike")] double strike, [ExcelArgument(Description = "The time to maturity in years from the value date to the exercise date.")] double timeToExercise, [ExcelArgument(Description = "The forward at the option exercise date.")] double forward, [ExcelArgument(Description = "Annualized volatility.")] double vol, [ExcelArgument(Description = "The discount factor from the value date to the settlement date of the option.")] double discountFactor) { return(BlackEtc.Black(putOrCall, strike, timeToExercise, forward, vol, discountFactor)); }
public static ResultStore BlackOption(JSEBondOption bondoption, double strike, double vol, double repo, JSEBondForward bond, double yieldToMaturity) { var settleDate = bondoption.settleDate; var timeToMaturity = bondoption.timeToMaturity; var ytm = yieldToMaturity; var bondforwardprice1 = (double)bond.ForwardPrice(settleDate, ytm, repo).GetScalar(JSEBondForwardEx.Keys.ForwardPrice); var discountFactor = Math.Exp(-repo * timeToMaturity); var optionPrice = BlackEtc.Black(PutOrCall.Call, strike, timeToMaturity, bondforwardprice1, vol, discountFactor); var resultStore = new ResultStore(); resultStore.Add(Keys.BlackOption, optionPrice); return(resultStore); }
public static double FormulaBlackScholes([QuantSAExcelArgument(Description = "PutOrCall")] PutOrCall putOrCall, [ExcelArgument(Description = "Strike")] double strike, [ExcelArgument(Description = "The value date as and Excel date.")] Date valueDate, [ExcelArgument(Description = "The exercise date of the option. Must be greater than the value date.")] Date exerciseDate, [ExcelArgument(Description = "The spot price of the underlying at the value date.")] double spotPrice, [ExcelArgument(Description = "Annualized volatility.")] double vol, [ExcelArgument(Description = "Continuously compounded risk free rate.")] double riskfreeRate, [QuantSAExcelArgument(Description = "Continuously compounded dividend yield.", Default = "0.0")] double divYield) { return(BlackEtc.BlackScholes(putOrCall, strike, Actual365Fixed.Instance.YearFraction(valueDate, exerciseDate), spotPrice, vol, riskfreeRate, divYield)); }