//using System; //using System.Collections.Generic; //using System.Linq; //using System.Text.RegularExpressions; //using YLErp.DBModels; //using YLErp.Helpers; //using YLErp.Model; //using YLErp.Modules.DataProviderModule; //namespace YLErp.BLL.MarginCalculationBak //{ // /// // /// 保证金计算 // /// // public class MarginCalculationBase // { // protected static readonly Abstract.ILogger logger = LogFactory.GetLogger("保证金计算"); // protected readonly UnderlyingDataProvider _underlyingDataProvider; // protected MarginCalculationBase() // { // _underlyingDataProvider = new UnderlyingDataProvider(); // } // public virtual bool MarginCalcNeedSpecial => false; // public virtual bool CalcClientMargin(int userId, string userName, DateTime settleDate, List tradeSpans, List tradeSpansOtherSide, int SpanType = 0, List RefreshClientIds = null, bool OnlyBuyer = true, Dictionary clientAdditionalMarginDic = null) // { // using (var db = new YLContext()) // { // //删除 // if (tradeSpans != null && tradeSpans.Count > 0) // { // var tradeIds = tradeSpans.Select(t => t.TradeId).ToList(); // var tradeList = db.trade.AsNoTracking().Where(t => tradeIds.Contains(t.id)).ToList(); // var clientIds = tradeSpans.Select(t => t.ClientId).Distinct().ToList(); // var clientList = db.client.Where(x => clientIds.Contains(x.id)).ToList(); // var tradeSpanInfo = (from tradeSpan in tradeSpans // join trade in tradeList on tradeSpan.TradeId equals trade.id // where tradeSpan.ValueDate == settleDate // select new { trade, tradeSpan }).ToList(); // if (OnlyBuyer) // { // tradeSpanInfo = tradeSpanInfo.Where(t => t.trade.BuySell == "买入").ToList(); // } // var clientSpanNews = new List(100); // var clientGroups = tradeSpanInfo.GroupBy(t => t.trade.ClientId); // foreach (var clientGroup in clientGroups) // { // var spvList = new[] { // clientGroup.Sum(g => g.tradeSpan.Spv1??0), // clientGroup.Sum(g => g.tradeSpan.Spv2??0), // clientGroup.Sum(g => g.tradeSpan.Spv3??0), // clientGroup.Sum(g => g.tradeSpan.Spv4??0) // }; // var maxSpv = spvList.Max(); // var twoSideMargin = PS.Config.ErpElement.TwoSideMargin && clientList.FirstOrDefault(x => x.id == clientGroup.Key)?.HasTwoSideMargin == 1; // var clientSpan = new client_span // { // ClientId = clientGroup.Key, // ValueDate = settleDate, // Spv1 = -spvList[0], // Spv2 = -spvList[1], // Spv3 = -spvList[2], // Spv4 = -spvList[3], // WorstCastClientPayable = twoSideMargin ? -maxSpv : -Math.Max(maxSpv, 0), // TwoSideMargin = -maxSpv, // RiskExposure = -clientGroup.Sum(g => g.tradeSpan.RiskExposure), // OptId = userId, // OptName = userName, // OptDate = DateTime.Now, // SpanType = SpanType, // AdditionalWorstCastClientPayable = clientAdditionalMarginDic != null && clientAdditionalMarginDic.TryGetValue(clientGroup.Key ?? 0, out var dd) ? dd : 0 // }; // clientSpanNews.Add(clientSpan); // } // var tradeSpanInfoOtherSide = (from tradeSpan in tradeSpansOtherSide // join trade in tradeList on tradeSpan.TradeId equals trade.id // where tradeSpan.ValueDate == settleDate // select new { trade, tradeSpan }).ToList(); // //处理从客户角度的保证金计算(将交易买卖方向反向处理) // var compareZero = !PS.Config.ErpElement.NonInterBankMarginNetting; // var clientGroupsOtherSide = tradeSpanInfoOtherSide.GroupBy(t => t.trade.ClientId); // foreach (var clientGroup in clientGroupsOtherSide) // { // var clientSpan = clientSpanNews.FirstOrDefault(x => x.ClientId == clientGroup.Key && x.ValueDate == settleDate); // if (clientSpan != null) // { // clientSpan.OtherSideMargin = clientGroup.Sum(g => // { // var arr = new[] { g.tradeSpan.Spv1 ?? 0, g.tradeSpan.Spv2 ?? 0, g.tradeSpan.Spv3 ?? 0, g.tradeSpan.Spv4 ?? 0 }; // return compareZero ? Math.Min(arr.Min(), 0) : arr.Min(); // }); // } // } // //span类型为实时删除所有实时计算的交易的保证金信息 // if (SpanType == client_span.SpanType_RealTime) // { // if (RefreshClientIds != null) // { // db.BulkDelete($"{nameof(client_span.ClientId)} in @ids", new { ids = RefreshClientIds }); // } // else // { // db.BulkDelete($"{nameof(client_span.SpanType)}={SpanType}"); // } // MySqlBulkExtensions.BulkInsert(db, clientSpanNews); // } // else // { // var sql = $"{nameof(client_span.ValueDate)}='{settleDate.ToSqlDate()}' and {nameof(client_span.SpanType)}={SpanType} and {nameof(client_span.ModifiedFlag)}=0"; // db.BulkDelete(sql); // var clientSpanOldsWithFlag = db.client_span.Where(t => t.ValueDate == settleDate && t.SpanType == 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(); // MySqlBulkExtensions.BulkInsert(db, clientSpanNews); // } // db.SaveChanges(); // } // return true; // } // } // public virtual 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) // { // var tradeSpans = new List(); // if (tradeList != null && tradeList.Count > 0) // { // using (var 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 virtual 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; // } // private double GetUpDownValue(string upDownLimit, double settlePrice, double minPriceChange) // { // double result = 0, haifPrice = minPriceChange / 2; // if (upDownLimit.Contains("%")) // { // //百分比 // double.TryParse(upDownLimit.Replace("%", ""), out result); // result = settlePrice * (result * 0.01); // } // else // { // //绝对值 // double.TryParse(upDownLimit, out result); // } // double diff = result % minPriceChange; // result -= diff; // if (diff >= haifPrice) { result += minPriceChange; } // return result; // } // /// // /// 获取涨跌幅 // /// // /// 标的Id // /// // /// Key:标的Id; // /// Value:[0]:涨幅; // /// Value:[1]:跌幅; // /// Value:[2]:最小价格变动; // /// // protected Dictionary GetUpDownLimitRate(IEnumerable underlyingId) // { // Dictionary result = new Dictionary(); // using (YLContext db = new YLContext()) // { // var underlyingIds = underlyingId.ToList(); // //获取标的涨跌幅限制 // var umDatas = (from um in db.underlying_manager // join variety in db.variety on um.UnderlyingTypeId equals variety.id // where underlyingIds.Contains(um.id) // select new // { // um.id, // um.VolatilityRate, // um.UpDownLimit, // variety.MinPriceChange, // defUpLimit = variety.UpLimit, // defDownLimit = variety.DownLimit, // defVolatilityRate = variety.VolatilityRate // }).ToList(); // if (umDatas != null && umDatas.Count > 0) // { // umDatas.ForEach(t => // { // string[] limitArr = new string[3]; // if (!string.IsNullOrWhiteSpace(t.UpDownLimit)) // { // limitArr[0] = t.UpDownLimit;//百分比或绝对值 // limitArr[1] = t.UpDownLimit; // } // else // { // limitArr[0] = t.defUpLimit?.ToString() ?? "5%"; // limitArr[1] = t.defDownLimit?.ToString() ?? "5%"; // } // if (string.IsNullOrEmpty(t.MinPriceChange)) // { // limitArr[2] = "0.01"; // } // else // { // limitArr[2] = Regex.Match(t.MinPriceChange, @"\d+(?=元.+)").Value; // if (string.IsNullOrEmpty(t.MinPriceChange)) // { // limitArr[2] = "0.01"; // } // } // result[t.id] = limitArr; // }); // } // } // return result; // } // /// // /// 获取涨跌幅价格 // /// // /// // /// [0]:涨幅; // /// [1]:跌幅; // /// // /// 基准价 // /// 最小价格变动 // /// // /// [0]:涨停价; // /// [1]:跌停价; // /// // protected double[] GetUpDownLimitPrice(string[] upDownLimit, double price, double minPriceChange) // { // double[] priceArr = new double[2]; // double tempDouble, haifPrice = minPriceChange / 2; // #region 涨幅 // tempDouble = GetUpDownValue(upDownLimit[0], price, minPriceChange); // priceArr[0] = price + Math.Abs(tempDouble); // #endregion // #region 跌幅 // tempDouble = GetUpDownValue(upDownLimit[1], price, minPriceChange); // priceArr[1] = price - Math.Abs(tempDouble); // #endregion // return priceArr; // } // /// // /// 获取涨跌停价格 // /// // /// // /// 当前价格 // /// Key:标的Id; // /// Value:标的价格; // /// // /// // /// Key:标的Id; // /// Value:[0]:涨停价; // /// Value:[1]:跌停价; // /// // protected Dictionary GetUpDownLimitPrice(Dictionary priceDict) // { // Dictionary result = new Dictionary(); // Dictionary upDownLimitRate = GetUpDownLimitRate(priceDict.Keys); // foreach (var item in upDownLimitRate) // { result[item.Key] = GetUpDownLimitPrice(item.Value, priceDict[item.Key], double.Parse(item.Value[2])); } // return result; // } // //为了算客户角度的一个保证金数值 // //RunMarginCalculation时forOtherSide为true时调用 // protected List RunMarginCalculationOtherSide(int userId, string userName, List tradeList, DateTime settleDate, Dictionary priceDict, bool hasOptionInfo, bool isEodSettle, bool forSingleTrade, string volType) // { // void RevertBuySell() // { // foreach (var x in tradeList) // { // x.BuySell = x.BuySell == "买入" ? "卖出" : "买入"; // if (x.SubTrades != null && x.SubTrades.Any()) // { // foreach (var xs in x.SubTrades) // { // xs.BuySell = xs.BuySell == "买入" ? "卖出" : "买入"; // } // } // } // } // RevertBuySell(); // var results = RunMarginCalculation(userId, userName, tradeList, settleDate, priceDict, hasOptionInfo, isEodSettle, forSingleTrade, volType, false); // RevertBuySell(); // return results; // } // /// // /// 获取currentDate参数前一日的结算价 // /// // /// // /// 当前日期 // /// // /// 结算价模式,默认为结算价模式 // /// valuedate.EodSettlePriceMode_*** // /// // /// // protected Dictionary GetSettlePrice(IEnumerable codes, DateTime currentDate, string settlePriceMode = "") // { // //默认情况选择结算价 // bool isClosePrice = "收盘价".Equals(settlePriceMode ?? ""); // codes = codes.ToHashSet(); // Dictionary priceDict = new Modules.MarginModule.eod_commodity_future_priceBLLBak().GetEodPriceToId(codes, currentDate, isClosePrice ? 2 : 3); // return priceDict; // } // } //}