using YLErp.BLL.Calculation; using YLErp.DBModels.Helpers; using YLErp.Enums; using YLErp.Modules.MarginModule; using YLErp.QdpModule; namespace YLErp.BLL.MarginCalculation { /// /// 申银万国 /// public class SYWGMarginCalculation : MarginCalculationBase { // 定义一个静态变量来保存类的实例 public static readonly SYWGMarginCalculation Instance; static SYWGMarginCalculation() { Instance = new SYWGMarginCalculation(); } // 定义私有构造函数,使外界不能创建该类实例 private SYWGMarginCalculation() { } public override List RunMarginCalculation(RunMarginCalculationReq req) { var tradeSpans = new List(); if (req.tradeList == null || req.tradeList.Count < 1) { return tradeSpans; } var tempStockTradeList = req.tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.Stock).ToList(); if (tempStockTradeList.Any()) { var stockTradeSpanlist = StockMarginCalculation(req.Clone(tempStockTradeList)); if (stockTradeSpanlist.Count > 0) { tradeSpans.AddRange(stockTradeSpanlist); } } var tempFutureTradeList = req.tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.CommodityFutures).ToList(); if (tempFutureTradeList.Any()) { var futureTradeSpanlist = FutureMarginCalculation(req.Clone(tempFutureTradeList)); if (futureTradeSpanlist.Count > 0) { tradeSpans.AddRange(futureTradeSpanlist); } } return tradeSpans; } /// /// 股票类期权计算预付金 /// public List StockMarginCalculation(RunMarginCalculationReq req) { var tradeSpans = new List(); if (req.tradeList == null || req.tradeList.Count < 1) { return tradeSpans; } var marginRation = valuedateBLL.SystemDate.MarginRatio ?? 0.15; var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); foreach (var t in req.tradeList) { if (!helper.GetSpecialMargin(t, 0, out var value)) { var client = helper.GetClient(t); if (client == null) { continue; } var clientRatio = client?.Ratio ?? 1.0; //如果是股票去名义本金,如果是期货取:份额 * 即期价格 value = (t.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(t.Notional * t.SpotPrice, t.ParticipationRate, t.AnnualizeFactor) : t.StockEqvNotional) * marginRation * (t.BuySell == "买入" ? 1 : 0) * clientRatio; } tradeSpans.Add(new trade_span { TradeId = t.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = t.ClientId, UnderlyingId = t.UnderlyingId, UnderlyingCode = t.UnderlyingCode, ValueDate = req.settleDate, Spv1 = value, Spv2 = value, Spv3 = value, Spv4 = value, WorstCastClientPayable = value }); } return tradeSpans; } /// /// 商品期权计算预付金 /// public List FutureMarginCalculation(RunMarginCalculationReq req) { var futureTradeList = req.tradeList; if (futureTradeList == null || !futureTradeList.Any()) { return new List(0); } var tradeSpans = new List(); var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); helper.SetFieldsByTradeType(); using (var db = new YLContext()) { var underlyingCodes = futureTradeList.Select(t => t.UnderlyingCode).ToHashSet(); var mpProvider = new MarginParamProvider(req.UserInfo, req.settleDate).Initialize(underlyingCodes, MarginParamTypeEnum.MarginRate); var overrideVolsForTrades = VolCaculator.Instance.GetVol(futureTradeList, req.settleDate); var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades( valueDate: req.settleDate, tradeList: futureTradeList, calcScenario: req.GetCalcScenario(), priceProvider: req.PriceProvider, pricingRequest: QdpPricingRequest.BASIC_GREEKS, addVolRateDic: null, volType: req.volType, overrideVolsForTrade: overrideVolsForTrades, isUseTradeVol: PS.Config.IsTradeVol, preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin); logger.Info($"商品期货预付金计算,交易入:[{futureTradeList.Count}条],返回[{tradeRiskResult.Results.Count}],错误:{tradeRiskResult.ErrorMessage}"); var alphaRate = valuedateBLL.SystemDate.FutureMarginAlphaRate ?? 1; var FutureMarginAddRatio = valuedateBLL.SystemDate.FutureMarginAddRatio ?? 0; if (tradeRiskResult.Results.Count <= 0) { return tradeSpans; } foreach (var trade in futureTradeList) { var closePrice = req.PriceProvider.GetPrice(trade.UnderlyingCode); var optionValueList = tradeRiskResult.Results.Where(t => t.Trade.id == trade.id && t.ValueResult != null && t.Trade != null && !double.IsNaN(t.ValueResult.Delta) && !double.IsNaN(t.ValueResult.Vega) && !double.IsNaN(t.ValueResult.Gamma)).ToList(); //未设置相关预付金系数默认为1.0 double clientRatio = 1, clientAddRatio = 0; var client = helper.GetClient(trade); if (client != null) { clientRatio = client.Ratio ?? 1; clientAddRatio = client.AddRatio ?? 0; } if (optionValueList.Any()) { var deltaMerge = 0.0; var deltaShort = optionValueList.Sum(t => t.ValueResult.Delta * (t.Trade.BuySell == "买入" ? 1 : 0)); var deltaMax = optionValueList.Sum(t => t.ValueResult.DeltaMax * (t.Trade.BuySell == "买入" ? 1 : 0)); //跨式组合和宽跨式组合用到的是组合交易里面的Max Delta作为deltaMerge参与预付金的计算 deltaMerge = trade.TradeType == "结构化交易" && (trade.StructureType == "跨式组合" || trade.StructureType == "宽跨式组合") ? Math.Abs(deltaMax) : Math.Abs(deltaShort); logger.Info("交易id为" + trade.id + "的delta:" + deltaMerge); //if (deltaLong * deltaShort == 0) //{ // deltaMerge = Math.Abs(deltaShort); //} //else if (deltaLong * deltaShort < 0) //{ // if (Math.Abs(deltaLong) >= Math.Abs(deltaShort)) // { // deltaMerge = 0; // } // else // { // deltaMerge = Math.Abs(deltaShort) - Math.Abs(deltaLong); // } //} //else //{ // deltaMerge = Math.Abs(deltaShort); //} mpProvider.TryGetMarginRate(trade.UnderlyingCode, out var marginRate); //预付金 = (交易预付金率+公司预付金率加点)*合约名义金额(期货价格*数量)*delta var margin = deltaMerge * closePrice * (marginRate + FutureMarginAddRatio + clientAddRatio) * alphaRate * clientRatio; if (trade.TradeType == "自定义交易") { if (helper.GetSpecialMargin(trade, 0, out var value)) { margin = value; } } tradeSpans.Add(new trade_span { TradeId = trade.id,//默认记录为第一条交易记录中 OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = trade.ClientId, ValueDate = req.settleDate, UnderlyingId = trade.UnderlyingId, UnderlyingCode = trade.UnderlyingCode, Spv1 = margin, Spv2 = margin, Spv3 = margin, Spv4 = margin, WorstCastClientPayable = margin, Comment = $"标的{trade.UnderlyingCode},deltaMerge:{deltaMerge},closePrice:{closePrice},Margin:{marginRate},FutureMarginAddRatio:{FutureMarginAddRatio},clientAddRatio:{clientAddRatio},alphaRate:{alphaRate},clientRatio:{clientRatio}" }); } else { var nanTradeValue = tradeRiskResult.Results.Where(t => t.Trade.id == trade.id && (double.IsNaN(t.ValueResult.Delta) || !double.IsNaN(t.ValueResult.Vega) || !double.IsNaN(t.ValueResult.Gamma))).Select(t => t.ValueResult).ToList(); nanTradeValue.ForEach(optionValue => { logger.Error($"交易ID:{trade.UnderlyingId},Delta:{optionValue.Delta},DeltaCash{optionValue.DeltaCash},Vega{optionValue.Vega},Gamma:{optionValue.Gamma},vol:{optionValue.Vol}"); }); } } } return tradeSpans; } public override double GetTradeMargin(GetTradeMarginReq req) { var trade = req.trade; using (var db = new YLContext()) { if (trade.TradeType == "结构化交易") { trade.SubTrades = db.trade.Where(x => x.ParentTradeId == trade.id).ToList(); } } var tradeMargin = RunMarginCalculation(req.GetRunMarginCalculationReq()); if (null != tradeMargin) { return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0; } return 0.0; } } }