using YLErp.BLL.Calculation.V2.Parameter; namespace YLErp.BLL.Calculation.V2 { class ParameterHelper { public static ParameterBase CreatePricingParameter( underlying_manager underlying, Variety variety, trade trade, double[] vols, double[] spotPrices, string fixing, bool preciseTimeMode, double[] correlations, string discountCurveName, double timeToMaturityDays, string engineName) { engineName = ConsTrade.GetEngineName(engineName); switch (trade.TradeType) { case "香草期权": case "场内期权": case "Risky期权": return CreateVanillaOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "障碍期权": return CreateBarrierOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "亚式期权": return CreateAsianOptionParameter(trade, underlying, variety, vols, spotPrices, fixing, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "二元期权": return CreateBinaryOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "彩虹期权": return CreateRainbowOptionParameter(trade, underlying, variety, vols, spotPrices, correlations, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "价差期权": return CreateSpreadOptionParameter(trade, underlying, variety, vols, spotPrices, correlations, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "合成价差期权": return CreateSyntheticNormalSpreadOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "双鲨期权": return CreateDoubleSharkFinOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "凤凰期权": return CreateAutocallOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "雪球期权": return CreateSnowballOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "累计期权": return CreateAccumulatorOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "区间累积期权": return CreateRangeAccrualParameter(trade, underlying, variety, vols, spotPrices, fixing, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "气囊结构": return CreateAirbagParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "收益增强结构": return CreateUnderlyingEnhanceParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); case "信用债": case "商品期货": case "股票": return CreateUnderlyingProductParameter(underlying, spotPrices); case "现金流交易": return CreateTradeCashParameter(trade, underlying); case "结构化产品": return CreateVanillaOptionParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName, timeToMaturityDays, engineName); default: break; } if (trade.TradeType.StartsWith("自定义_")) { return CreateUserDefinedStrucutreParameter(trade, underlying, variety, vols, spotPrices, preciseTimeMode, discountCurveName); } throw new Exception($"不支持交易结构{trade.TradeType}的参数生成"); } private static ParameterBase CreateVanillaOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new VanillaOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateBarrierOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new BarrierOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateAsianOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, string fixing, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new AsianOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, Fixings = fixing, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateBinaryOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new BinaryOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateRainbowOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, double[] correlations, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new RainbowOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], Volatility2 = vols.Length > 1 ? vols[1] : trade.trade_rainbow_option.Vol2, SpotPrices = new Dictionary() { { underlying.UnderlyingCode, spotPrices[0] }, { trade.trade_rainbow_option.UnderlyingAssetCode2, spotPrices.Length > 1 ? spotPrices[1] : (trade.trade_rainbow_option.SpotPrice2 ?? 0) } }, Correlation = correlations != null ? correlations[0] : (trade.trade_rainbow_option.CorRelation ?? 0.0), HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateSpreadOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, double[] correlations, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new SpreadOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatilities = vols.ToArray(), SpotPrices = new Dictionary(), Correlations = correlations.ToArray(), HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; parameter.SpotPrices[underlying.UnderlyingCode] = spotPrices[0]; parameter.SpotPrices[trade.trade_spread_option.UnderlyingAssetCode2] = spotPrices[1]; if (spotPrices.Length >= 3) { parameter.SpotPrices[trade.trade_spread_option.UnderlyingAssetCode3] = spotPrices[2]; } if (spotPrices.Length == 4) { parameter.SpotPrices[trade.trade_spread_option.UnderlyingAssetCode4] = spotPrices[3]; } if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateSyntheticNormalSpreadOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new SyntheticNormalSpreadOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateDoubleSharkFinOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new DoubleSharkFinOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateAutocallOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new AutocallParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateSnowballOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new SnowballParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateRangeAccrualParameter(trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, string fixing, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new RangeAccrualParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, Fixings = fixing, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateAirbagParameter(trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new AirbagParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateUnderlyingEnhanceParameter(trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new UnderlyingEnhanceParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateAccumulatorOptionParameter( trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, double timeToMaturityDays, string engineName) { var parameter = new AccumulatorOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, EngineName = engineName }; if (!double.IsNaN(timeToMaturityDays)) { parameter.OverrideTTM = timeToMaturityDays; } if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } private static ParameterBase CreateUnderlyingProductParameter(underlying_manager underlying, double[] spotPrices) { return new ParameterBase() { SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } } }; } public static ParameterBase CreateUserDefinedStrucutreParameter(trade trade, underlying_manager underlying, Variety variety, double[] vols, double[] spotPrices, bool preciseTimeMode, string discountCurveName, bool useDraftCode = false) { var parameter = new UserDefinedOptionParameter() { ValueDate = underlying.QuotationDate.Value, Volatility = vols[0], SpotPrices = new Dictionary { { underlying.UnderlyingCode, spotPrices[0] } }, HasNightMarket = variety?.HasNightMarket ?? false, PreciseTimeMode = preciseTimeMode, UseDraftCode = useDraftCode }; if (string.IsNullOrWhiteSpace(discountCurveName)) { parameter.RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate / 100.0); } else { parameter.DiscountCurveName = discountCurveName; } parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } public static ParameterBase CreateTradeCashParameter(trade trade, underlying_manager underlying) { var parameter = new CashFlowTradeParameter() { ValueDate = underlying.QuotationDate.Value, SpotPrices = new Dictionary { { "", 0 } }, RiskFreeRate = trade.NoRiskRate ?? 0.0, }; parameter.DividendRate = trade.DividendRate ?? 0; return parameter; } } }