Files
zszq-trs/YLErpDAL/BLL/Calculation/Engine/BarrierEngineFactory.cs
T
2024-05-09 14:06:26 +08:00

128 lines
5.6 KiB
C#

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}.无法创建计算引擎");
}
}
}
}