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; } }
public BarrierOptionFourierPvPricer(BarrierOption barrierOption, IMarketCondition market, double timeIncrement = 0.0) { var exerciseDate = barrierOption.ExerciseDates.Last(); var riskFreeRate = market.DiscountCurve.Value.ZeroRate(market.ValuationDate, exerciseDate); var spotPrice = market.SpotPrices.Value.Values.First(); var vol = market.VolSurfaces.Value.Values.First().GetValue(market.ValuationDate, barrierOption.Strike, spotPrice); var exerciseInYears = AnalyticalOptionPricerUtil.timeToMaturityFraction(market.ValuationDate, exerciseDate, barrierOption) + timeIncrement; _optionType = barrierOption.OptionType; _rebate = barrierOption.Rebate; _coupon = barrierOption.Coupon; _K = barrierOption.Strike; _S = spotPrice; _T = exerciseInYears; _v = vol; _r = riskFreeRate; _B = barrierOption.UpperBarrier; _A = barrierOption.Barrier; b = Math.Log(_B); a = Math.Log(_A); x0 = Math.Log(_S); v2 = Math.Pow(_v, 2); u = _r - v2 / 2; u2 = Math.Pow(u, 2); }
public void testFdmHestonBarrier() { //Testing FDM with barrier option for Heston model vs Black-Scholes model... using (SavedSettings backup = new SavedSettings()) { Handle <Quote> s0 = new Handle <Quote>(new SimpleQuote(100.0)); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.05, new Actual365Fixed())); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(0.0, new Actual365Fixed())); HestonProcess hestonProcess = new HestonProcess(rTS, qTS, s0, 0.04, 2.5, 0.04, 0.66, -0.8); Settings.Instance.setEvaluationDate(new Date(28, 3, 2004)); Date exerciseDate = new Date(28, 3, 2005); Exercise exercise = new EuropeanExercise(exerciseDate); StrikedTypePayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 100); BarrierOption barrierOption = new BarrierOption(Barrier.Type.UpOut, 135, 0.0, payoff, exercise); barrierOption.setPricingEngine(new FdHestonBarrierEngine(new HestonModel(hestonProcess), 50, 400, 100)); double tol = 0.01; double npvExpected = 9.1530; double deltaExpected = 0.5218; double gammaExpected = -0.0354; if (Math.Abs(barrierOption.NPV() - npvExpected) > tol) { QAssert.Fail("Failed to reproduce expected npv" + "\n calculated: " + barrierOption.NPV() + "\n expected: " + npvExpected + "\n tolerance: " + tol); } if (Math.Abs(barrierOption.delta() - deltaExpected) > tol) { QAssert.Fail("Failed to reproduce expected delta" + "\n calculated: " + barrierOption.delta() + "\n expected: " + deltaExpected + "\n tolerance: " + tol); } if (Math.Abs(barrierOption.gamma() - gammaExpected) > tol) { QAssert.Fail("Failed to reproduce expected gamma" + "\n calculated: " + barrierOption.gamma() + "\n expected: " + gammaExpected + "\n tolerance: " + tol); } } }
static void Main(string[] args) { Calendar calendar = new TARGET(); Date todaysDate = new Date(22, 7, 2014); Date settlementDate = new Date(3, 6, 2014); Settings.setEvaluationDate(todaysDate); DayCounter dayCounter = new Actual365Fixed(); double dividendYield = 0.0117; double volatility = 0.15517; Barrier.Type type = Barrier.Type.UpOut; QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call, 261.4); QLNet.EuropeanExercise ex = new EuropeanExercise(new Date(30, 11, 2015)); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 1.2,1.0, 0.0, payoff, ex); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.0, payoff, ex); QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.32, 0.0, payoff, ex); double underlying = 262.86; double riskFreeRate = 0.0243; Handle <Quote> underlyingH = new Handle <Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle <YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle <YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle <BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess); barrierOption.setPricingEngine(engine); double kk = barrierOption.NPV(); Console.WriteLine(kk); Console.WriteLine(kk / 261.4); }
static void Main(string[] args) { Calendar calendar = new TARGET(); Date todaysDate = new Date(22, 7, 2014); Date settlementDate = new Date(3, 6, 2014); Settings.setEvaluationDate(todaysDate); DayCounter dayCounter = new Actual365Fixed(); double dividendYield = 0.0117; double volatility = 0.15517; Barrier.Type type = Barrier.Type.UpOut; QLNet.PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Call,261.4); QLNet.EuropeanExercise ex = new EuropeanExercise(new Date(30,11,2015)); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 1.2,1.0, 0.0, payoff, ex); //QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.0, payoff, ex); QLNet.BarrierOption barrierOption = new BarrierOption(type, 313.68, 0.32,0.0, payoff, ex); double underlying = 262.86; double riskFreeRate = 0.0243; Handle<Quote> underlyingH = new Handle<Quote>(new SimpleQuote(underlying)); // bootstrap the yield/dividend/vol curves var flatTermStructure = new Handle<YieldTermStructure>(new FlatForward(settlementDate, riskFreeRate, dayCounter)); var flatDividendTS = new Handle<YieldTermStructure>(new FlatForward(settlementDate, dividendYield, dayCounter)); var flatVolTS = new Handle<BlackVolTermStructure>(new BlackConstantVol(settlementDate, calendar, volatility, dayCounter)); var bsmProcess = new BlackScholesMertonProcess(underlyingH, flatDividendTS, flatTermStructure, flatVolTS); QLNet.AnalyticBarrierWithPartiRateEngine engine = new AnalyticBarrierWithPartiRateEngine(bsmProcess); barrierOption.setPricingEngine(engine); double kk = barrierOption.NPV(); Console.WriteLine(kk); Console.WriteLine(kk / 261.4); }
public void testAssetOrNothingHaugValues() { // Testing asset-or-nothing barrier options against Haug's values BinaryOptionData[] values = { /* The data below are from * "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 180 - cases 15,16,19,20,23,24,27,28 * Note: * q is the dividend rate, while the book gives b, the cost of carry (q=r-b) */ // barrierType, barrier, cash, type, strike, spot, q, r, t, vol, value, tol new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 37.2782, 1e-4), new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 45.8530, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 44.5294, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 54.9262, 1e-4), // 19,20 new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 27.5644, 1e-4), new BinaryOptionData(Barrier.Type.DownIn, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 18.9896, 1e-4), // following value is wrong in book. new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 33.1723, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 22.7755, 1e-4), // 23,24 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 39.9391, 1e-4), new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 40.1574, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.2676, 1e-4), // 27,28 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.2183, 1e-4), new BinaryOptionData(Barrier.Type.DownOut, 100.00, 0.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.2983, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 0.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 17.0306, 1e-4), }; DayCounter dc = new Actual360(); Date today = Date.Today; SimpleQuote spot = new SimpleQuote(100.0); SimpleQuote qRate = new SimpleQuote(0.04); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); SimpleQuote rRate = new SimpleQuote(0.01); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new AssetOrNothingPayoff(values[i].type, values[i].strike); Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); Exercise amExercise = new AmericanExercise(today, exDate, true); spot.setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle <Quote>(spot), new Handle <YieldTermStructure>(qTS), new Handle <YieldTermStructure>(rTS), new Handle <BlackVolTermStructure>(volTS)); IPricingEngine engine = new AnalyticBinaryBarrierEngine(stochProcess); BarrierOption opt = new BarrierOption(values[i].barrierType, values[i].barrier, 0, payoff, amExercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, values[i].barrier, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); } } }
public BarrierOperand(BarrierOption barrierOption) : base(PrimitiveType.Byte) { this.Option = barrierOption; }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BarrierOption obj) { return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr); }
private double CalcSinglePv(BarrierOption option, IMarketCondition market) { var strike = option.Strike; var lnK = Math.Log(strike); var spot = market.SpotPrices.Value.Values.First(); var x0 = Math.Log(spot); var a = Math.Log(option.Barrier); var b = Math.Log(option.UpperBarrier); var exerciseDate = option.ExerciseDates.Last(); var volatility = market.VolSurfaces.Value.Values.First().GetValue(exerciseDate, option.Strike); var dist = b - a; var tmp1 = Math.Max(a, lnK); var discFact = market.DiscountCurve.Value.GetDf(market.ValuationDate, exerciseDate); var yearFrac = option.DayCount.CalcDayCountFraction(market.ValuationDate, exerciseDate); var dt = yearFrac / Steps; var upBarrier = option.UpperBarrier; var lowBarrier = option.Barrier; var random = new MersenneTwister(); var pvAvg = 0.0; var outProb = 0.0; for (int i = 0; i < NumSimulations; ++i) { var stockPrice = spot; bool isOut = false; var pv = 0.0; int j = 0; while (!isOut && j < Steps - 1) { // generate N(0,1) sample var drift = market.DiscountCurve.Value.ZeroRate(market.ValuationDate, exerciseDate) - 0.5 * volatility * volatility; var newStockPrice = stockPrice * Math.Exp(volatility * Math.Sqrt(dt) * Normal.Sample(random, 0, 1.0) + drift * dt); if (newStockPrice > option.UpperBarrier || newStockPrice < option.Barrier) // knock-out happened { isOut = true; outProb += 1.0 / NumSimulations; } else // possible barrier crossing giving two end points { var pUp = Math.Exp(-2 * Math.Log(upBarrier / stockPrice) * Math.Log(upBarrier / newStockPrice) / (dt * volatility * volatility)); var pLow = Math.Exp(-2 * Math.Log(lowBarrier / stockPrice) * Math.Log(lowBarrier / newStockPrice) / (dt * volatility * volatility)); var pOut = pUp + pLow; if (random.NextDouble() < pOut) { isOut = true; outProb += 1.0 / NumSimulations; } } stockPrice = newStockPrice; ++j; } // payoff at exercise if not knocked out if (!isOut) { var drift = market.DiscountCurve.Value.ZeroRate(market.ValuationDate, exerciseDate) - 0.5 * volatility * volatility; stockPrice *= Math.Exp(volatility * Math.Sqrt(dt) * Normal.Sample(random, 0, 1.0) + drift * dt); pv = option.OptionType == OptionType.Call ? Math.Max(stockPrice - strike, 0) : Math.Max(strike - stockPrice, 0); pvAvg += (pv + option.Coupon); //std::cout << "pv*discFact=" << pv*discFact << std::endl; } else { pvAvg += option.Rebate; } } pvAvg /= NumSimulations; return(pvAvg * option.Notional * discFact); }
private void calculate_Click(object sender, RoutedEventArgs e) { this.sw.Reset(); this.sw.Start(); graphPlot = new GraphPlotting(); this.DataContext = graphPlot; this.graphs.IsEnabled = true; if (this.simulationNumber > 500 && this.steps > 500) { this.graphs.ToolTip = "Graph may take time to load "; } else { this.graphs.ToolTip = ""; } ISecurity underlying = new Stock(this.underlyingPrice); Options option = null; switch (this.kind) { case OptionKind.ASIAN: option = new AsianOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind); break; case OptionKind.BARRIER: option = new BarrierOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind, this.rebate, this.barrierOptiont); break; case OptionKind.DIGITAL: option = new DigitalOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind, this.rebate); break; case OptionKind.EUROPEAN: option = new EuropeanOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind); break; case OptionKind.LOOKBACK: option = new LookbackOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind); break; case OptionKind.RANGE: option = new RangeOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind); break; default: option = new EuropeanOption(underlying.Symbol, underlying, this.maturityDate, this.strike, this.vol, this.type, this.kind); break; } try { Task work = Task.Factory.StartNew(() => { this.Dispatcher.Invoke(() => this.progress.IsActive = true); option.calulateOptionPriceAndGreeks(this.simulationNumber, this.rate, this.steps, this.anitheticReductionEnabled, this.controlVariateEnabled, this.multithreadingEnabled, plot: this.graphPlot); this.sw.Stop(); this.Dispatcher.Invoke(() => { display(option); this.progress.IsActive = false; }); }); } catch (Exception message) { MessageBox.Show(message.Message.ToString() + "\n" + message.StackTrace.ToString()); } }
private void bPriceOptionBook_Click(object sender, RoutedEventArgs e) { graphPlot = new GraphPlotting(); graphs.DataContext = graphPlot; Task work = Task.Factory.StartNew(() => { var orderBook = model.OrderBookDBs.ToList(); foreach (var trade in orderBook) { if (trade.InstrumentsDB.SecurityTypeDB.TypeName.Equals("Stocks")) { var instrument = model.StockDBs.Where(x => x.Symbol == trade.InstrumentsDB.Symbol).First(); trade.FairPrice = trade.Price; trade.Delta = trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity; trade.ProfitLoss = 0; trade.Theta = 0; trade.Gamma = 0; trade.Vega = 0; trade.Rho = 0; lock (lck) { model.SaveChanges(); } } else if (trade.InstrumentsDB.SecurityTypeDB.TypeName.Equals("Options")) { var instrument = model.OptionsDBs.Where(x => x.Symbol == trade.InstrumentsDB.Symbol).First(); Options option = null; ISecurity underlying = new Stock(instrument.StockDB.LastTradedPrice); switch (instrument.OptionKindDB.OptionKindName) { case "Asian Option": option = new AsianOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.ASIAN); break; case "Barrier Option": option = new BarrierOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.BARRIER, (Double)instrument.Barrier, (instrument.BarrierOptionType == "downout" ? BarrierOptionType.DOWNOUT : (instrument.BarrierOptionType == "downin" ? BarrierOptionType.DOWNIN : (instrument.BarrierOptionType == "upout" ? BarrierOptionType.UPOUT : BarrierOptionType.UPIN)))); break; case "Digital Option": option = new DigitalOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.DIGITAL, (Double)instrument.Rebate); break; case "European Option": option = new EuropeanOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.EUROPEAN); break; case "Lookback Option": option = new LookbackOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.LOOKBACK); break; case "Range Option": option = new RangeOption(instrument.Symbol, underlying, instrument.MaturityDate, (Double)instrument.StrikePrice, instrument.StockDB.HistoricalVolatility, instrument.OptionType == "CALL" ? OptionType.CALL : OptionType.PUT, OptionKind.RANGE); break; default: break; } try { option.calulateOptionPriceAndGreeks(1000, 0.05, (option.ExpiryDate - DateTime.Now).Days, true, option.OptionKind == OptionKind.EUROPEAN ? true : false, true, plot: graphPlot); trade.FairPrice = Math.Round(option.Price, 4); trade.ProfitLoss = Math.Round((Double)trade.FairPrice - (Double)trade.Price, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); trade.Delta = Math.Round(option.Greeks.Delta, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); trade.Theta = Math.Round(option.Greeks.Theta, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); trade.Gamma = Math.Round(option.Greeks.Gamma, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); trade.Vega = Math.Round(option.Greeks.Vega, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); trade.Rho = Math.Round(option.Greeks.Rho, 4) * (trade.Position == "BUY" ? trade.Quantity : -1 * trade.Quantity); lock (lck) { model.SaveChanges(); } } catch (Exception message) { MessageBox.Show(message.Message.ToString() + "\n" + message.StackTrace.ToString()); } } } this.Dispatcher.Invoke(() => { dataGrid.DataContext = orderBook; }); }); }
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; object[] parameters = e.Argument as object[]; int steps = Convert.ToInt16(parameters[5]); int trials = Convert.ToInt32(parameters[6]); double s = Convert.ToDouble(parameters[0]); double k = Convert.ToDouble(parameters[1]); double t = Convert.ToDouble(parameters[2]); double sig = Convert.ToDouble(parameters[3]); double r = Convert.ToDouble(parameters[4]); string type = parameters[7].ToString(); double exoticAmount = Convert.ToDouble(parameters[8]); try { for (int i = 1; i <= 1; i++) { if (worker.CancellationPending == true) { e.Cancel = true; break; } else { switch (type) { case "None": e.Result = EuropeanOption.GetDataSet(steps, trials, s, k, t, sig, r); break; case "Asian": e.Result = AsianOption.GetDataSet(steps, trials, s, k, t, sig, r); break; case "Barrier": e.Result = BarrierOption.GetDataSet(steps, trials, s, k, t, sig, r, exoticAmount); break; case "Digital": e.Result = DigitalOption.GetDataSet(steps, trials, s, k, t, sig, r, exoticAmount); break; case "Lookback": e.Result = LookBackOption.GetDataSet(steps, trials, s, k, t, sig, r, exoticAmount); break; case "Range": e.Result = RangeOption.GetDataSet(steps, trials, s, k, t, sig, r, exoticAmount); break; default: break; } // Perform a time consuming operation and report progress. Thread.Sleep(100); worker.ReportProgress(i * 100); } } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
public void testMethodOfLinesAndCN() { //Testing method of lines to solve Heston PDEs... using (SavedSettings backup = new SavedSettings()) { DayCounter dc = new Actual365Fixed(); Date today = new Date(21, 2, 2018); Settings.Instance.setEvaluationDate(today); Handle <Quote> spot = new Handle <Quote>(new SimpleQuote(100.0)); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.0, dc)); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(today, 0.0, dc)); double v0 = 0.09; double kappa = 1.0; double theta = v0; double sigma = 0.4; double rho = -0.75; Date maturity = today + new Period(3, TimeUnit.Months); HestonModel model = new HestonModel( new HestonProcess(rTS, qTS, spot, v0, kappa, theta, sigma, rho)); int xGrid = 21; int vGrid = 7; IPricingEngine fdmDefault = new FdHestonVanillaEngine(model, 10, xGrid, vGrid, 0); IPricingEngine fdmMol = new FdHestonVanillaEngine( model, 10, xGrid, vGrid, 0, new FdmSchemeDesc().MethodOfLines()); PlainVanillaPayoff payoff = new PlainVanillaPayoff(Option.Type.Put, spot.currentLink().value()); VanillaOption option = new VanillaOption(payoff, new AmericanExercise(maturity)); option.setPricingEngine(fdmMol); double calculatedMoL = option.NPV(); option.setPricingEngine(fdmDefault); double expected = option.NPV(); double tol = 0.005; double diffMoL = Math.Abs(expected - calculatedMoL); if (diffMoL > tol) { QAssert.Fail("Failed to reproduce european option values with MOL" + "\n calculated: " + calculatedMoL + "\n expected: " + expected + "\n difference: " + diffMoL + "\n tolerance: " + tol); } IPricingEngine fdmCN = new FdHestonVanillaEngine(model, 10, xGrid, vGrid, 0, new FdmSchemeDesc().CrankNicolson()); option.setPricingEngine(fdmCN); double calculatedCN = option.NPV(); double diffCN = Math.Abs(expected - calculatedCN); if (diffCN > tol) { QAssert.Fail("Failed to reproduce european option values with Crank-Nicolson" + "\n calculated: " + calculatedCN + "\n expected: " + expected + "\n difference: " + diffCN + "\n tolerance: " + tol); } BarrierOption barrierOption = new BarrierOption(Barrier.Type.DownOut, 85.0, 10.0, payoff, new EuropeanExercise(maturity)); barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11)); double expectedBarrier = barrierOption.NPV(); barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11, 0, new FdmSchemeDesc().MethodOfLines())); double calculatedBarrierMoL = barrierOption.NPV(); double barrierTol = 0.01; double barrierDiffMoL = Math.Abs(expectedBarrier - calculatedBarrierMoL); if (barrierDiffMoL > barrierTol) { QAssert.Fail("Failed to reproduce barrier option values with MOL" + "\n calculated: " + calculatedBarrierMoL + "\n expected: " + expectedBarrier + "\n difference: " + barrierDiffMoL + "\n tolerance: " + barrierTol); } barrierOption.setPricingEngine(new FdHestonBarrierEngine(model, 100, 31, 11, 0, new FdmSchemeDesc().CrankNicolson())); double calculatedBarrierCN = barrierOption.NPV(); double barrierDiffCN = Math.Abs(expectedBarrier - calculatedBarrierCN); if (barrierDiffCN > barrierTol) { QAssert.Fail("Failed to reproduce barrier option values with Crank-Nicolson" + "\n calculated: " + calculatedBarrierCN + "\n expected: " + expectedBarrier + "\n difference: " + barrierDiffCN + "\n tolerance: " + barrierTol); } } }
public void testFdmHestonBarrierVsBlackScholes() { //Testing FDM with barrier option in Heston model... using (SavedSettings backup = new SavedSettings()) { NewBarrierOptionData[] values = new NewBarrierOptionData[] { /* The data below are from * "Option pricing formulas", E.G. Haug, McGraw-Hill 1998 pag. 72 */ // barrierType, barrier, rebate, type, strike, s, q, r, t, v new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 1.00, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.00, 0.08, 0.25, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.00, 0.08, 0.25, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 0.40, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.00, 0.08, 0.40, 0.35), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.00, 0.00, 1.00, 0.20), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Call, 110, 100.0, 0.00, 0.08, 1.00, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Call, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.25), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.00, 0.04, 1.00, 0.15), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownOut, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpOut, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 95.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.DownIn, 100.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 1.00, 0.15), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 90, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 100, 100.0, 0.04, 0.08, 0.50, 0.30), new NewBarrierOptionData(Barrier.Type.UpIn, 105.0, 3.0, Option.Type.Put, 110, 100.0, 0.04, 0.08, 0.50, 0.30) }; DayCounter dc = new Actual365Fixed(); Date todaysDate = new Date(28, 3, 2004); Date exerciseDate = new Date(28, 3, 2005); Settings.Instance.setEvaluationDate(todaysDate); Handle <Quote> spot = new Handle <Quote>(new SimpleQuote(0.0)); SimpleQuote qRate = new SimpleQuote(0.0); Handle <YieldTermStructure> qTS = new Handle <YieldTermStructure>(Utilities.flatRate(qRate, dc)); SimpleQuote rRate = new SimpleQuote(0.0); Handle <YieldTermStructure> rTS = new Handle <YieldTermStructure>(Utilities.flatRate(rRate, dc)); SimpleQuote vol = new SimpleQuote(0.0); Handle <BlackVolTermStructure> volTS = new Handle <BlackVolTermStructure>(Utilities.flatVol(vol, dc)); BlackScholesMertonProcess bsProcess = new BlackScholesMertonProcess(spot, qTS, rTS, volTS); IPricingEngine analyticEngine = new AnalyticBarrierEngine(bsProcess); for (int i = 0; i < values.Length; i++) { Date exDate = todaysDate + Convert.ToInt32(values[i].t * 365 + 0.5); Exercise exercise = new EuropeanExercise(exDate); (spot.currentLink() as SimpleQuote).setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); StrikedTypePayoff payoff = new PlainVanillaPayoff(values[i].type, values[i].strike); BarrierOption barrierOption = new BarrierOption(values[i].barrierType, values[i].barrier, values[i].rebate, payoff, exercise); double v0 = vol.value() * vol.value(); HestonProcess hestonProcess = new HestonProcess(rTS, qTS, spot, v0, 1.0, v0, 0.005, 0.0); barrierOption.setPricingEngine(new FdHestonBarrierEngine(new HestonModel(hestonProcess), 200, 101, 3)); double calculatedHE = barrierOption.NPV(); barrierOption.setPricingEngine(analyticEngine); double expected = barrierOption.NPV(); double tol = 0.0025; if (Math.Abs(calculatedHE - expected) / expected > tol) { QAssert.Fail("Failed to reproduce expected Heston npv" + "\n calculated: " + calculatedHE + "\n expected: " + expected + "\n tolerance: " + tol); } } } }
public void testCashOrNothingHaugValues() { // Testing cash-or-nothing barrier options against Haug's values BinaryOptionData[] values = { /* The data below are from * "Option pricing formulas 2nd Ed.", E.G. Haug, McGraw-Hill 2007 pag. 180 - cases 13,14,17,18,21,22,25,26 * Note: * q is the dividend rate, while the book gives b, the cost of carry (q=r-b) */ // barrierType, barrier, cash, type, strike, spot, q, r, t, vol, value, tol new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9289, 1e-4), new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 6.2150, 1e-4), // following value is wrong in book. new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.8926, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4519, 1e-4), // 17,18 new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.4314, 1e-4), new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 3.1454, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 5.3297, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.7704, 1e-4), // 21,22 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.8758, 1e-4), new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 4.9081, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 0.0407, 1e-4), // 25,26 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 102.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0323, 1e-4), new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 102.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0461, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 3.0054, 1e-4), // other values calculated with book vba new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, -0.14, 0.10, 0.5, 0.20, 8.6806, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 102.00, 95.00, 0.03, 0.10, 0.5, 0.20, 5.3112, 1e-4), // degenerate conditions (barrier touched) new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Call, 98.00, 95.00, 0.00, 0.10, 0.5, 0.20, 7.4926, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Call, 98.00, 105.00, 0.00, 0.10, 0.5, 0.20, 11.1231, 1e-4), // 17,18 new BinaryOptionData(Barrier.Type.DownIn, 100.00, 15.00, Option.Type.Put, 102.00, 98.00, 0.00, 0.10, 0.5, 0.20, 7.1344, 1e-4), new BinaryOptionData(Barrier.Type.UpIn, 100.00, 15.00, Option.Type.Put, 102.00, 101.00, 0.00, 0.10, 0.5, 0.20, 5.9299, 1e-4), // 21,22 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Call, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Call, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), // 25,26 new BinaryOptionData(Barrier.Type.DownOut, 100.00, 15.00, Option.Type.Put, 98.00, 99.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), new BinaryOptionData(Barrier.Type.UpOut, 100.00, 15.00, Option.Type.Put, 98.00, 101.00, 0.00, 0.10, 0.5, 0.20, 0.0000, 1e-4), }; DayCounter dc = new Actual360(); Date today = Date.Today; SimpleQuote spot = new SimpleQuote(100.0); SimpleQuote qRate = new SimpleQuote(0.04); YieldTermStructure qTS = Utilities.flatRate(today, qRate, dc); SimpleQuote rRate = new SimpleQuote(0.01); YieldTermStructure rTS = Utilities.flatRate(today, rRate, dc); SimpleQuote vol = new SimpleQuote(0.25); BlackVolTermStructure volTS = Utilities.flatVol(today, vol, dc); for (int i = 0; i < values.Length; i++) { StrikedTypePayoff payoff = new CashOrNothingPayoff(values[i].type, values[i].strike, values[i].cash); Date exDate = today + Convert.ToInt32(values[i].t * 360 + 0.5); Exercise amExercise = new AmericanExercise(today, exDate, true); spot.setValue(values[i].s); qRate.setValue(values[i].q); rRate.setValue(values[i].r); vol.setValue(values[i].v); BlackScholesMertonProcess stochProcess = new BlackScholesMertonProcess( new Handle <Quote>(spot), new Handle <YieldTermStructure>(qTS), new Handle <YieldTermStructure>(rTS), new Handle <BlackVolTermStructure>(volTS)); IPricingEngine engine = new AnalyticBinaryBarrierEngine(stochProcess); BarrierOption opt = new BarrierOption(values[i].barrierType, values[i].barrier, 0, payoff, amExercise); opt.setPricingEngine(engine); double calculated = opt.NPV(); double error = Math.Abs(calculated - values[i].result); if (error > values[i].tol) { REPORT_FAILURE("value", payoff, amExercise, values[i].barrierType, values[i].barrier, values[i].s, values[i].q, values[i].r, today, values[i].v, values[i].result, calculated, error, values[i].tol); } } }
internal static global::System.Runtime.InteropServices.HandleRef getCPtr(BarrierOption obj) { return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr; }
private void priceTradeBookToolStripMenuItem_Click(object sender, EventArgs e) { foreach (ListViewItem i in ListTrade.Items) { Int32 tmp = Convert.ToInt32(i.Text); Trade tt = (from q in AppEntities.Trades where q.Id == tmp select q).FirstOrDefault(); double s = getLatestPrice(tt.Instrument); double k = Convert.ToDouble(tt.Instrument.Strike); double t = (double)tt.Instrument.Tenor; double r = getInterestRate(tt.Instrument); double sig = Convert.ToDouble(textBoxVol.Text) / 100.0; int instrumentTypeId = (Int32)tt.Instrument.InstrumentTypeId; int barrierTypeId = (Int32)tt.Instrument.BarrierTypeId; double barrier = (double)tt.Instrument.Barrier; double rebate = (double)tt.Instrument.Rebate; int steps = 100, trials = 10000; DataSet result = new DataSet(); Dictionary <String, double> stockMetric = new Dictionary <string, double>(); stockMetric.Add("Delta", 1); switch (instrumentTypeId) { case 1: stockMetric.Add("Delta", 1); break; case 2: result = AsianOption.GetDataSet(steps, trials, s, k, t, sig, r); break; case 3: result = EuropeanOption.GetDataSet(steps, trials, s, k, t, sig, r); break; case 4: result = BarrierOption.GetDataSet(steps, trials, s, k, t, sig, r, barrier); break; case 5: result = RangeOption.GetDataSet(steps, trials, s, k, t, sig, r, rebate); break; case 6: result = LookBackOption.GetDataSet(steps, trials, s, k, t, sig, r, 0); break; default: break; } ListViewItem i2; i2 = new ListViewItem(); i2.Text = tt.Id.ToString(); i2.SubItems.Add(tt.Instrument.Ticker); i2.SubItems.Add(tt.Instrument.InstrumentType.TypeName); i2.SubItems.Add(tt.IsBuy ? "BUY" : "SELL"); i2.SubItems.Add(tt.Quantity.ToString()); i2.SubItems.Add(tt.Price.ToString()); i2.SubItems.Add("10"); i2.SubItems.Add("10"); i2.SubItems.Add("10"); i2.SubItems.Add("10"); i2.SubItems.Add("10"); i2.SubItems.Add("10"); i2.SubItems.Add("10"); ListTrade.Items.Add(i2); } }