116 lines
4.9 KiB
C#
116 lines
4.9 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.Asian;
|
|
using Qdp.Pricing.Library.Options.Products.Asian.Engines.Analytical;
|
|
using Qdp.Pricing.Library.Options.Products.Asian.Engines.Numerical;
|
|
|
|
namespace YLErp.BLL.Calculation.Engine
|
|
{
|
|
class AsianEngineFactory : OptionEngineFactoryBase
|
|
{
|
|
public static AsianEngineFactory Instance
|
|
{
|
|
get
|
|
{
|
|
if (_instance == null)
|
|
{
|
|
_instance = new AsianEngineFactory();
|
|
}
|
|
return _instance;
|
|
}
|
|
}
|
|
protected AsianEngineFactory() { }
|
|
protected static AsianEngineFactory _instance;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="engineName"></param>
|
|
/// <param name="exercise"></param>
|
|
/// <param name="additionalParams">应该传入AverageType的值和AsianOption对象</param>
|
|
/// <returns></returns>
|
|
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 "ANALYTICALASIANOPTIONENGINE":
|
|
return new AnalyticalAsianOptionEngine();
|
|
case "BINOMIALTREEAMERICANASIANENGINE":
|
|
return new BinomialTreeAmericanAsianEngine();
|
|
case "GENERICMONTECARLOENGINE":
|
|
return CreateGenericMonteCarloEngine(additionalParams);
|
|
case "GBMMONTECARLOENGINE":
|
|
return new GbmMonteCarloEngine(100000, 1e-3, 1e-6, 1);
|
|
case "ANALYTICALENHANCEDASIANOPTIONENGINE":
|
|
AsianOption asianOption = null;
|
|
if (additionalParams != null && additionalParams.Length > 1)
|
|
{
|
|
asianOption = additionalParams[1] as AsianOption;
|
|
}
|
|
if (asianOption == null)
|
|
{
|
|
throw new Exception($"增强亚式期权计算引擎需传入期权对象.");
|
|
}
|
|
return new AnalyticalEnhancedAsianOptionEngine(asianOption);
|
|
default:
|
|
if (engineName.IsValidEngineName())
|
|
{
|
|
return OptionEngineRepository.CreateEngine(engineName);
|
|
}
|
|
else
|
|
{
|
|
return DefaultEngine(exercise);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static IEngine DefaultEngine(OptionExercise exercise, params object[] additionalParams)
|
|
{
|
|
if (additionalParams.Length > 2)
|
|
{
|
|
if ((string)additionalParams[2] == "Segmented")
|
|
{
|
|
return new GenericMonteCarloEngine(PS.Config.ErpElement.QdpParallelDegree, 50000, useConstRate: true, useConstVol: true);
|
|
}
|
|
}
|
|
|
|
if (additionalParams.Length > 1)
|
|
{
|
|
if ((string)additionalParams[0] == "EnhancedArithmeticAverage" && additionalParams[1] is AsianOption asianOption)
|
|
{
|
|
if (Math.Abs(asianOption.EnhancedPrice - asianOption.Strike) > 1e-8)
|
|
{
|
|
// 如果增强亚式 行权价格和增强价格一致,则只能使用蒙特卡洛引擎,解析解计算不准确
|
|
return new GbmMonteCarloEngine(100000, 1e-3, 1e-6, 1);
|
|
}
|
|
return new AnalyticalEnhancedAsianOptionEngine((AsianOption)additionalParams[1]);
|
|
}
|
|
}
|
|
|
|
switch (exercise)
|
|
{
|
|
case OptionExercise.European:
|
|
return string.IsNullOrWhiteSpace(OptionEngineRepository.AsianEuropeanDefaultEngine)
|
|
? new AnalyticalAsianOptionEngine()
|
|
: OptionEngineRepository.CreateEngine(OptionEngineRepository.AsianEuropeanDefaultEngine);
|
|
case OptionExercise.American:
|
|
return string.IsNullOrWhiteSpace(OptionEngineRepository.AsianAmericanDefaultEngine)
|
|
? new BinomialTreeAmericanAsianEngine()
|
|
: OptionEngineRepository.CreateEngine(OptionEngineRepository.AsianAmericanDefaultEngine);
|
|
default:
|
|
throw new Exception($"亚式期权不支持的行权方式{exercise}.无法创建计算引擎");
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|