public override IEngine <ConvertibleBond> GenerateEngine() { var optionInfo = TradeInfo.ConversionOption; var exercise = optionInfo.Exercise.ToOptionExercise(); IEngine <VanillaOption> optionEngine = null; if (exercise == OptionExercise.European) { //不该用MonteCarlo 直接判断 逻辑更合理 if (optionInfo.MonteCarlo) { optionEngine = new GenericMonteCarloEngine(optionInfo.ParallelDegree ?? 2, optionInfo.NSimulations ?? 50000); return(new SimpleConvertibleBondEngine <GenericMonteCarloEngine>(optionEngine as GenericMonteCarloEngine)); } else { optionEngine = new AnalyticalVanillaEuropeanOptionEngine(); return(new SimpleConvertibleBondEngine <AnalyticalVanillaEuropeanOptionEngine>(optionEngine as AnalyticalVanillaEuropeanOptionEngine)); } } else if (exercise == OptionExercise.American) { optionEngine = new BinomialTreeAmericanEngine(BinomialTreeType.CoxRossRubinstein, 100); return(new SimpleConvertibleBondEngine <BinomialTreeAmericanEngine>(optionEngine as BinomialTreeAmericanEngine)); } else { throw new PricingBaseException("Conversion option exercise type should be European or American!"); } }
//TODO: enable true MC pricer after CB MC model improvement public void TestConvertibleBond_American_MCPricer() { var convertibleBond = GeliCB(American: true); var optionEngine = new GenericMonteCarloEngine(2, 50000); var engine = new SimpleConvertibleBondEngine <GenericMonteCarloEngine>(optionEngine as GenericMonteCarloEngine); var market = TestMarket_Jin("2017-10-20", spot: 6.07); var result = engine.Calculate(convertibleBond, market, PricingRequest.All); var optionPrem = market.MktQuote.Value[convertibleBond.Bond.Id].Item2 - result.Pv; Assert.AreEqual(convertibleBond.ConversionRatio * 1.603780133, optionPrem, 1e-7); }
public void TestVanillaEuropeanCallMc() { var startDate = new Date(2014, 03, 18); var maturityDate = new Date(2015, 03, 18); var market = TestMarket(); var call = new VanillaOption(startDate, maturityDate, OptionExercise.European, OptionType.Call, 1.0, InstrumentType.Stock, CalendarImpl.Get("chn"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { maturityDate }, new[] { maturityDate }); var mcengine = new GenericMonteCarloEngine(2, 200000); var result = mcengine.Calculate(call, market, PricingRequest.All); var analyticalResult = new AnalyticalVanillaEuropeanOptionEngine().Calculate(call, market, PricingRequest.All); Console.WriteLine("{0},{1}", analyticalResult.Pv, result.Pv); Console.WriteLine("{0},{1}", analyticalResult.Delta, result.Delta); Console.WriteLine("{0},{1}", analyticalResult.Gamma, result.Gamma); Console.WriteLine("{0},{1}", analyticalResult.Vega, result.Vega); Console.WriteLine("{0},{1}", analyticalResult.Rho, result.Rho); Console.WriteLine("{0},{1}", analyticalResult.Theta, result.Theta); Assert.AreEqual(analyticalResult.Pv, result.Pv, 0.002); Assert.AreEqual(analyticalResult.Delta, result.Delta, 0.02); Assert.AreEqual(analyticalResult.Gamma, result.Gamma, 0.05); Assert.AreEqual(analyticalResult.Theta, result.Theta, 1e-5); Assert.AreEqual(analyticalResult.Rho, result.Rho, 1e-6); Assert.AreEqual(analyticalResult.Vega, result.Vega, 1e-4); }
//Takes too long time //[TestMethod] public void CommodityBinaryEuropeanOptionMcTest() { var goldOption = new BinaryOption( new Date(2015, 03, 20), new Date(2015, 06, 16), OptionExercise.European, OptionType.Put, 231.733, InstrumentType.Futures, BinaryOptionPayoffType.CashOrNothing, 10.0, CalendarImpl.Get("chn"), new Act365(), CurrencyCode.CNY, CurrencyCode.CNY, new[] { new Date(2015, 06, 16) }, new[] { new Date(2015, 06, 16) }, 1.0 ); var market = GetMarket(); var volsurf = market.GetData <VolSurfMktData>("goldVolSurf").ToImpliedVolSurface(market.ReferenceDate); var yc = market.GetData <CurveData>("Fr007").YieldCurve; IMarketCondition marketCondition = new MarketCondition( x => x.ValuationDate.Value = market.ReferenceDate, x => x.DiscountCurve.Value = yc, x => x.DividendCurves.Value = new Dictionary <string, IYieldCurve> { { "", yc } }, x => x.SpotPrices.Value = new Dictionary <string, double> { { "", 240.6 } }, x => x.VolSurfaces.Value = new Dictionary <string, IVolSurface> { { "", volsurf } } ); // set first point on dividend curve to 0 //MC pricing var dc = ZeroRateCurve(marketCondition.DividendCurves.Value.Values.First()); marketCondition = marketCondition.UpdateCondition(new UpdateMktConditionPack <Dictionary <string, IYieldCurve> >(x => x.DividendCurves, new Dictionary <string, IYieldCurve> { { "", dc } })); var engine = new GenericMonteCarloEngine(2, 500000); var result = engine.Calculate(goldOption, marketCondition, PricingRequest.All); //analytical pricing var analyticalResult = new AnalyticalBinaryEuropeanOptionEngine().Calculate(goldOption, marketCondition, PricingRequest.All); Console.WriteLine("Pv:{0},{1}", analyticalResult.Pv, result.Pv); Console.WriteLine("Delta: {0},{1}", analyticalResult.Delta, result.Delta); Console.WriteLine("Gamma: {0},{1}", analyticalResult.Gamma, result.Gamma); Console.WriteLine("Vega: {0},{1}", analyticalResult.Vega, result.Vega); Console.WriteLine("Rho: {0},{1}", analyticalResult.Rho, result.Rho); //TODO binary option monte carlo rho Console.WriteLine("Theta: {0},{1}", analyticalResult.Theta, result.Theta); //Assert.AreEqual(analyticalResult.Pv, result.Pv, 0.02); //Assert.AreEqual(analyticalResult.Delta, result.Delta, 0.02); //Assert.AreEqual(analyticalResult.Gamma, result.Gamma, 0.05); //Assert.AreEqual(analyticalResult.Vega, result.Vega, 1e-2); //Assert.AreEqual(analyticalResult.Rho, result.Rho, 1e-6); //Assert.AreEqual(analyticalResult.Theta, result.Theta, 1e-5); }