using YLErp.Modules.MarginModule; namespace YLErp.BLL.MarginCalculation { public class UniversalMarginCalculation : MarginCalculationBase { // 定义一个静态变量来保存类的实例 public static readonly UniversalMarginCalculation Instance; static UniversalMarginCalculation() { Instance = new UniversalMarginCalculation(); } // 定义私有构造函数,使外界不能创建该类实例 private UniversalMarginCalculation() { } public override List RunMarginCalculation(RunMarginCalculationReq req) { var tradeSpans = new List(); if (req.tradeList != null && req.tradeList.Count > 0) { 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) { //20210415:为了格林大华收盘通过 //throw new Exception("未实现"); return new List(); } /// /// 商品期权计算预付金 /// public List FutureMarginCalculation(RunMarginCalculationReq req) { var futureTradeList = req.tradeList; var tradeSpans = new List(); if (futureTradeList == null || futureTradeList.Count < 1) { return tradeSpans; } var underlyingCodes = futureTradeList.Select(O => O.UnderlyingCode).ToHashSet(); var mpProvider = new MarginParamProvider(req.UserInfo, req.settleDate) .Initialize(underlyingCodes, MarginParamTypeEnum.MarginRate); var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); foreach (var t in futureTradeList) { if (!helper.GetSpecialMargin(t, 0, out var value)) { req.PriceProvider.TryGetPrice(t.UnderlyingCode, out var price); mpProvider.TryGetMarginRate(t.UnderlyingCode, out var marginRate); var contractSize = (_underlyingDataProvider.GetUnderlying(t.UnderlyingCode)?.ContractSize) ?? 0; double diffPrice = 0; switch (t.OptionType) { case "看涨": diffPrice = (t.Strike ?? 0) - price; break; case "看跌": diffPrice = price - (t.Strike ?? 0); break; } var visualValue = Math.Max(diffPrice, 0) * contractSize; var futureMargin = price * marginRate * contractSize; var optionMargin1 = t.StockEqvNotional + futureMargin - 0.5 * visualValue; var optionMargin2 = t.StockEqvNotional + futureMargin * 0.5; value = Math.Max(optionMargin1, optionMargin2); } 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 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; } } }