using Qdp.Pricing.Base.Enums; using Qdp.Pricing.Library.Common.Interfaces; using Qdp.Pricing.Library.Options.MonteCarlo; using Qdp.Pricing.Library.Options.Products.Barrier; using Qdp.Pricing.Library.Options.Products.Barrier.Engines.Analytical; using Qdp.Pricing.Library.Options.Products.Barrier.Engines.Numerical; using Qdp.Pricing.Library.Options.Products.Barrier.Engines.Numerical.Quad; namespace YLErp.BLL.Calculation.Engine { class BarrierEngineFactory : OptionEngineFactoryBase { public static BarrierEngineFactory Instance { get { if (_instance == null) { _instance = new BarrierEngineFactory(); } return _instance; } } protected BarrierEngineFactory() { } protected static BarrierEngineFactory _instance; public override IEngine GetEngine( string engineName = null, OptionExercise exercise = OptionExercise.European, params object[] additionalParams) { if (string.IsNullOrWhiteSpace(engineName)) { return DefaultEngine(exercise, additionalParams); } else { switch (engineName.ToUpper()) { case "ANALYTICALBARRIEREUROPEANOPTIONENGINE": return new AnalyticalBarrierEuropeanOptionEngine(); case "FDIMPLICITBARRIEROPTIONENGINE": return new FdImplicitBarrierOptionEngine(); case "QUADRATUREBARRIEROPTIONENGINE": return new QuadratureBarrierOptionEngine(); case "GENERICMONTECARLOENGINE": return CreateGenericMonteCarloEngine(additionalParams); case "GBMMONTECARLOENGINE": return new GbmMonteCarloEngine(100000, 1e-3, 1e-6, 1); default: if (engineName.IsValidEngineName()) { return OptionEngineRepository.CreateEngine(engineName); } else { return DefaultEngine(exercise, additionalParams); } } } } private IEngine DefaultEngine( OptionExercise exercise, params object[] additionalParams) { switch (exercise) { case OptionExercise.European: if (additionalParams.Length > 1) { var barrierOption = (BarrierOption)additionalParams[0]; var customizedObservation = (bool)additionalParams[1]; var quadratureFastMode = false; if (additionalParams.Length > 2) { quadratureFastMode = (bool)additionalParams[2]; } //年化敲出补偿且不是双障碍 if (barrierOption.RebateAnnualizedAtKO) { if (!(barrierOption.BarrierType == BarrierType.DoubleTouchIn || barrierOption.BarrierType == BarrierType.DoubleTouchOut)) return new QuadBarrierOptionEngine(parallelDegree: quadratureFastMode ? Environment.ProcessorCount : PS.Config.ErpElement.QdpParallelDegree); } if (barrierOption.BarrierType == BarrierType.DoubleTouchIn || barrierOption.BarrierType == BarrierType.DoubleTouchOut) { return new AnalyticalDoubleBarrierEuropeanOptionEngine(false); } else if (barrierOption.BarrierType == BarrierType.KIKO) { return new AnalyticalKiKoOptionEngine(); } else if(customizedObservation) { //仅在到期日观察 if (barrierOption.BarrierObservationDates.Length > 0 && barrierOption.BarrierObservationDates[0] == barrierOption.ExerciseDates[0]) { return new AnalyticalBarrierEuropeanOptionReplicationEngine(); } else { return new QuadBarrierOptionEngine(parallelDegree: quadratureFastMode ? Environment.ProcessorCount : PS.Config.ErpElement.QdpParallelDegree); } } } return string.IsNullOrWhiteSpace(OptionEngineRepository.BarrierEuropeanDefaultEngine) ? new AnalyticalBarrierEuropeanOptionEngine() : OptionEngineRepository.CreateEngine(OptionEngineRepository.BarrierEuropeanDefaultEngine); case OptionExercise.American: return string.IsNullOrWhiteSpace(OptionEngineRepository.BarrierAmericanDefaultEngine) ? new AnalyticalBarrierEuropeanOptionEngine() // new FdImplicitBarrierOptionEngine() 原来采用的是这个引擎 : OptionEngineRepository.CreateEngine(OptionEngineRepository.BarrierAmericanDefaultEngine); default: throw new Exception($"障碍期权不支持的行权方式{exercise}.无法创建计算引擎"); } } } }