using Qdp.Foundation.Implementations; using Qdp.Pricing.Base.Enums; using Qdp.Pricing.Base.Implementations; using Qdp.Pricing.Base.Utilities; using Qdp.Pricing.Library.Base.Curves.Interfaces; using Qdp.Pricing.Library.Common.Interfaces; using Qdp.Pricing.Library.Common.Market; using Qdp.Pricing.Library.Options.MonteCarlo; using Qdp.Pricing.Library.Options.Products.Asian; using YLErp.BLL.Calculation; using YLErp.Enums; using YLErp.Modules.ApiModule.PricingModule.CustomizedAsianPricing; using YLErp.Modules.CalculationModule; using YLErp.Modules.PricingModule; using YLErp.QdpModule; namespace YLErp.Modules.ApiModule.PricingModule { /// /// 期权定价api服务 /// public partial class OptionPricingApiService { /// /// 获取期权定价结果 /// public CalcOptionPriceResult GetOptionPrice(OptionPricingModelV2 req) { if (req.ExtendFields != null && req.ExtendFields.Count > 0) { var dic = new Dictionary(StringComparer.OrdinalIgnoreCase); foreach (var kv in req.ExtendFields) { dic[kv.Key] = req.ExtendFields[kv.Key]; } req.ExtendFields = dic; } OptionPricingApiHelper.CheckPricingRequestData(req); string fixings = null; if (req.ExtendFields != null) { req.ExtendFields.TryGetValue("fixings", out fixings); } var result = new PriceCalcService(OptUserInfo.SystemUser).CalcOptionPrice(req, req.IsCalcMargin , CalcScenarioEnum.Pricing, req.IsCalcGreeks, fixings: fixings); return result; } public CalcOptionPriceResult GetCustomizedAsianOptionPrice(CustomizedAsianPricingModel req) { var startDate = new Date(req.StartDate.Value); var maturityDate = new Date(req.ExerciseDate.Value); var callPut = req.CallPut.ToUpper() == "PUT" ? OptionType.Put : OptionType.Call; var lockObsStartDate = new Date(req.LockObsStartDate); var lockObsEndDate = new Date(req.LockObsEndDate); var lockStartDate = new Date(req.LockStartDate); var calendar = CalendarImpl.Get("chn"); var dayCount = CalculatorHelper.GetTradeDayCount().ToDayCountImpl(); var option = new EnhancedAsianOptionWithLockAndBarrier( startDate, maturityDate, OptionExercise.European, callPut, strike: req.Strike.Value, lockPrice: req.LockPrice, barrierPrice: req.BarrierPrice.HasValue ? req.BarrierPrice.Value : double.NaN, // 13659.26, isLocked: req.IsLocked, lockObsStartDate: lockObsStartDate, lockObsEndDate: lockObsEndDate, lockStartDate: lockStartDate, underlyingInstrumentType: InstrumentType.CommodityFutures, calendar: calendar, dayCount: dayCount, payoffCcy: CurrencyCode.CNY, settlementCcy: CurrencyCode.CNY, exerciseDates: new Date[] { maturityDate }, observationDates: calendar.BizDaysBetweenDatesExcluStartDay(lockObsEndDate, maturityDate).ToArray(), fixings: QdpHelper.ParseFixingsFromString(req.Fixings), avgPriceRate: req.AvgPriceRate.HasValue ? req.AvgPriceRate.Value : 1.0, finalPriceSpread: req.FinalPriceSpread.HasValue ? req.FinalPriceSpread.Value : 0.0, notional: req.Notional); var mcEngine = new GbmMonteCarloEngine(5000, 1e-3, 1e-6, 1, true); var vol = req.Vol.Value; var spot = req.SpotPrice.Value; var r = req.RiskFreeRate.Value; var q = req.DividendRate.Value; var valueDate = new Date(req.ValueDate.Value); //var market = TestHelper.CreateMarket(valueDate, vol: vol, spot: spot, riskFreeRate: r, dividendRate: q); var marketProxy = new MarketProxy(valueDate, r); marketProxy.SetVolSurface("volsurf", vol); var volsurf = marketProxy.QdpMarket.VolSurfaces["volsurf"]; var dividendCurveName = Guid.NewGuid().ToString(); var dividendCurve = CalculatorHelper.CreateConstantRiskFreeCurve(dividendCurveName, q); marketProxy.SetYieldCurve(dividendCurveName, dividendCurve); var market = new MarketCondition( x => x.ValuationDate.Value = marketProxy.QdpMarket.ReferenceDate, x => x.DiscountCurve.Value = marketProxy.QdpMarket.YieldCurves[MarketProxy.RiskFreeDiscountCurve], x => x.DividendCurves.Value = new Dictionary { { "", marketProxy.QdpMarket.YieldCurves[dividendCurveName] } }, x => x.VolSurfaces.Value = new Dictionary { { "", volsurf } }, x => x.SpotPrices.Value = new Dictionary { { "", spot } } ); var result = mcEngine.Calculate(option, market, QdpPricingRequest.BASIC_GREEKS); return new CalcOptionPriceResult() { CalcId = req.CalcId, calcResult = new TradeValueResult(result) }; } } }