//using BaseOUDAL; //using System; //using System.Collections.Generic; //using System.Linq; //using YLErp.BLL.Calculation; //using YLErp.BLL.Calculation.V2; //using YLErp.BLL.Eod; //using YLErp.DBModels; //using YLErp.DBModels.Consts; //using YLErp.Model; //using YLErp.Modules.DataCacheModule; //using YLErp.Modules.TradeDalModule; //using YLErp.Modules.VolatilityModule; //using YLErp.QdpModule; //using CalculatorHelper = YLErp.BLL.Calculation.CalculatorHelperOld; //namespace YLErp.BLL.MarginCalculationBak //{ // /// // /// 方顿 // /// // public class FDMarginCalculation : MarginCalculationBase // { // // 定义一个静态变量来保存类的实例 // public static readonly FDMarginCalculation Instance; // static FDMarginCalculation() // { // Instance = new FDMarginCalculation(); // } // // 定义私有构造函数,使外界不能创建该类实例 // private FDMarginCalculation() // { // } // 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; // } // using (YLContext db = new YLContext()) // { // if (!hasOptionInfo) // { // tradeBLL.SetFieldsByTradeType(tradeList); // } // var lastSettleDate = EodOperationBase.GetLastSettlementDate(settleDate, true); // var tradeIds = tradeList.Select(t => t.id).ToList(); // var tradeMetaDatas = db.TradeMeta.Where(m => tradeIds.Contains(m.TradeId)).ToList().GroupBy(t => t.TradeId).ToDictionary(g => g.Key, g => g.ToDictionary(m => m.MetaKey, m => m.MetaValue)); // var positionMaginRatioDic = db.TradeMeta.Where(m => tradeIds.Contains(m.TradeId) && m.MetaKey == ConsTradeMetaKey.PositionMarginRate) // .ToList().ToDictionary(m => m.TradeId, m => DataConvert.ToDouble(m.MetaValue)); // new TradeDalService(new OptUserInfo(userId, userName)).SetSubTradeList(tradeList); // var tradeRiskResult = CalculatorHelper.CalculateRisksForTrades(userId + "", settleDate, tradeList, priceDict, ValueCalculator.BASIC_PRICING, null, isEodSettle, volType, isUseTradeVol: PS.Config.IsTradeVol); // logger.Info($"商品期货保证金计算,交易入:[{tradeList.Count}条],返回[{tradeRiskResult.Results.Count}],错误:{tradeRiskResult.ErrorMessage}"); // //客户对应等级系数 // 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 (!string.IsNullOrWhiteSpace(tradeRiskResult.ErrorMessage)) // { // throw new ServiceException(tradeRiskResult.ErrorMessage); // } // if (tradeRiskResult.Results.Count > 0) // { // var lastTradeSpanList = db.trade_span.Where(s => s.ValueDate == lastSettleDate).ToList(); // foreach (var item in tradeRiskResult.Results) // { // var client = clientList.FirstOrDefault(c => c.client.id == item.Trade.ClientId); // Dictionary metaDics = null; // if (tradeMetaDatas.ContainsKey(item.Trade.id)) // { // metaDics = tradeMetaDatas[item.Trade.id]; // } // #region 维持保证金率 // var positionMaginRatio = 0.0; // if (metaDics != null && metaDics.ContainsKey(ConsTradeMetaKey.PositionMarginRate)) // { // positionMaginRatio = DataConvert.ToDouble(metaDics[ConsTradeMetaKey.PositionMarginRate]); // } // #endregion // #region 当前保证金额 // var cashDeposit = 0.0; // var lastTradeSpan = lastTradeSpanList.FirstOrDefault(s => s.TradeId == item.Trade.id); // if (lastTradeSpan != null) // { // cashDeposit = (lastTradeSpan.CashDeposit ?? 0) + (lastTradeSpan.Margin ?? 0); // } // else if (metaDics != null && metaDics.ContainsKey(ConsTradeMetaKey.InitialMarginMoney)) // { // cashDeposit = DataConvert.ToDouble(metaDics[ConsTradeMetaKey.InitialMarginMoney]); // } // #endregion // var value = Math.Abs(item.ValueResult.DeltaCash) * positionMaginRatio * (item.Trade.BuySell == "买入" ? 1 : (PS.Config.ErpElement.TwoSideMargin && client.client.HasTwoSideMargin == 1 ? -1 : 0)); // var twoSideMargin = Math.Abs(item.ValueResult.DeltaCash) * positionMaginRatio * (item.Trade.BuySell == "买入" ? 1 : -1); // if (item.Trade.TradeType == "自定义交易") // { // var eodTradeRiskManual = db.eod_trade_risk_manual.Where(x => x.ValueDate <= settleDate && x.TradeId == item.Trade.id).OrderByDescending(x => x.ValueDate).FirstOrDefault(); // //收盘时如果自定义交易还活着且没有维护当日风险,并且收的时系统日期当日的盘,抛出exception // if (isEodSettle && !ConsTrade.TradeCompleteStatus.Contains(item.Trade.TradeStatus) && settleDate == valuedateBLL.SystemDate.ValueDate) // { // if (eodTradeRiskManual == null || eodTradeRiskManual.ValueDate != settleDate) // { // var error = $"TradeNumber:{item.Trade.TradeNumber}在{settleDate:yyyy-MM-dd}需先进行交易风险维护"; // throw new Exception(error); // } // } // value = eodTradeRiskManual?.Margin ?? 0; // twoSideMargin = eodTradeRiskManual?.Margin ?? 0; // } // #region 风险敞口 // var riskExposure = 0.0; // if (item.Trade.BuySell == "买入") // { // //这个地方很诡异,GetAsianFinalPrice和ActualStrike使用了相同的逻辑取均价,不同的地方在于ActualStrike使用的是系统日期,但这样又会造成历史收盘的偏差 // riskExposure = Math.Max(0, (trade_asian_optionBLL.GetAsianFinalPrice(item.Trade, settleDate) - item.Trade.ActualStrike ?? 0) * (item.Trade.OptionType == "看涨" ? 1 : -1)) * item.Trade.Notional; // } // #endregion // //是否需要追保 // var needMargin = (riskExposure - cashDeposit) > 0; // tradeSpans.Add(new trade_span // { // TradeId = item.Trade.id,//默认记录为第一条交易记录中 // OptDate = DateTime.Now, // OptId = userId, // OptName = userName, // ClientId = item.Trade.ClientId, // ValueDate = settleDate, // UnderlyingId = item.Trade.UnderlyingId, // UnderlyingCode = item.Trade.UnderlyingCode, // Spv1 = value, // Spv2 = value, // Spv3 = value, // Spv4 = value, // WorstCastClientPayable = value, // TwoSideMargin = twoSideMargin, // RiskExposure = riskExposure, // CashDeposit = cashDeposit, // Margin = needMargin ? (riskExposure - cashDeposit + Math.Max(value, 0)) : 0, // Comment = $"DeltaCash:{item.ValueResult.DeltaCash},PositionMaginRatio:{positionMaginRatio}" // }); // } // } // return tradeSpans; // } // } // /// // /// 获取初始保证金率 // /// // /// // /// // public double? GetInitialMarginRatio(trade trade) // { // if (trade == null) // { // return 0; // } // if (!trade.VarietyId.HasValue || trade.VarietyId <= 0) // { // return 0; // } // if (!trade.StockEqvNotional.HasValue) // { // return 0; // } // var variety = DataCacheManager.GetVarietyDataSource().GetData(trade.VarietyId ?? 0); // if (variety == null) // { // return 0; // } // //OTC-8856 Start // var UpLimitValue = variety.UpLimitValue; // //var UpLimitValue =((Math.Abs(trade.Underlying.UpDownLimitValue) > 1e-5) ? trade.Underlying.UpDownLimitValue : variety.UpLimitValue); // //End // if (trade.StockEqvNotional <= 5000000) // { // return 2 * UpLimitValue; // } // else if (trade.StockEqvNotional <= 10000000) // { // return 2.5 * UpLimitValue; // } // else if (trade.StockEqvNotional <= 20000000) // { // return 3 * UpLimitValue; // } // return null; // } // /// // /// 获取维持保证金率 // /// // /// // /// // public double? GetPositionMarginRatio(trade trade) // { // if (trade == null) // { // return 0; // } // if (!trade.VarietyId.HasValue || trade.VarietyId <= 0) // { // return 0; // } // if (!trade.StockEqvNotional.HasValue) // { // return 0; // } // //underlying_manager // var variety = DataCacheManager.GetVarietyDataSource().GetData(trade.VarietyId ?? 0); // if (variety == null) // { // return 0; // } // if (trade.StockEqvNotional <= 5000000) // { // return 1.5 * variety.UpLimitValue; // } // else if (trade.StockEqvNotional <= 10000000) // { // return 2 * variety.UpLimitValue; // } // else if (trade.StockEqvNotional <= 20000000) // { // return 2.5 * variety.UpLimitValue; // } // return null; // } // /// // /// 获取初始保证金 // /// // /// // /// // public double GetInitialMargin(trade trade) // { // return DoInitialMarginCalculationV2(trade); // } // public double DoInitialMarginCalculationV2(trade trade) // { // if (trade.BuySell == "卖出") // { // return 0; // } // var underlying = DataCacheManager.GetUnderlyingDataSource().GetData(trade.UnderlyingId); // underlying.QuotationDate = trade.TradeDate; // var spotPrices = new double[] { trade.SpotPrice ?? 0 }; // string userGroup = UserBLL.GetUserGroup(trade.TraderId ?? 0); // var volSurfaceData = VolatilityHelper.GetVol(underlying.QuotationDate.Value, "交易", underlying.UnderlyingCode, userGroup); // var vol = OptionCalculator.GetInterpolatedVol( // VolConstructionType.Normal, // trade.OptId.ToString(), // volSurfaceData, // underlying.QuotationDate?.ToString("yyyy-MM-dd"), // underlying.UnderlyingCode, // trade.ExerciseDate?.ToString("yyyy-MM-dd"), // trade.Strike ?? 0.0, // isBuy: true, // isCall: trade.CallPut == "Call", // spotPrice: spotPrices[0], // isMoneynessOption: trade.IsMoneynessOptionData, // timeToMaturityDays: trade.TTMDays ?? double.NaN); // if (!trade.NoRiskRate.HasValue) // { // trade.NoRiskRate = (valuedateBLL.SystemDate.RiskFreeRate ?? 0) * 0.01; // } // string fixing = null; // //亚式期权 // if (trade.TradeType == "亚式期权" || trade.StructureType == "亚式熊市价差") // { // fixing = CalculatorHelper.GetFixingStringForAsianOption(trade, trade.TradeDate); // } // var optionValue = ValueCalculator.GetOptionValueResultV2( // trade.OptId.ToString(), // underlying, // trade, // new double[] { vol }, // spotPrices, // fixing, // commodityFuturesPreciseTimeMode: true); // //保证金初始价值=期初期权价值+CashDelta(t)*保证金初始比例(保证金初始比例) // return (trade.TradePrice ?? 0) + ((optionValue == null) ? 0 : Math.Abs(optionValue.DeltaCash)) * (trade.InitialMarginRatio ?? 0); // } // public override double GetTradeMargin(trade trade, double price, bool isInitialMargin = false, bool hasOptionInfo = false) // { // 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; // } // } //}