using YLErp.BLL.Calculation; using YLErp.Configuration; using YLErp.DBModels.Enums; using YLErp.DBModels.Helpers; using YLErp.Enums; using YLErp.Model; using YLErp.Modules; using YLErp.Modules.CalculationModule; using YLErp.Modules.TradeModule; using YLErp.QdpModule; namespace YLErp.BLL.MarginCalculation { /// /// /// public static class MarginDefault { /// /// 计算日终预付金 /// public static List RunMarginCalculation(RunMarginCalculationReq req) { var result = new List(); var eodTradeids = new YLContext().eod_trade_risk_manual.Where(x => x.ValueDate == req.settleDate && x.Margin != null && string.IsNullOrEmpty(x.VolType)).Select(x => x.TradeId); var tempTradeList = req.tradeList.Where(O => eodTradeids.Contains(O.id)).ToList(); if (tempTradeList.Any() && PS.Config.Company != CompanyEnum.广期资本) { result = EodtraderiskmanualCalculation(req.Clone(tempTradeList)); } tempTradeList = req.tradeList.Where(O => O.TradeType == "现金流交易" && !eodTradeids.Contains(O.id)).ToList(); if (tempTradeList.Any()) { result.AddRange(cashflowMarginCalculation(req.Clone(tempTradeList))); } tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType != MarginTypeEnum.DEFAULT && !eodTradeids.Contains(O.id)).ToList(); if (tempTradeList.Any()) { result.AddRange(SingleMarginCalculation(req.Clone(tempTradeList))); } //if(PS.Config.ErpElement.SecuritiesEnvironment ){ // tempTradeList = req.tradeList.Where(O => O.TradeType == "收益互换" && !eodTradeids.Contains(O.id)).ToList(); // if (tempTradeList.Any()) // { // result.AddRange(SwapTradeMarginCalculation(req.Clone(tempTradeList))); // } //} tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType == MarginTypeEnum.DEFAULT && !eodTradeids.Contains(O.id)).ToList(); if (PS.Config.Company == CompanyEnum.广期资本) { tempTradeList = req.tradeList.Where(O => O.TradeType != "现金流交易" && O.MarginType == MarginTypeEnum.DEFAULT).ToList(); } if (tempTradeList.Any()) { switch (PS.Config.Company) { case CompanyEnum.渤海: case CompanyEnum.安粮: result.AddRange(BHRSMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.申万: result.AddRange(SYWGMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.方顿: result.AddRange(FDMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.茂川资本: result.AddRange(MaoChuanMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.宏源: result.AddRange(HongYuanMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.中财资本: result.AddRange(ZhongCaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.上期资本: result.AddRange(SQMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.伴兴: result.AddRange(BXMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.海通: result.AddRange(HaiTongMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.瑞达: result.AddRange(RDMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.兴证: result.AddRange(XingZhengMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.弘业: result.AddRange(HongYeMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.广期资本: result.AddRange(GQMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.中金: result.AddRange(ZhongJinMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.厦门象屿: result.AddRange(XMXYMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.国海: result.AddRange(GuoHaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.润和: case CompanyEnum.中基石化: result.AddRange(DongZhengRunHeMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.华安: result.AddRange(HuaAnMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.浙期: result.AddRange(ZheQiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.国投: result.AddRange(GuoTouMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.湘财: result.AddRange(XiangCaiMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.中粮: result.AddRange(ZhongLiangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.长江: result.AddRange(ChangJiangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.国信金阳: result.AddRange(GuoXinJinYangMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; 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.兴业商贸: result.AddRange(GTJAMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.广发商贸: result.AddRange(GFSMMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; case CompanyEnum.招证: result.AddRange(ZhaoZhengMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; default: result.AddRange(DefaultMarginCalculation.Instance.RunMarginCalculation(req.Clone(tempTradeList))); break; } } foreach (var ret in result) { var trade = tempTradeList.FirstOrDefault(o => o.id == ret.TradeId); if (trade != null && trade.TradeType == "现金流交易") { ret.WorstCastClientPayable = 0; } } return result; } private static List cashflowMarginCalculation(RunMarginCalculationReq runMarginCalculationReq) { List result = new List(); runMarginCalculationReq.tradeList.ForEach(O => { result.Add(new trade_span() { TradeId = O.id, OptDate = DateTime.Now, OptId = runMarginCalculationReq.userId, OptName = runMarginCalculationReq.userName, ClientId = O.ClientId, UnderlyingId = O.UnderlyingId, UnderlyingCode = O.UnderlyingCode, ValueDate = runMarginCalculationReq.settleDate, Spv1 = 0, Spv2 = 0, Spv3 = 0, Spv4 = 0, Spv5 = 0, Spv6 = 0, Spv7 = 0, Spv8 = 0, Spv = 0, WorstCastClientPayable = 0, TwoSideMargin = 0 }); }); return result; } /// /// 收益互换预付金计算 /// /// /// private static List SwapTradeMarginCalculation(RunMarginCalculationReq req) { var result = new List(); var clientIds = req.tradeList.Where(t => t.ParentTradeId == 0).Select(t => t.ClientId).Distinct().ToList(); //增加clientId=0,默认为全部 clientIds.Add(0); //获取客户互换预付金预警设置 var marginRateList = new YLContext().client_marginrate.Where(t => clientIds.Contains(t.ClientId) && t.ValueDate <= req.settleDate).ToList(); //期权详情 tradeBLL.SetFieldsByTradeType(req.tradeList); foreach (var trade in req.tradeList) { //剔除多空组合子交易 if (trade.ParentTradeId > 0) continue; client_marginrate clientMarginRateSet = null; var extendService = new TradeExtendService(req.UserInfo); extendService.SetTradeExtend(new[] { trade }); //盈亏 var profitAndLoss = 0.0; //计息开始日 var swapStartDate = (trade.StartDate ?? trade.TradeDate).Value.AddDays(trade.trade_swap.IncludeFirstDay ? 1 : 0); //初始预付金比例 var initMarginRate = (trade.trade_swap.GetMarginRate ?? 0) - (trade.trade_swap.PayMarginRate ?? 0); var initMargin = Math.Max(initMarginRate, 0) * trade.StockEqvNotional; //利息收入 收取 - 支付 var interestIncome = PayoffSwapCalcService.GetExtraAmountBySwapRate(trade.ClientId, trade.TradeDate, trade.trade_swap.GetSwapTimeAndRate, swapStartDate, req.settleDate, trade.trade_swap.AnnualDays ?? 0, trade.StockEqvNotional) - PayoffSwapCalcService.GetExtraAmountBySwapRate(trade.ClientId, trade.TradeDate, trade.trade_swap.PaySwapTimeAndRate, swapStartDate, req.settleDate, trade.trade_swap.AnnualDays ?? 0, trade.StockEqvNotional); profitAndLoss += interestIncome; var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode); var costTradePrice = 0.0; //是否开仓是收取手续费 if (!trade.trade_swap.IsTradePriceWhenOpen) { costTradePrice += (trade.trade_swap.GetSingleFee ?? 0) * (trade.trade_swap.GetNotional ?? 0) / underlying.ContractSize; costTradePrice += (trade.trade_swap.GetUnAnnualRate ?? 0) * trade.StockEqvNotional; costTradePrice -= (trade.trade_swap.PaySingleFee ?? 0) * (trade.trade_swap.PayNotional ?? 0) / underlying.ContractSize; costTradePrice -= (trade.trade_swap.PayUnAnnualRate ?? 0) * trade.StockEqvNotional; } profitAndLoss += costTradePrice; //多空组合 if (SwapTypeEnum.多空组合.ToString().Equals(trade.trade_swap.SwapType)) { //标的盈亏 if (trade.get_trade_swap_details != null && trade.get_trade_swap_details.Count > 0) { trade.get_trade_swap_details.ForEach(a => { profitAndLoss += (req.PriceProvider.GetPrice(a.UnderlyingCode) - (a.SpotPrice ?? 0.0)) * (a.Notional ?? 0.0) * ("空头".Equals(a.LongShort) ? -1.0 : 1.0) * (a.IsForGet ? 1 : -1); }); } //预警线 if (marginRateList.Any(a => a.Type.Equals("多空组合") && (a.ClientId == trade.ClientId || a.ClientId == 0))) { clientMarginRateSet = marginRateList.Where(a => a.Type.Equals("多空组合") && (a.ClientId == trade.ClientId || a.ClientId == 0)).OrderByDescending(a => a.ClientId).ThenByDescending(a => a.ValueDate).FirstOrDefault(); } } else {//普通 +收取盈亏 -支付盈亏 profitAndLoss += PayoffSwapCalcService.GetInitialAmountSwapGet(trade, trade.trade_swap, trade.trade_swap.GetSpotPrice ?? 0, req.PriceProvider.GetPrice(trade.trade_swap.GetUnderlyingCode), trade.StockEqvNotional, req.settleDate, null) - PayoffSwapCalcService.GetInitialAmountSwapPay(trade, trade.trade_swap, trade.trade_swap.PaySpotPrice ?? 0, req.PriceProvider.GetPrice(trade.trade_swap.PayUnderlyingCode), trade.StockEqvNotional, req.settleDate, null); if (underlying != null && underlying.Variety != null) { if (marginRateList.Any(a => a.Type.Equals("品种") && (a.ClientId == trade.ClientId || a.ClientId == 0) && a.VarietyId == underlying.Variety.id)) { clientMarginRateSet = marginRateList.Where(a => a.Type.Equals("品种") && (a.ClientId == trade.ClientId || a.ClientId == 0) && a.VarietyId == underlying.Variety.id).OrderByDescending(a => a.ClientId).ThenByDescending(a => a.ValueDate).FirstOrDefault(); } } } //维持预付金 var WorstCastClientPayable = initMargin - profitAndLoss; //持仓预付金 var positionMargin = initMargin; var margin = 0.0; //追保计算 未设置预警线 则取初始预付金比例 if (WorstCastClientPayable <= (clientMarginRateSet == null ? initMarginRate : clientMarginRateSet.WarningLine) * trade.StockEqvNotional) { margin = initMargin - WorstCastClientPayable; //追保暂时只算单方向 positionMargin = initMargin + Math.Max(margin, 0); } result.Add(new trade_span() { TradeId = trade.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = trade.ClientId, UnderlyingId = trade.UnderlyingId, UnderlyingCode = trade.UnderlyingCode, ValueDate = req.settleDate, Spv1 = positionMargin, Spv2 = positionMargin, Spv3 = positionMargin, Spv4 = positionMargin, Spv5 = positionMargin, Spv6 = positionMargin, Spv7 = positionMargin, Spv8 = positionMargin, Spv = positionMargin, WorstCastClientPayable = positionMargin, Margin = margin }); } return result; } private static List SingleMarginCalculation(RunMarginCalculationReq req) { var result = new List(); double value = 0; foreach (var trade in req.tradeList) { bool isSingleMargin = false; switch (trade.MarginType) { case MarginTypeEnum.FIXED: if (req.CalcMarginType == CalcMarginTypeEnum.InitialMargin) { value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate; } else { if (PS.Config.ErpElement.EodFixedMarginUseSpotPrice) { value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.PositionMarginRate; } else { value = (trade.StockEqvNotional == 0 || (trade.SpotPrice ?? 0) == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * req.PriceProvider.GetPrice(trade.UnderlyingCode), trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional * req.PriceProvider.GetPrice(trade.UnderlyingCode) / (trade.SpotPrice ?? 0)) * trade.PositionMarginRate; } } break; case MarginTypeEnum.FLOAT: value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate; if (req.CalcMarginType != CalcMarginTypeEnum.InitialMargin) { if (trade.TradeType == "远期") { var eodpriceProvider = new YLErp.Modules.DataProviderModule.EodPriceProvider(req.settleDate); var spotPrice = eodpriceProvider.GetPrice(trade.UnderlyingCode, SettlementTypeEnum.ClosePrice);//收盘价 TradeValueResult curValue = ForwardradeCalcService.CalcValue(trade, spotPrice); var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0; double pnl = 0; pnl = curValue.Pv + tradePrice * (trade.BuySell == "买入" ? -1 : 1); value += pnl; if (value < 0) { value = 0; } } else { var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades( valueDate: req.settleDate, tradeList: new[] { trade }, calcScenario: req.GetCalcScenario(), priceProvider: req.PriceProvider, pricingRequest: QdpPricingRequest.PV_ONLY, addVolRateDic: null, volType: req.volType, isUseTradeVol: PS.Config.IsTradeVol, preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin); if (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage)) { LogFactory.GetLogger().Error("Pv计算失败:" + tradeRiskResult.ErrorMessage); } var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0; double pnl = 0; if (trade.BuySell == "买入") { pnl = tradePrice - Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv); } else { pnl = Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv) - tradePrice; } value += pnl; if (value < 0) { value = 0; } } } break; case MarginTypeEnum.FLOATP: if (req.CalcMarginType == CalcMarginTypeEnum.InitialMargin) { value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * trade.SpotPrice, trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.MarginRate; } else if (req.CalcMarginType != CalcMarginTypeEnum.InitialMargin) { value = (trade.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(trade.Notional * req.PriceProvider.GetPrice(trade.UnderlyingCode), trade.ParticipationRate, trade.AnnualizeFactor) : trade.StockEqvNotional) * trade.PositionMarginRate; var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades( valueDate: req.settleDate, tradeList: new[] { trade }, calcScenario: req.GetCalcScenario(), priceProvider: req.PriceProvider, pricingRequest: QdpPricingRequest.PV_ONLY, addVolRateDic: null, volType: req.volType, isUseTradeVol: PS.Config.IsTradeVol, preciseTimeMode: req.CalcMarginType != CalcMarginTypeEnum.EodMargin); if (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage)) { LogFactory.GetLogger().Error("Pv计算失败:" + tradeRiskResult.ErrorMessage); } var tradePrice = (trade.TradePrice * trade.Notional / trade.OriginalNotional) ?? 0; double pnl = 0; if (trade.BuySell == "买入") { pnl = tradePrice - Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv); } else { pnl = Math.Abs(tradeRiskResult.Results.First().ValueResult.Pv) - tradePrice; } value += pnl; if (value < 0) { value = 0; } } break; case MarginTypeEnum.XingYe: value = XingYeMarginCalculation.TradeMargin(req, trade); break; case MarginTypeEnum.GuoTouLock: if (trade.TradeType == "雪球期权" || trade.TradeType == "收益互换") { var initialMargin = (trade.InitialMargin ?? 0) * trade.StockEqvNotional / trade.OriginalStockEqvNotional.Value; double[] lockvals = { initialMargin, PS.Config.Company == CompanyEnum.湘财 ? XiangCaiMarginCalculation.TradeMargin(req, trade) : GuoTouMarginCalculation.TradeMargin(req, trade) }; if (PS.Config.Company == CompanyEnum.湘财 && initialMargin < 0) {// #OTC-5636 见备注 value = lockvals.Min(); } else { value = lockvals.Max(); } isSingleMargin = true; } break; case MarginTypeEnum.GuoTouNoLock: if (trade.TradeType == "雪球期权" || trade.TradeType == "收益互换") { double[] noLockvals = { 0, PS.Config.Company == CompanyEnum.湘财 ? XiangCaiMarginCalculation.TradeMargin(req, trade) : GuoTouMarginCalculation.TradeMargin(req, trade) }; value = noLockvals.Max(); isSingleMargin = true; } break; default: case MarginTypeEnum.NONE: value = 0; break; } result.Add(new trade_span() { TradeId = trade.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = trade.ClientId, UnderlyingId = trade.UnderlyingId, UnderlyingCode = trade.UnderlyingCode, ValueDate = req.settleDate, Spv1 = value, Spv2 = value, Spv3 = value, Spv4 = value, Spv5 = value, Spv6 = value, Spv7 = value, Spv8 = value, Spv = value, WorstCastClientPayable = value, TwoSideMargin = value, IsSingleMargin = isSingleMargin }); } return result; } private static List EodtraderiskmanualCalculation(RunMarginCalculationReq req) { var result = new List(); List reqids = req.tradeList.Select(x => x.id).ToList(); var eodTradeRiskManual = new YLContext().eod_trade_risk_manual.Where(x => reqids.Contains(x.TradeId) && x.ValueDate == req.settleDate && x.Margin != null && string.IsNullOrEmpty(x.VolType)); if (eodTradeRiskManual.Any()) { var tradeRiskManuals = (from trade in req.tradeList join riskManuals in eodTradeRiskManual on trade.id equals riskManuals.TradeId select new { trade, riskManuals }).ToList(); foreach (var item in tradeRiskManuals) { double value = item.riskManuals.Margin ?? 0; result.Add(new trade_span() { TradeId = item.trade.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = item.trade.ClientId, UnderlyingId = item.trade.UnderlyingId, UnderlyingCode = item.trade.UnderlyingCode, ValueDate = req.settleDate, Spv1 = value, Spv2 = value, Spv3 = value, Spv4 = value, Spv5 = value, Spv6 = value, Spv7 = value, Spv8 = value, Spv = value, WorstCastClientPayable = value, TwoSideMargin = value, IsSingleMargin = true }); } } return result; } public static List CalcClientMargin(CalcClientMarginReq req) { switch (PS.Config.Company) { case CompanyEnum.渤海: return BHRSMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.安粮: return BHRSMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.申万: return SYWGMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.伴兴: return BXMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.海通: return HaiTongMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.瑞达: return RDMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.兴证: return XingZhengMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.宏源: return HongYuanMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.中财资本: return ZhongCaiMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.上期资本: return SQMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.弘业: return HongYeMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.广期资本: return GQMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.方顿: return FDMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.中金: return ZhongJinMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.国海: return GuoHaiMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.厦门象屿: return XMXYMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.华安: return HuaAnMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.浙期: return ZheQiMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.润和: case CompanyEnum.中基石化: return DongZhengRunHeMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.国投: return GuoTouMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.湘财: return XiangCaiMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.中粮: return ZhongLiangMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.长江: return ChangJiangMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.国信金阳: return GuoXinJinYangMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.东吴: return DongWuMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.格林大华: #if DEBUG return GLDHMarginCalculation.Instance.CalcClientMargin(req); #endif case CompanyEnum.国泰君安: case CompanyEnum.光大光子: return GTJAMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.广发商贸: return GFSMMarginCalculation.Instance.CalcClientMargin(req); case CompanyEnum.招证: return ZhaoZhengMarginCalculation.Instance.CalcClientMargin(req); default: return DefaultMarginCalculation.Instance.CalcClientMargin(req); } } /// /// 这个方法不明白什么意思 /// 按照历史代码,国君应该一直返回的是false,但事实是根据收盘数据看2021年9月24日及以前返回的是true /// public static bool IsMarginCalcNeedSpecial(DateTime valueDate) { //国君商品类预付金需要算反向预付金,权益类不需要 if (PS.Config.IsGuoJun && (!PS.Config.ErpElement.IsStockMargin || PS.Config.ClientElement.TwoSideMargin) && valuedateBLL.TwoSideMarginValueDate.HasValue && valueDate >= valuedateBLL.TwoSideMarginValueDate) { return true; } switch (PS.Config.Company) { case CompanyEnum.渤海: case CompanyEnum.安粮: case CompanyEnum.润和: case CompanyEnum.中基石化: return true; default: return false; } } public static double? GetInitialMarginRatio(trade trade) { switch (PS.Config.Company) { case CompanyEnum.方顿: return FDMarginCalculation.Instance.GetInitialMarginRatio(trade); default: return 0; } } public static double? GetPositionMarginRatio(trade trade) { switch (PS.Config.Company) { case CompanyEnum.方顿: return FDMarginCalculation.Instance.GetPositionMarginRatio(trade); default: return 0; } } public static double GetInitialMarginWithPreHandle(trade trade) { var tradeClone = trade.Clone(); tradeBLL.SetFieldsByTradeType(tradeClone); var realTradeId = tradeClone.id; tradeClone.id = 0; tradeClone.VolType = "报价Bid"; tradeClone.TradeCloseVolatility = null;//不设置为null会影响计算结果 var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(tradeClone.UnderlyingCode); tradeClone.StockEqvNotional = tradeClone.OriginalStockEqvNotional ?? 0; tradeClone.Notional = tradeClone.OriginalNotional ?? 0; tradeClone.TradeAmount = underlying != null && underlying.CountRatio != 0 ? tradeClone.Notional / underlying.CountRatio : tradeClone.Notional; if (!tradeClone.TTMDays.HasValue) { tradeClone.TTMDays = TradeCalcHelper.CalculateTTMDays(tradeClone.TradeDate.Value, tradeClone.ExerciseDate.Value, underlying?.UnderlyingTypeId ?? 0, PS.Config.ErpElement.PrecisionOfMinuteInQuote); } return GetInitialMargin(tradeClone, realTradeId, true); } public static double GetInitialMargin(trade trade, int realTradeId, bool hasOptionInfo = false) { if (trade is null) { return 0; } var um = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode); trade.MaturityDate = um?.MaturityDate; ///关于交易id的多义性: 1.组合交易需要真实的交易id;2.考虑到波动率不能获取持仓波动率,将id赋值为0;3.定价页面结构化交易子交易id会赋值-1和-2 var req = new GetTradeMarginReq { realTradeId = realTradeId, trade = trade, price = trade.SpotPrice ?? 0, hasOptionInfo = hasOptionInfo, calcMarginType = CalcMarginTypeEnum.InitialMargin }; return GetTradeMargin(req); } /// /// isInitialMargin为true: 为初始预付金 /// isInitialMargin为false: 为实时预付金 /// public static double GetTradeMargin(GetTradeMarginReq req) { if (req.trade.TradeType == "结构化交易") { var option = StructureOption_Code.StructureOptions.FirstOrDefault(o => o.Name == req.trade.StructureType || o.CnName == req.trade.StructureType); //自由组合时不在变更StructureType字段值,保持原有结构化交易的内容; if (option != null) { req.trade.StructureType = option.CnName; } } double? tempInitialMargin = null; if (req.calcMarginType != CalcMarginTypeEnum.InitialMargin && req.trade.CalcFlag == 1) { tempInitialMargin = req.trade.InitialMargin; req.trade.InitialMargin = null; } try { if (req.trade.TradeType == "现金流交易") { return 0; } else if (req.trade.MarginType != MarginTypeEnum.DEFAULT) { var result = SingleMarginCalculation(req.GetRunMarginCalculationReq()); return (result.FirstOrDefault()?.WorstCastClientPayable) ?? 0; } else { switch (PS.Config.Company) { case CompanyEnum.渤海: return BHRSMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.安粮: return BHRSMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.申万: return SYWGMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.茂川资本: return MaoChuanMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.宏源: return HongYuanMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.伴兴: return BXMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.海通: return HaiTongMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.瑞达: return RDMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.兴证: return XingZhengMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.弘业: return HongYeMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.广期资本: return GQMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.方顿: return FDMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.国海: return GuoHaiMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.华安: return HuaAnMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.浙期: return ZheQiMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.润和: return DongZhengRunHeMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.国投: return GuoTouMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.湘财: return XiangCaiMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.中粮: return ZhongLiangMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.长江: return ChangJiangMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.国信金阳: return GuoXinJinYangMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.东吴: return DongWuMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.格林大华: #if DEBUG return GLDHMarginCalculation.Instance.GetTradeMargin(req); #endif case CompanyEnum.广发商贸: return GFSMMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.国泰君安: case CompanyEnum.上期资本: case CompanyEnum.光大光子: return GTJAMarginCalculation.Instance.GetTradeMargin(req); case CompanyEnum.招证: return ZhaoZhengMarginCalculation.Instance.GetTradeMargin(req); default: return DefaultMarginCalculation.Instance.GetTradeMargin(req); } } } finally { if (req.calcMarginType == CalcMarginTypeEnum.InitialMargin && req.trade.CalcFlag == 1 && req.trade.InitialMargin == null) { req.trade.InitialMargin = tempInitialMargin; } } } } }