using BaseOUDAL; using System.Data; using YLErp.Commons; using YLErp.Model.Enum; namespace YLErp.Modules.MarginModule { public class MarginRateSwapService : YLBaseService { public MarginRateSwapService(OptUserInfo userInfo) : base(userInfo) { } /// /// 导入预付金率 /// public void ImportMarginRate(Stream streamIn, out int totalNum, out int successNum) { totalNum = 0; successNum = 0; var rowIndex = 0; try { var ds = Office.ExcelHelper.ReadExcelAsDataSet(streamIn, new[] { 0 }, 1); if (ds.Tables.Count < 1 || ds.Tables[0].Rows.Count < 1) { throw new ServiceException("读取导入数据失败:数据为空") { Tag = "111" }; } var table = ds.Tables[0]; var reader = new DataRowReader(table); rowIndex = 0; totalNum = table.Rows.Count - rowIndex; foreach (var row in table.Rows.Cast()) { rowIndex++; if (row.ItemArray.All(n => string.IsNullOrWhiteSpace(n?.ToString()))) { totalNum--; continue; } reader.SetDataRow(row); using (var trans = BeginTransaction()) { //映射导入数据到交易对象 var maginRate = MapMarginRate(reader); saveMarginRate(maginRate, true); successNum++; trans.Commit(); } } } catch (ServiceException se) { if (se.Tag != null) { throw; } throw new ServiceException($"已成功导入{successNum}条;\n第{rowIndex}行,{se.Message}"); } catch (Exception ex) { LogFactory.GetLogger("导入互换预付金率").Error(ex); throw new ServiceException($"已成功导入{successNum}条,\n第{rowIndex}行,发生错误:{ex.Message}", ex); } } private client_marginrate MapMarginRate(DataRowReader reader) { var marginRate = new client_marginrate() { ClientName = reader.GetString("客户名称", false), ValueDate = reader.GetDate("起效日期", true) ?? DateTime.Now, InitMarginRate = reader.GetPercent("初始保证金率", true) ?? 0, MaintenanceRate = reader.GetPercent("维持保证金率", true) ?? 0, SwapEndDays =reader.GetInt("互换默认期限",true) }; var client = new Client(); marginRate.Type = "普通"; if (!string.IsNullOrWhiteSpace(marginRate.ClientName)) { client = DataCacheProvider.GetClientDataSource().AsQueryable().Where(o => o.Name == marginRate.ClientName).FirstOrDefault(); if (client == null) { throw new ServiceException("未找到客户:" + marginRate.ClientName); } marginRate.ClientId = client.id; } marginRate.VarietyId = null; return marginRate; } public void saveMarginRate(client_marginrate marginrate, bool canCover = false) { if (marginrate == null) { throw new ServiceException("无数据"); } if (marginrate.InitMarginRate < 0) { throw new ServiceException("预付金率数据格式错"); } var dbMarginRate = new client_marginrate(); var marginrateType = "普通"; if (marginrate.id != 0) { dbMarginRate = DbContext.client_marginrate.Find(marginrate.id); if (dbMarginRate == null) { throw new ServiceException("未找到该记录"); } dbMarginRate.ClientId = marginrate.ClientId; dbMarginRate.VarietyId = marginrate.VarietyId; dbMarginRate.Type = marginrate.Type; dbMarginRate.InitMarginRate = marginrate.InitMarginRate; dbMarginRate.ClosePositionLine = marginrate.ClosePositionLine; dbMarginRate.WarningLine = marginrate.WarningLine; dbMarginRate.ValueDate = marginrate.ValueDate; dbMarginRate.InitMarginRebateRate = marginrate.InitMarginRebateRate; dbMarginRate.AddToMarginRebateRate= marginrate.AddToMarginRebateRate; dbMarginRate.LongInitMarginRate = marginrate.LongInitMarginRate; dbMarginRate.ShortInitMarginRate = marginrate.ShortInitMarginRate; dbMarginRate.SwapEndDays = marginrate.SwapEndDays; dbMarginRate.MaintenanceRate= marginrate.MaintenanceRate; dbMarginRate.OptId = UserId; dbMarginRate.OptName = UserName; dbMarginRate.OptDate = DateTime.Now; if (DbContext.client_marginrate.Any(o =>marginrate.Type == marginrateType && o.VarietyId == marginrate.VarietyId && o.ClientId == marginrate.ClientId && o.ValueDate == marginrate.ValueDate && o.id != marginrate.id)) { throw new ServiceException("同一客户同一" + marginrateType + "不支持在同一生效日有多条记录!"); } } else { dbMarginRate = DbContext.client_marginrate.Where(o =>marginrate.Type == marginrateType && o.VarietyId == marginrate.VarietyId && o.Type == marginrate.Type && o.ClientId == marginrate.ClientId && o.ValueDate == marginrate.ValueDate).FirstOrDefault(); if (dbMarginRate == null) { marginrate.OptId = UserId; marginrate.OptName = UserName; marginrate.OptDate = DateTime.Now; DbContext.client_marginrate.Add(marginrate); } else if (canCover) { dbMarginRate.InitMarginRate = marginrate.InitMarginRate; dbMarginRate.ClosePositionLine = marginrate.ClosePositionLine; dbMarginRate.WarningLine = marginrate.WarningLine; dbMarginRate.InitMarginRebateRate = marginrate.InitMarginRebateRate; dbMarginRate.AddToMarginRebateRate = marginrate.AddToMarginRebateRate; dbMarginRate.LongInitMarginRate = marginrate.LongInitMarginRate; dbMarginRate.ShortInitMarginRate = marginrate.ShortInitMarginRate; dbMarginRate.SwapEndDays = marginrate.SwapEndDays; dbMarginRate.MaintenanceRate = marginrate.MaintenanceRate; dbMarginRate.OptId = UserId; dbMarginRate.OptName = UserName; dbMarginRate.OptDate = DateTime.Now; } else { throw new ServiceException("同一客户同一" + marginrateType + "不支持在同一天有多条记录"); } } DbContext.SaveChanges(); } private void checkMarginRate(client_marginrate marginrate) { if (ClientMarginTypeEnum.多空组合.ToString().Equals(marginrate.Type)) { if (marginrate.InitMarginRate < 0.25) { throw new ServiceException("根据监管要求权益类多空组合型收益互换预付金不得低于25%"); } } else { var variety = DbContext.variety.Find(marginrate.VarietyId); if (variety == null) { throw new ServiceException("所设置标的品种不存在!"); } else { //股票、窄基股票指数及其产品、信用债 初始预付金比率 必须大于等于100% if ((variety.AssetType == "个股" || (variety.AssetType == "指数" && "窄基指数".Equals(variety.IndexType))) && marginrate.InitMarginRate < 1) { throw new ServiceException("所设置品种包含股票或窄基指数及其产品、信用债,初始预付金比例不得低于100%!"); } else if ((variety.AssetType == "指数" && "宽基指数".Equals(variety.IndexType)) && marginrate.InitMarginRate < 0.5) { //挂钩宽基股票指数及其产品,无对应期货品种的 向单一交易对手方收取的预付金比例不得低于50% throw new ServiceException("所设置品种挂钩宽基股票指数及其产品,无对应期货品种的,初始预付金比例不得低于50%!"); } else if (marginrate.InitMarginRate < (variety.Margin ?? 0.0)) { //有对应期货或集中交易品种的 不得低于品种设置的最低预付金比例 throw new ServiceException(String.Format("所设置品种有对应期货或集中交易品种的,初始预付金比例不得低于品种[{0}]所设置最低预付金比例{1}%!", variety.VarietyName, variety.Margin * 100)); } } } } public SearchListResult SearchList(MarginRateSwapReq req) { var query = from source in DbContext.client_marginrate select source; if (req.ClientId > 0) { query = query.Where(o => o.ClientId == req.ClientId); } if (req.VarietyId > 0) { query = query.Where(o => o.VarietyId == req.VarietyId); } if (req.Type != null) { query = query.Where(o => o.Type == req.Type); } if (string.IsNullOrEmpty(req.sidx)) { req.sidx = "id"; req.sord = "desc"; } return query.ToSearchList(req); } public double GetMarginRate(int clientId, int varietyId, DateTime searchDate) { var marginRates = DbContext.client_marginrate.Where(o => o.VarietyId == varietyId && o.ValueDate < searchDate).OrderByDescending(o => o.ValueDate); var marginRate = marginRates.Any(o => o.ClientId == clientId) ? marginRates.FirstOrDefault(o => o.ClientId == clientId) : marginRates.FirstOrDefault(o => o.ClientId == 0); if (marginRate == null) { throw new Exception($"ClientId:{clientId} - VarietyId:{varietyId} 未找到对应的预付金率"); } else { var credit = DbContext.credit.Where(o => o.ClientId == clientId && o.CreditStartDate <= searchDate).FirstOrDefault(); if (credit == null || credit.PFECredit == null || credit.PFECredit == 0) { return marginRate.InitMarginRate; } return marginRate.InitMarginRate; } } public class MarginRateSwapReq : BaseSearchReq { public int ClientId { get; set; } public int VarietyId { get; set; } public string Type { get; set; } } public class MarginRateSwapMonitorReq : BaseSearchReq { public IEnumerable WarnningTypes { get; set; } public IEnumerable ClientIds { get; set; } public IEnumerable VarietyIds { get; set; } public DateTime? ValueDate { get; set; } public IEnumerable AssetIds { get; set; } public IEnumerable UnderlyingIds { get; set; } public IEnumerable UnderlyingCodes { get; set; } public string SwapType { get; set; } public string TradeNumber { get; set; } public bool OpenWaringLineMonitor { get; set; } public bool OpenCloseLineMonitor { get; set; } public DateTime? DateFromTradeDate { get; set; } public DateTime? DateToTradeDate { get; set; } } } }