From 6ff068d70b1413f8ee684776a580d1f6bc4ca660 Mon Sep 17 00:00:00 2001 From: hjhan Date: Sat, 22 Aug 2026 07:44:23 +0800 Subject: [PATCH] =?UTF-8?q?chore(swap):=20=E5=88=A0=E9=99=A4=E6=A0=BC?= =?UTF-8?q?=E6=9E=97=E5=A4=A7=E5=8D=8E=E4=BF=9D=E8=AF=81=E9=87=91#if=20DEB?= =?UTF-8?q?UG=E6=98=8E=E6=98=BEbug=E5=88=86=E6=94=AF=E2=80=94=E2=80=94Rele?= =?UTF-8?q?ase=E4=B8=8Bcase=E7=A9=BA=E4=BD=93=E8=AF=AF=E8=90=BD=E5=9B=BD?= =?UTF-8?q?=E6=B3=B0=E5=90=9B=E5=AE=89=E5=85=AC=E5=BC=8F=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本部署CompanyEnum=国联(走default→DefaultMarginCalculation),且保证金正在其他分支重写,各家期货公司定制对本分支无意义;格林大华case体整体包在#if DEBUG里,Release编译时空case直接fall-through到国泰君安/光大光子/兴业商贸组——若格林大华环境用Release版,保证金一直在用别家公式。连同DAL的GLDHMarginCalculation.cs与UT下整文件注释的死备份一并删除。dotnet build 0错误 --- .../GLDHMarginCalculation.cs | 513 ------------------ .../MarginCalculation/MarginCalculation.cs | 5 - .../GLDHMarginCalculation.cs | 217 -------- 3 files changed, 735 deletions(-) delete mode 100644 YLErpDAL/BLL/MarginCalculation/GLDHMarginCalculation.cs delete mode 100644 YLErpUnitTest/Modules/MarginModule/MarginCalculation/GLDHMarginCalculation.cs diff --git a/YLErpDAL/BLL/MarginCalculation/GLDHMarginCalculation.cs b/YLErpDAL/BLL/MarginCalculation/GLDHMarginCalculation.cs deleted file mode 100644 index 91e946e7..00000000 --- a/YLErpDAL/BLL/MarginCalculation/GLDHMarginCalculation.cs +++ /dev/null @@ -1,513 +0,0 @@ -using YLErp.BLL.Calculation; -using YLErp.Enums; -using YLErp.Helpers; -using YLErp.Modules; -using YLErp.Modules.DataProviderModule; -using YLErp.Modules.MarginModule; -using YLErp.QdpModule; - -namespace YLErp.BLL.MarginCalculation -{ - /// - /// 格林大华 - /// - public class GLDHMarginCalculation : MarginCalculationBase - { - // 定义一个静态变量来保存类的实例 - public static readonly GLDHMarginCalculation Instance; - - static GLDHMarginCalculation() - { - Instance = new GLDHMarginCalculation(); - } - - // 定义私有构造函数,使外界不能创建该类实例 - private GLDHMarginCalculation() - { - } - - public override List RunMarginCalculation(RunMarginCalculationReq req) - { - var resultList = new List(); - - if (req.CalcMarginType == Enums.CalcMarginTypeEnum.InitialMargin) - { - resultList = calcInitialMargin(req); - } - else - { - resultList = calcPositionMargin(req); - } - - - return resultList; - } - /// - /// 初始预付金 - /// - /// - /// - private List calcInitialMargin(RunMarginCalculationReq req) - { - Dictionary resultMap = new Dictionary(); - var _helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); - var marginProvider = _helper.GetMarginParamProvider(Modules.MarginModule.MarginParamTypeEnum.MarginRate); - - var tradeTypes = new List() { "远期", "收益互换" }; - var forword = req.tradeList.Where(O => O.TradeType == "远期"); - foreach (var item in forword) - { - var margin = - item.Notional * (item.SpotPrice ?? 0) - * (marginProvider.TryGetMarginRate(item.UnderlyingCode, out var m) ? m : 0); - var sp = _helper.CreateTradeSpan(item).SetAllSpvAndWorst(margin); - LogFactory.GetLogger().Debug($"{margin}={item.Notional}*{item.SpotPrice}* {(marginProvider.TryGetMarginRate(item.UnderlyingCode, out var ms) ? ms : 0)})"); - - sp.SetWorstCastClientPayable(); - - resultMap[sp.TradeId] = sp; - } - - var swap = req.tradeList.Where(O => O.TradeType == "收益互换"); - tradeBLL.SetFieldsByTradeType(swap); - foreach (var item in swap) - { - var rate = (item.trade_swap?.GetMarginRate ?? 0) - (item.trade_swap?.PayMarginRate ?? 0); - var margin = 0d; - if (rate > 0) - { - margin = - item.StockEqvNotional - * rate; - var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId); - var clientLevel = DataCacheProvider.GetClientLevelDataSource().GetData(client.LevelId ?? 0); - var clientRatio = clientLevel?.Ratio ?? 1.0; - margin *= clientRatio; - } - var sp = _helper.CreateTradeSpan(item).SetAllSpvAndWorst(margin); - sp.SetWorstCastClientPayable(); - - resultMap[sp.TradeId] = sp; - } - - - //所有客户买入的交易都不收取预付金,包含买入单腿,跨式期权,风险反转期权以及其他多腿组合期权(买入牛市价差或熊市价差时,卖出的那条腿也不收取预付金) - var sellList = req.tradeList.Where(O => !tradeTypes.Contains(O.TradeType) && O.BuySell == "卖出"); - foreach (var item in sellList) - { - var sp = _helper.CreateTradeSpan(item).SetAllSpvAndWorst(0); - sp.SetWorstCastClientPayable(); - resultMap[sp.TradeId] = sp; - } - - var buyList = req.tradeList.Where(O => !tradeTypes.Contains(O.TradeType) && !resultMap.Keys.Contains(O.id)); - var calcReq = - _helper.GetCalculateRisksForTradesReq( - req.PriceProvider, - null, - null, - Qdp.Pricing.Base.Implementations.PricingRequest.Delta); - calcReq.tradeList = buyList; - var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(calcReq); - - //客户卖出跨式期权 - //初始预付金 = max(D1,D2)×S×交易所期货预付金率×数量; - //其中 D1,D2 分别为跨式期权两腿的 Delta 绝对值。 - var tradeIds = buyList.Where(O => (O.StructureType ?? O.TradeType).Contains("跨式") && O.BuySell == "买入").Select(O => O.id); - var resultDict = tradeRiskResult.Results.Where(O => tradeIds.Contains(O.Trade.id)).GroupBy(O => O.Trade.ParentTradeId).ToDictionary(K => K.Key, V => V.ToList()); - foreach (var item in resultDict) - { - var margin = - item.Value - .Max(O => Math.Abs(O.ValueResult.DeltaCash) - * (marginProvider.TryGetMarginRate(O.Trade.UnderlyingCode, out var m) ? m : 0)); - var sp = _helper.CreateTradeSpan(item.Value[0].Trade).SetAllSpvAndWorst(margin); - sp.SetWorstCastClientPayable(); - resultMap[item.Value[0].Trade.id] = sp; - for (int i = 1; i < item.Value.Count; i++) - { - sp = _helper.CreateTradeSpan(item.Value[i].Trade).SetAllSpvAndWorst(0); - sp.SetWorstCastClientPayable(); - resultMap[item.Value[i].Trade.id] = sp; - } - } - - //客户卖出单腿期权 - //初始预付金 = D×S×交易所期货预付金率×数量; - tradeIds = buyList.Where(O => !((O.StructureType ?? O.TradeType).Contains("跨式")) && O.BuySell == "买入").Select(O => O.id); - var resultList = tradeRiskResult.Results.Where(O => tradeIds.Contains(O.Trade.id)); - resultList.ToList().ForEach(O => - { - var margin = Math.Abs(O.ValueResult.DeltaCash * (marginProvider.TryGetMarginRate(O.Trade.UnderlyingCode, out var m) ? m : 0)); - LogFactory.GetLogger().Info("初始预付金 = D×S×交易所期货预付金率×数量;"); - LogFactory.GetLogger().Info($"{margin}=Math.Abs({O.ValueResult.DeltaCash} * {(marginProvider.TryGetMarginRate(O.Trade.UnderlyingCode, out var ms) ? ms : 0)})"); - var sp = _helper.CreateTradeSpan(O.Trade).SetAllSpvAndWorst(margin); - sp.SetWorstCastClientPayable(); - resultMap[sp.TradeId] = sp; - }); - - return resultMap.Values.ToList(); - } - /// - /// 计算每笔预付金 - /// - /// - /// - private List calcPositionMargin(RunMarginCalculationReq req) - { - var resultMap = new Dictionary(); - var tradeTypes = new List() { "远期", "收益互换" }; - //结算s - req.PriceProvider = new EodPriceProvider(req.settleDate).GetPriceProvider(SettlementTypeEnum.SettlePrice); - //收盘 - var closePriceProvider = new EodPriceProvider(req.settleDate).GetPriceProvider(SettlementTypeEnum.ClosePrice); - var _helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); - var marginProvider = _helper.GetMarginParamProvider(Modules.MarginModule.MarginParamTypeEnum.MarginRate); - //获取涨跌停价格字典 - _helper.GetUpDownLimitPrices(out var upPrices, out var downPrices); - //获取持仓波动率字典 - _helper.GetUpDownVolRateDic(out var upVolRateDic, out _); - - var clientGroup = req.tradeList.GroupBy(O => new { O.ClientId, O.UnderlyingCode }).ToDictionary(K => K.Key, V => V.ToList()); - foreach (var item in clientGroup) - { - var forword = req.tradeList.Where(O => O.TradeType == "远期"); - foreach (var t in forword) - { - var margin = - t.Notional * (t.SpotPrice ?? 0) - * (marginProvider.TryGetMarginRate(t.UnderlyingCode, out var m) ? m : 0); - LogFactory.GetLogger().Info($"该交易{t.TradeNumber}id{t.id};远期" + - $"{margin} ={t.Notional * (t.SpotPrice ?? 0) * (marginProvider.TryGetMarginRate(t.UnderlyingCode, out var s) ? s : 0)}"); - - var sp = _helper.CreateTradeSpan(t).SetAllSpvAndWorst(margin); - sp.SetWorstCastClientPayable(); - resultMap[sp.TradeId] = sp; - } - var swap = req.tradeList.Where(O => O.TradeType == "收益互换"); - tradeBLL.SetFieldsByTradeType(swap); - foreach (var t in swap) - { - var rate = (t.trade_swap?.GetMarginRate ?? 0) - (t.trade_swap?.PayMarginRate ?? 0); - var margin = 0d; - if (rate > 0) - { - margin = - t.StockEqvNotional - * (marginProvider.TryGetMarginRate(t.UnderlyingCode, out var m) ? m : 0); - LogFactory.GetLogger().Info($"该交易{t.TradeNumber}id{t.id}收益互换{margin}"); - - - var client = DataCacheProvider.GetClientDataSource().GetData(t.ClientId); - var clientLevel = DataCacheProvider.GetClientLevelDataSource().GetData(client.LevelId ?? 0); - var clientRatio = clientLevel?.Ratio ?? 1.0; - margin *= clientRatio; - LogFactory.GetLogger().Info($"该交易 margin *= clientRatio {t.TradeNumber} id{t.id}收益互换{margin}"); - } - var sp = _helper.CreateTradeSpan(t).SetAllSpvAndWorst(margin); - sp.SetWorstCastClientPayable(); - resultMap[sp.TradeId] = sp; - } - /*计算总维持预付金时,先分标的计算,再进行汇总计算。 - * 如果客户在标的 i 上只有买权合约,则该标的不计入预付金计算范围; - * 如果客户在在标的 i 上有卖权合约,则该标的的所有合约都纳入预付金计算范围。 - */ - var option = item.Value.Where(O => !tradeTypes.Contains(O.TradeType)); - if (option.All(O => O.BuySell == "卖出")) - { - foreach (var t in option) - { - var sp = _helper.CreateTradeSpan(t).SetAllSpvAndWorst(0); - sp.SetWorstCastClientPayable(); - resultMap[sp.TradeId] = sp; - } - } - else - { - var prices = new Dictionary>(); - var umCodeList = option.Select(O => O.UnderlyingCode).ToHashSet(); - foreach (var code in umCodeList) - { - prices[1] = new Dictionary(); - prices[2] = new Dictionary(); - prices[3] = new Dictionary(); - prices[4] = new Dictionary(); - prices[5] = new Dictionary(); - prices[6] = new Dictionary(); - prices[7] = new Dictionary(); - prices[8] = new Dictionary(); - var upPrice = upPrices.GetPrice(code); - var downPrice = downPrices.GetPrice(code); - LogFactory.GetLogger().Info($"涨跌价格:{upPrice} {downPrice}"); - var interval = (upPrice - downPrice) / 6; - - var settlePrice = req.PriceProvider.GetPrice(code); - LogFactory.GetLogger().Info($"settlePrice:{settlePrice} interval:=(upPrice - downPrice) / 6={interval}={(upPrice - downPrice)} / {6}"); - prices[1][code] = settlePrice - 3 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金1:prices[1][{code}] = settlePrice - 3 * interval;{prices[1][code]}={settlePrice}- 3 * {interval}"); - prices[2][code] = settlePrice - 2 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金2:prices[2][{code}] = settlePrice - 2 * interval:{prices[2][code]}={settlePrice}- 2 * {interval}"); - prices[3][code] = settlePrice - 1 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金3:prices[3][{code}] = settlePrice - 1 * interval:{prices[3][code]}={settlePrice}- 1 * {interval}"); - prices[4][code] = settlePrice; - LogFactory.GetLogger().Info($"格林持仓预付金4:prices[4][{code}] = settlePrice:{prices[4][code] = settlePrice}"); - prices[5][code] = settlePrice + 1 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金5:prices[5][{code}] = settlePrice - 1 * interval:{prices[5][code]}={settlePrice}+ 1 * {interval}"); - prices[6][code] = settlePrice + 2 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金6:prices[6][{code}] = settlePrice - 2 * interval:{prices[6][code]}={settlePrice}+ 2 * {interval}"); - prices[7][code] = settlePrice + 3 * interval; - LogFactory.GetLogger().Info($"格林持仓预付金7:prices[7][{code}] = settlePrice - 3 * interval:{prices[7][code]} ={settlePrice}+3 * {interval}"); - prices[8][code] = closePriceProvider.GetPrice(code); - LogFactory.GetLogger().Info($"格林持仓预付金8收盘价算Detal:{prices[8][code] = closePriceProvider.GetPrice(code)}"); - } - foreach (var p in prices) - { - var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades( - valueDate: req.settleDate, - calcScenario: req.GetCalcScenario(), - tradeList: item.Value, - priceProvider: new ManualPriceProvider(p.Value), - pricingRequest: QdpPricingRequest.BASIC_PRICING, - addVolRateDic: p.Key < 8 ? upVolRateDic : null, //1~7为PM,波动率应当上浮,第8个为DM,波动率不用变化 - volType: req.volType, - isUseTradeVol: PS.Config.IsTradeVol, - preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin, - isAddVolPercent: true); - foreach (var risk in tradeRiskResult.Results) - { - var code = risk.Trade.UnderlyingCode; - var pric = p.Value[risk.Trade.UnderlyingCode]; - LogFactory.GetLogger().Info($"格林持仓预付金该交易编号:{risk.Trade.TradeNumber} id:{risk.Trade.id}标的:{code} 交易价格为:{pric}"); - if (!resultMap.TryGetValue(risk.Trade.id, out var tradeSpan)) - { - resultMap[risk.Trade.id] = tradeSpan = _helper.CreateTradeSpan(risk.Trade); - } - - switch (p.Key) - { - case 1: - tradeSpan.Spv1 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV1为:{tradeSpan.Spv1}"); - break; - case 2: - tradeSpan.Spv2 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV2为:{tradeSpan.Spv2}"); - break; - case 3: - tradeSpan.Spv3 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV3为:{tradeSpan.Spv3}"); - break; - case 4: - tradeSpan.Spv4 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV4为:{tradeSpan.Spv4}"); - break; - case 5: - tradeSpan.Spv5 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV5为:{tradeSpan.Spv5}"); - break; - case 6: - tradeSpan.Spv6 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV6为:{tradeSpan.Spv6}"); - break; - case 7: - tradeSpan.Spv7 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV7为:{tradeSpan.Spv7}"); - break; - case 8: - tradeSpan.Spv8 = risk.ValueResult.Pv; - LogFactory.GetLogger().Info($"格林持仓预付金该交易的PV8为:{tradeSpan.Spv8}"); - tradeSpan.DeltaMargin = risk.ValueResult.DeltaCash; - break; - default: - break; - } - //第八个pv不参与pm计算 - if (p.Key < 8) - { - tradeSpan.SetWorstCastClientPayable(); - } - } - } - } - } - return resultMap.Values.ToList(); - } - - /// - /// 计算每个客户预付金 - /// - /// - /// - public override List CalcClientMargin(CalcClientMarginReq req) - { - var clientSpanNews = new List(); - var _mpProvider = new MarginParamProvider(req.UserInfo, req.settleDate); - - using (var db = new YLContext()) - { - if (req.tradeSpans != null && req.tradeSpans.Count > 0) - { - var tradeIds = req.tradeSpans.Select(t => t.TradeId).ToList(); - var tradeList = db.trade.AsNoTracking().Where(t => tradeIds.Contains(t.id)).ToList(); - var tradeSpanInfo = (from tradeSpan in req.tradeSpans - join trade in tradeList on tradeSpan.TradeId equals trade.id - where tradeSpan.ValueDate == req.settleDate - select new { trade, tradeSpan }).ToList(); - - var umCode = tradeList.Select(O => O.UnderlyingCode).ToHashSet(); - var marginProvider = _mpProvider.Initialize(umCode, MarginParamTypeEnum.MarginRate); - - var clientGroups = tradeSpanInfo.GroupBy(t => t.trade.ClientId); - foreach (var item in clientGroups) - { - var tradeTypes = new List() { "远期", "收益互换" }; - var forword = item.Where(O => O.trade.TradeType == "远期"); - var swap = item.Where(O => O.trade.TradeType == "收益互换"); - - var worstCastClientPayable_forward = -forword.Sum(O => O.tradeSpan.WorstCastClientPayable ?? 0); - LogFactory.GetLogger().Info($"格林维持预付金远期为:{worstCastClientPayable_forward}"); - var worstCastClientPayable_swap = -swap.Sum(O => O.tradeSpan.WorstCastClientPayable ?? 0); - LogFactory.GetLogger().Info($"格林维持预付金收益互换为:{worstCastClientPayable_swap}"); - var worstCastClientPayable_option = 0d; - - var option = item.Where(O => !tradeTypes.Contains(O.trade.TradeType)); - if (option.Any(O => O.trade.BuySell == "买入")) - { - var dm = option.Sum(O => - { - var margin = (marginProvider.TryGetMarginRate(O.trade.UnderlyingCode, out var m) ? m : 0); - var a = Math.Abs((O.tradeSpan.DeltaMargin ?? 0) * margin) - O.tradeSpan.Spv8 ?? 0; - LogFactory.GetLogger().Info($"格林维持保证的dm为:{a}"); - return Math.Abs((O.tradeSpan.DeltaMargin ?? 0) * margin) - O.tradeSpan.Spv8 ?? 0; - }); - - dm = Math.Max(dm, 0); - LogFactory.GetLogger().Info($"格林维持保证最大的dm:{dm}"); - //计算标的 i 在上 7 种情形下客户持仓的持仓价值 MVi,k(k=1,2,3…7)(客户卖出期权,期权价值取负值), - //则客户在标的 i 上隔日最大亏损 Li = -min(Vi,k),对第 i 个标的取维持预付金 PMi = Max(Li,0); - //var pm = option.GroupBy(O => O.trade.UnderlyingCode).Sum(O => Math.Max(O.Sum(B => B.tradeSpan.WorstCastClientPayable ?? 0), 0)); - var underlyingGroup = option.GroupBy(O => O.trade.UnderlyingCode); - var pmList = new List(); - foreach (var unItem in underlyingGroup) - { - var list = new List() - { - unItem.Sum(O => O.tradeSpan.Spv1??0), - unItem.Sum(O => O.tradeSpan.Spv2??0), - unItem.Sum(O => O.tradeSpan.Spv3??0), - unItem.Sum(O => O.tradeSpan.Spv4??0), - unItem.Sum(O => O.tradeSpan.Spv5??0), - unItem.Sum(O => O.tradeSpan.Spv6??0), - unItem.Sum(O => O.tradeSpan.Spv7??0), - }; LogFactory.GetLogger().Info($"格林维持预付金 7 种情形下客户持仓值为1:" + - $"{unItem.Sum(O => O.tradeSpan.Spv1 ?? 0)}" + - " 2:" + $"{unItem.Sum(O => O.tradeSpan.Spv2 ?? 0)}" + - " 3:" + $"{unItem.Sum(O => O.tradeSpan.Spv3 ?? 0)}" + - " 4:" + $"{unItem.Sum(O => O.tradeSpan.Spv4 ?? 0)}" + - " 5:" + $"{unItem.Sum(O => O.tradeSpan.Spv5 ?? 0)}" + - " 6:" + $"{unItem.Sum(O => O.tradeSpan.Spv6 ?? 0)}" + - " 7:" + $"{unItem.Sum(O => O.tradeSpan.Spv7 ?? 0)} 代码角度若为卖出期权则为负数(-min)所以最小的加-则为正数"); - var pmi = list.Max(O => O); - LogFactory.GetLogger().Info($"格林维持预付金PM为Max(Li,0){pmi}"); - pmList.Add(pmi); - } - - var pm = pmList.Sum(); - - worstCastClientPayable_option = Math.Max(dm, pm); - - LogFactory.GetLogger().Info($"格林维持保证标的i维持预付金M=Max(dm,pm){worstCastClientPayable_option}={Math.Max(dm, pm)}"); - LogFactory.GetLogger().Info($"格林维持保证标的i维持预付金M=Max(dm,pm){worstCastClientPayable_option}"); - #region 更新tradeSpan,使得每笔交易的持仓预付金和客户预付金计算用的Spv组保持一致 - - var sumDelta = option.Sum(O => Math.Abs(O.tradeSpan.DeltaMargin ?? 0)); - tradeIds = option.Select(x => x.trade.id).ToList(); - var tradeSpansUpdate = db.trade_span.Where(x => tradeIds.Contains(x.TradeId) && x.ClientId == item.Key && x.ValueDate == req.settleDate).ToList(); - var tradeSpansReq = req.tradeSpans.Where(x => tradeIds.Contains(x.TradeId) && x.ClientId == item.Key && x.ValueDate == req.settleDate).ToList(); - - tradeSpansUpdate.ForEach(x => x.WorstCastClientPayable = worstCastClientPayable_option * Math.Abs(x.DeltaMargin ?? 0) / sumDelta); - tradeSpansReq.ForEach(x => x.WorstCastClientPayable = worstCastClientPayable_option * Math.Abs(x.DeltaMargin ?? 0) / sumDelta); - - #endregion - } - var worstCastClientPayable = -worstCastClientPayable_option + worstCastClientPayable_forward + worstCastClientPayable_swap; - LogFactory.GetLogger().Info($"{worstCastClientPayable = -worstCastClientPayable_option + worstCastClientPayable_forward + worstCastClientPayable_swap}"); - var clientSpan = new ClientSpan - { - ClientId = item.Key, - ValueDate = req.settleDate, - Spv1 = worstCastClientPayable, - Spv2 = worstCastClientPayable, - Spv3 = worstCastClientPayable, - Spv4 = worstCastClientPayable, - //负数代表客户应缴预付金,正数代表客户应收预付金 - WorstCastClientPayable = worstCastClientPayable, - SwapWorstCastClientPayable = worstCastClientPayable_swap, - MySideMargin = worstCastClientPayable, - OptId = req.userId, - OptName = req.userName, - OptDate = DateTime.Now, - SpanType = req.SpanType, - AdditionalWorstCastClientPayable = req.clientAdditionalMarginDic != null - && req.clientAdditionalMarginDic.TryGetValue(item.Key, out var dd) ? dd : 0 - }; - clientSpanNews.Add(clientSpan); - } - } - //span类型为实时删除所有实时计算的交易的预付金信息 - if (req.SpanType == ClientSpan.SpanType_RealTime) - { - if (req.RefreshClientIds != null) - { - db.BulkDelete($"{nameof(ClientSpan.ClientId)} in @ids", new { ids = req.RefreshClientIds }); - } - else - { - db.BulkDelete($"{nameof(ClientSpan.SpanType)}={req.SpanType}"); - } - } - else - { - if (req.ClientIds != null) - { - var sql = $"{nameof(ClientSpan.ClientId)} in @ids and {nameof(ClientSpan.ValueDate)}='{req.settleDate.ToSqlDate()}' and {nameof(ClientSpan.SpanType)}={req.SpanType} and {nameof(ClientSpan.ModifiedFlag)}=0"; - db.BulkDelete(sql, new { ids = req.ClientIds }); - } - else - { - var sql = $"{nameof(ClientSpan.ValueDate)}='{req.settleDate.ToSqlDate()}' and {nameof(ClientSpan.SpanType)}={req.SpanType} and {nameof(ClientSpan.ModifiedFlag)}=0"; - db.BulkDelete(sql); - } - var clientSpanOldsWithFlag = db.client_span.Where(t => t.ValueDate == req.settleDate && t.SpanType == req.SpanType && t.ModifiedFlag) - .Select(n => new { n.ValueDate, n.ClientId }).ToList(); - //筛选出可以修改的clientSpan - clientSpanNews = clientSpanNews.Where(c => !clientSpanOldsWithFlag.Any(t => t.ValueDate == c.ValueDate && t.ClientId == c.ClientId)).ToList(); - } - if (clientSpanNews.Count > 0) - { - //MySqlBulkExtensions.BulkInsert(db, clientSpanNews); - db.client_span.AddRange(clientSpanNews); - } - db.SaveChanges(); - } - return req.tradeSpans; - } - public override double GetTradeMargin(GetTradeMarginReq req) - { - var trade = req.trade; - using (YLContext 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; - } - } -} diff --git a/YLErpDAL/BLL/MarginCalculation/MarginCalculation.cs b/YLErpDAL/BLL/MarginCalculation/MarginCalculation.cs index e19170cb..0ec23c19 100644 --- a/YLErpDAL/BLL/MarginCalculation/MarginCalculation.cs +++ b/YLErpDAL/BLL/MarginCalculation/MarginCalculation.cs @@ -131,11 +131,6 @@ namespace YLErp.BLL.MarginCalculation case CompanyEnum.东吴: result.AddRange(DongWuMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; - case CompanyEnum.格林大华: -#if DEBUG - result.AddRange(GLDHMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); - break; -#endif case CompanyEnum.国泰君安: case CompanyEnum.光大光子: case CompanyEnum.兴业商贸: diff --git a/YLErpUnitTest/Modules/MarginModule/MarginCalculation/GLDHMarginCalculation.cs b/YLErpUnitTest/Modules/MarginModule/MarginCalculation/GLDHMarginCalculation.cs deleted file mode 100644 index 1a2f0b71..00000000 --- a/YLErpUnitTest/Modules/MarginModule/MarginCalculation/GLDHMarginCalculation.cs +++ /dev/null @@ -1,217 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.Linq; -//using YLErp.DBModels; -//using YLErp.Model; - -//namespace YLErp.BLL.MarginCalculationBak -//{ -// /// -// /// 格林大华 -// /// -// public class GLDHMarginCalculation : MarginCalculationBase -// { -// // 定义一个静态变量来保存类的实例 -// public static readonly GLDHMarginCalculation Instance; - -// static GLDHMarginCalculation() -// { -// Instance = new GLDHMarginCalculation(); -// } - -// // 定义私有构造函数,使外界不能创建该类实例 -// private GLDHMarginCalculation() -// { -// } - -// public override List RunMarginCalculation(int userId, string userName, List tradeList, DateTime settleDate, Dictionary priceDict, bool hasOptionInfo = false, bool isEodSettle = false, bool forSingleTrade = true, string volType = "交易", bool forOtherSide = false) -// { -// List tradeSpans = new List(); -// //实际计算的时候没有使用到收盘价格,所以先把取价格的逻辑注释掉; -// //if (!(priceDict?.Count > 0)) -// //{ -// // var codes = tradeList.Select(O => O.UnderlyingCode).ToArray(); -// // priceDict = base.GetSettlePrice(codes, settleDate); -// //} -// //if (priceDict.Count == 0) -// //{ -// // //如果价格没有传入也没从数据库获取到,就直接返回,没必要往下运行了。但不应该报错; -// // return tradeSpans; -// //} -// if (tradeList != null && tradeList.Count > 0) -// { -// var tempStockTradeList = tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.Stock).ToList(); -// if (tempStockTradeList.Any()) -// { -// var stockTradeSpanlist = StockMarginCalculation(userId, userName, tempStockTradeList, settleDate, priceDict, hasOptionInfo, isEodSettle); -// if (stockTradeSpanlist.Count > 0) -// { -// tradeSpans.AddRange(stockTradeSpanlist); -// } -// } -// var tempFutureTradeList = tradeList.Where(t => t.UnderlyingInstrumentType == ConsGlobal.InstrumentType.CommodityFutures).ToList(); -// if (tempFutureTradeList.Any()) -// { -// var futureTradeSpanlist = FutureMarginCalculation(userId, userName, tempFutureTradeList, settleDate, priceDict, hasOptionInfo, isEodSettle); -// if (futureTradeSpanlist.Count > 0) -// { -// tradeSpans.AddRange(futureTradeSpanlist); -// } -// } -// } -// return tradeSpans; -// } - -// /// -// /// 股票类期权计算保证金 -// /// -// /// -// /// -// /// -// /// -// /// -// /// -// public List StockMarginCalculation(int userId, string userName, List tradeList, DateTime settleDate, Dictionary priceDict, bool hasOptionInfo = false, bool isEodSettle = false) -// { -// List tradeSpans = new List(); -// if (tradeList != null && tradeList.Count > 0) -// { -// using (YLContext db = new YLContext()) -// { -// var marginRation = valuedateBLL.SystemDate.MarginRatio ?? 0.15; -// var clientIds = tradeList.Select(t => t.ClientId).ToList(); -// var clientList = (from client in db.client -// join clientlevel in db.clientlevel -// on client.LevelId equals clientlevel.id into tempClientlevel -// from clientlevelTT in tempClientlevel.DefaultIfEmpty() -// where clientIds.Contains(client.id) -// select new -// { -// client, -// clientlevel = clientlevelTT -// }).ToList(); - -// if (clientList != null) -// { - -// tradeList.ForEach(t => -// { -// var client = clientList.FirstOrDefault(c => c.client.id == t.ClientId); -// if (client != null) -// { -// //未设置相关保证金系数默认为1.0 -// var clientRatio = client.clientlevel == null ? 1.0 : (client.clientlevel.Ratio ?? 1.0); -// //如果是股票去名义本金,如果是期货取:份额 * 即期价格 -// var value = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.client.HasTwoSideMargin == 1 ? -1 : 0)) * clientRatio; -// var twoSideMargin = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : -1) * clientRatio; -// tradeSpans.Add(new trade_span -// { -// TradeId = t.id, -// OptDate = DateTime.Now, -// OptId = userId, -// OptName = userName, -// ClientId = client.client.id, -// UnderlyingId = t.UnderlyingId, -// UnderlyingCode = t.UnderlyingCode, -// ValueDate = settleDate, -// Spv1 = value, -// Spv2 = value, -// Spv3 = value, -// Spv4 = value, -// WorstCastClientPayable = value, -// TwoSideMargin = twoSideMargin -// }); -// } -// }); -// } -// } -// } -// return tradeSpans; -// } - -// /// -// /// 商品期权计算保证金 -// /// -// /// -// /// -// /// -// /// -// /// -// /// -// public List FutureMarginCalculation(int userId, string userName, List futureTradeList, DateTime settleDate, Dictionary priceDict, bool hasOptionInfo = false, bool isEodSettle = false) -// { -// List tradeSpans = new List(); -// if (futureTradeList != null && futureTradeList.Count > 0) -// { -// using (YLContext db = new YLContext()) -// { -// var marginRation = valuedateBLL.SystemDate.FutureMarginRatio ?? 0.15; -// var clientIds = futureTradeList.Select(t => t.ClientId).ToList(); -// var clientList = (from client in db.client -// join clientlevel in db.clientlevel -// on client.LevelId equals clientlevel.id into tempClientlevel -// from clientlevelTT in tempClientlevel.DefaultIfEmpty() -// where clientIds.Contains(client.id) -// select new -// { -// client, -// clientlevel = clientlevelTT -// }).ToList(); - -// if (clientList != null) -// { - -// futureTradeList.ForEach(t => -// { -// var client = clientList.FirstOrDefault(c => c.client.id == t.ClientId); -// if (client != null) -// { -// //未设置相关保证金系数默认为1.0 -// var clientRatio = client.clientlevel == null ? 1.0 : (client.clientlevel.Ratio ?? 1.0); -// //如果是股票去名义本金,如果是期货取:份额 * 即期价格 -// var value = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.client.HasTwoSideMargin == 1 ? -1 : 0)) * clientRatio; -// var twoSideMargin = (t.StockEqvNotional ?? (t.Notional * t.SpotPrice ?? 0.0)) * marginRation * (t.BuySell == "买入" ? 1 : -1) * clientRatio; -// tradeSpans.Add(new trade_span -// { -// TradeId = t.id, -// OptDate = DateTime.Now, -// OptId = userId, -// OptName = userName, -// ClientId = client.client.id, -// UnderlyingId = t.UnderlyingId, -// UnderlyingCode = t.UnderlyingCode, -// ValueDate = settleDate, -// Spv1 = value, -// Spv2 = value, -// Spv3 = value, -// Spv4 = value, -// WorstCastClientPayable = value, -// TwoSideMargin = twoSideMargin -// }); -// } -// }); -// } -// } -// } -// return tradeSpans; -// } - -// public override double GetTradeMargin(trade trade, double price, bool isInitialMargin = false, bool hasOptionInfo = false) -// { -// using (YLContext db = new YLContext()) -// { -// if (trade.TradeType == "结构化交易") -// { -// trade.SubTrades = db.trade.Where(x => x.ParentTradeId == trade.id).ToList(); -// } -// } - -// var tradeMargin = RunMarginCalculation(0, "系统", new List { trade }, isInitialMargin ? (trade.TradeDate ?? valuedateBLL.ValueDate) : valuedateBLL.ValueDate, new Dictionary { { trade.UnderlyingId, price } }, hasOptionInfo: hasOptionInfo); -// if (null != tradeMargin) -// { -// return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0; -// } -// return 0.0; -// } -// } -//}