using YLErp.BLL.Calculation; using YLErp.DBModels.Helpers; using YLErp.QdpModule; namespace YLErp.BLL.MarginCalculation { /// /// 安粮 /// public class ALQHMarginCalculation : MarginCalculationBase { // 定义一个静态变量来保存类的实例 public static readonly ALQHMarginCalculation Instance; static ALQHMarginCalculation() { Instance = new ALQHMarginCalculation(); } // 定义私有构造函数,使外界不能创建该类实例 private ALQHMarginCalculation() { } 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; } /// /// 股票类期权计算预付金 /// private List StockMarginCalculation(RunMarginCalculationReq req) { var tradeSpans = new List(); if (req.tradeList == null || req.tradeList.Count < 1) { return tradeSpans; } var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); var marginRation = valuedateBLL.SystemDate.MarginRatio ?? 0.15; foreach (var t in req.tradeList) { var client = helper.GetClient(t.ClientId); if (client == null) { continue; } //未设置相关预付金系数默认为1.0 var clientRatio = client?.Ratio ?? 1.0; //如果是股票去名义本金,如果是期货取:份额 * 即期价格 var baseValue = (t.StockEqvNotional == 0 ? TradeHelper.GetStockEqvNotional(t.Notional * t.SpotPrice, t.ParticipationRate, t.AnnualizeFactor) : t.StockEqvNotional) * marginRation; var value = baseValue * (t.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.MarginOptionType == 1 ? -1 : 0)) * clientRatio; var twoSideMargin = baseValue * (t.BuySell == "买入" ? 1 : -1) * clientRatio; tradeSpans.Add(new trade_span { TradeId = t.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = client.ClientId, UnderlyingId = t.UnderlyingId, UnderlyingCode = t.UnderlyingCode, ValueDate = req.settleDate, Spv1 = value, Spv2 = value, Spv3 = value, Spv4 = value, WorstCastClientPayable = value, TwoSideMargin = twoSideMargin }); } return tradeSpans; } /// /// 商品期权计算预付金 /// public List FutureMarginCalculation(RunMarginCalculationReq req) { var futureTradeList = req.tradeList; var tradeSpans = new List(); if (req.tradeList == null || req.tradeList.Count < 1) { return tradeSpans; } var helper = new RunMarginCalculationHelper(req, _underlyingDataProvider); helper.SetFieldsByTradeType(); var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades( valueDate: req.settleDate, tradeList: futureTradeList, calcScenario: req.GetCalcScenario(), priceProvider: req.PriceProvider, pricingRequest: QdpPricingRequest.BASIC_GREEKS, addVolRateDic: null, volType: req.volType, settlementType: req.settlementType, isUseTradeVol: PS.Config.IsTradeVol, preciseTimeMode: req.CalcMarginType != Enums.CalcMarginTypeEnum.EodMargin); var deltaCoefficient = valuedateBLL.SystemDate.FutureMarginDeltaCoefficient ?? 1; var vegaCoefficient = valuedateBLL.SystemDate.FutureMarginVegaCoefficient ?? 3; var omegaCoefficient = valuedateBLL.SystemDate.FutureMarginOmegaCoefficient ?? 2.5; var alphaRate = valuedateBLL.SystemDate.FutureMarginAlphaRate ?? 1; foreach (var item in tradeRiskResult.Results) { var tempTrade = futureTradeList.FirstOrDefault(t => t.id == item.Trade.id); var optionValue = item.ValueResult; var tempVariety = _underlyingDataProvider.GetVariety(tempTrade.UnderlyingId); var closePrice = req.PriceProvider.GetPrice(tempTrade.UnderlyingCode); var client = helper.GetClient(item.Trade.ClientId); if (tempTrade != null && item.ValueResult != null && tempVariety != null) { //未设置相关预付金系数默认为1.0 var clientRatio = client?.Ratio ?? 1.0; //预付金 = ( a * DeltaCash + b* GammaCash * PricingVol / 16) * 当前标的预付金率 + c * Vega var value = ((optionValue.DeltaCash * deltaCoefficient + optionValue.GammaCash * 0.01 * (optionValue.Vol / 16) * omegaCoefficient) * tempVariety.Margin + optionValue.Vega * vegaCoefficient ) * alphaRate * (tempTrade.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.MarginOptionType == 1 ? 1 : 0)) * clientRatio; var twoSideMargin = ((optionValue.DeltaCash * deltaCoefficient + optionValue.GammaCash * 0.01 * (optionValue.Vol / 16) * omegaCoefficient) * tempVariety.Margin + optionValue.Vega * vegaCoefficient ) * alphaRate * (tempTrade.BuySell == "买入" ? 1 : -1) * clientRatio; tradeSpans.Add(new trade_span { TradeId = tempTrade.id, OptDate = DateTime.Now, OptId = req.userId, OptName = req.userName, ClientId = tempTrade.ClientId, UnderlyingId = tempTrade.UnderlyingId, UnderlyingCode = tempTrade.UnderlyingCode, ValueDate = req.settleDate, Spv1 = value, Spv2 = value, Spv3 = value, Spv4 = value, WorstCastClientPayable = value, TwoSideMargin = twoSideMargin }); } } return tradeSpans; } public override double GetTradeMargin(GetTradeMarginReq req) { var marginReq = req.GetRunMarginCalculationReq(); var tradeMargin = RunMarginCalculation(marginReq); if (null != tradeMargin) { return tradeMargin.FirstOrDefault()?.WorstCastClientPayable ?? 0.0; } return 0.0; } } }