using Qdp.Pricing.Library.Common.Products.Rates; using System.Linq.Expressions; using System.Runtime.Intrinsics.Arm; using YLErp.BLL; using YLErp.Modules.DataProviderModule; namespace YLErp.Modules.UnderlyingModule { /// /// 标的选项服务 /// public class UnderlyingSelectService : YLBaseService { public UnderlyingSelectService(YLBaseService baseService) : base(baseService) { } public UnderlyingSelectService(OptUserInfo userInfo) : base(userInfo) { } /// /// 获取标的选项 /// public IEnumerable GetSelectItems(UnderlyingSelectRequest req) { if (req.MaxShowLength < 1) req.MaxShowLength = 1; IEnumerable datas = null; var predicate = BuildPredicate(req); var query = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().Where(predicate).Take(req.MaxShowLength).ToList(); if (req.UseForTrading) { List Codes = null; var useWhiteCode = req.BlackLimit > 0 && new StockBlackWhiteService(UserInfo).GetStockBlackWhiteList((Configuration.Enums.LimitRangeEnum)req.BlackLimit, out Codes); UnderlyingSelectItem2 convert(underlying_manager n) { var item = new UnderlyingSelectItem2 { id = n.id, Code = n.UnderlyingCode, Name = n.CalcTypeIsStock() && !n.IsSynthetic() ? n.UnderlyingName : "", VarietyId = n.UnderlyingTypeId, MaturityDate = n.CalcTypeIsStock() || n.IsCommoditySpot() || !n.MaturityDate.HasValue ? "" : n.MaturityDate.Value.ToString("yyyy-MM-dd"), CountRatio = n.CountRatio, ContractSize = n.ContractSize, Price = n.IsBasket() ? DataCacheProvider.GetUnderlyingDataSource().GetPrice(n.UnderlyingCode) : n.Price ?? 0, IsSynthetic = n.IsSynthetic(), IsBasket = n.IsBasket(), InstrumentType = n.UnderlyingInstrumentType, DividendRate = n.DividendRate, QuoteUnitString = n.QuoteUnitString, BlackWhiteState = req.BlackLimit == 0 ? 0 : useWhiteCode ? 1 : 2, Disallow = req.BlackLimit != 0 && n.IsStock() && !n.IsSynthetic() && !n.IsBasket() && Codes != null && useWhiteCode == Codes.Contains(n.UnderlyingCode), UpDownLimit = n.UpDownLimit, PrevClosePrice = n.PrevClosePrice }; if (n.IsBond()&&!string.IsNullOrEmpty(n.ExJson)) { var bond = JsonHelper.Deserialize(n.ExJson); item.Name = n.UnderlyingName; item.UnderlyingFullName=bond.UnderlyingFullName; item.UnderlyingIssuer = bond.UnderlyingIssuer; item.IssueSize = bond.IssueSize; } return item; } datas = query.Select(convert).Take(req.MaxShowLength).ToArray(); Variety variety = null; foreach (UnderlyingSelectItem2 item in datas) { if (string.IsNullOrWhiteSpace(item.UpDownLimit)) { if (variety != null && variety.id == item.VarietyId) { item.UpDownLimit = variety.UpLimit; } else { variety = DataCacheProvider.GetVarietyDataSource().GetData(item.VarietyId); if (variety != null) { item.UpDownLimit = variety.UpLimit; } } } if (Codes == null) { continue; } if (item.IsSynthetic) { var underlyingInfo = DataCacheProvider.GetUnderlyingDataSource().GetSyntheticUnderlying(item.Code); item.Disallow = underlyingInfo.GetUnderlyingCodes().Any(O => { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(O); return req.BlackLimit != 0 && um.IsStock() && !um.IsSynthetic() && !um.IsBasket() && Codes != null && useWhiteCode == Codes.Contains(O); }); } if (item.IsBasket) { var underlyingInfo = DataCacheProvider.GetUnderlyingDataSource().GetData(item.Code); var data = JsonHelper.Deserialize>(underlyingInfo.SubData); item.Disallow = data.Any(O => { var um = DataCacheProvider.GetUnderlyingDataSource().GetData(O.code); return um == null ? true : req.BlackLimit != 0 && um.IsStock() && !um.IsSynthetic() && !um.IsBasket() && Codes != null && useWhiteCode == Codes.Contains(O.code); }); } } } else { var query2 = query.Select(n => new UnderlyingSelectItem { id = n.id, Code = n.UnderlyingCode, Name = ConsGlobal.InstrumentType.CalcTypeIsStock(n.UnderlyingInstrumentType) ? n.UnderlyingName : "", VarietyId = n.UnderlyingTypeId }).Take(req.MaxShowLength); datas = query2.ToArray(); } if (req.MustRetOne && !datas.Any()) { req.MustRetOne = false; req.MaxShowLength = 1; req.FilterCode = null; return GetSelectItems(req); } return datas; } //创建标的查询预测 private Expression> BuildPredicate(UnderlyingSelectRequest req) { if (req.UnderlyingId > 0) { return PredicateBuilder.Create(n => n.id == req.UnderlyingId); } if (req.ExcatCodeFilter) { return string.IsNullOrWhiteSpace(req.FilterCode) ? PredicateBuilder.False() : PredicateBuilder.Create(n => n.UnderlyingCode==req.FilterCode); } var predicate = PredicateBuilder.True(); //标的品种 IEnumerable varietyids = null; if (req.ClientId > 0) { varietyids = TradeRightProvider.GetClientVarietyIds(req.ClientId); } if (req.UseRightFilter) { var varietyids2 = TradeRightProvider.GetUserVarietyIds(UserId); varietyids = varietyids == null ? varietyids2 : varietyids.Concat(varietyids2); } if (varietyids != null) { if (!varietyids.Any(n => n > 0)) { return PredicateBuilder.False(); } predicate = predicate.And(n => varietyids.Contains(n.UnderlyingTypeId)); } //是否启用 if (req.CheckLaunch) { predicate = predicate.And(n => n.LaunchState == "1"); } //资产类型 List instTypes = null; if (req.InstrumentTypes != null && req.InstrumentTypes.Any(n => !string.IsNullOrEmpty(n))) { instTypes = req.InstrumentTypes.Where(n => !string.IsNullOrEmpty(n)).ToList(); } if (!string.IsNullOrWhiteSpace(req.Scenario)) { if (instTypes == null) { instTypes = new List(); } if (req.Scenario == "期权交易") { instTypes.AddRange(ConsGlobal.InstrumentType.GetFutureTypes()); instTypes.AddRange(ConsGlobal.InstrumentType.GetSpotTypes()); instTypes.AddRange(ConsGlobal.InstrumentType.GetStockTypes()); } } if (instTypes != null) { if (!instTypes.Any()) { return PredicateBuilder.False(); } predicate = predicate.And(n => instTypes.Contains(n.UnderlyingInstrumentType)); } //组合标的 if (req.OnlySynthetic) { predicate = predicate.And(n => n.CommodityCode == "组合标的"); } else if (!req.IncludeSynthetic) { predicate = predicate.And(n => n.CommodityCode != "组合标的"); } //篮子标的 if (req.OnlyBasket) { predicate = predicate.And(n => n.CommodityCode == "篮子标的"); } else if (!req.IncludeBasket) { predicate = predicate.And(n => n.CommodityCode != "篮子标的"); } //过期标的 if (req.MinMaturityDate.HasValue) { predicate = predicate.And(n => n.UnderlyingInstrumentType != ConsGlobal.InstrumentType.CommodityFutures || n.MaturityDate >= req.MinMaturityDate.Value); } else if (!req.IncludeMatured) { var valueDate = valuedateBLL.ValueDate; predicate = predicate.And(n => n.UnderlyingInstrumentType != ConsGlobal.InstrumentType.CommodityFutures || n.MaturityDate >= valueDate); } //标的代码 var filterCode = req.FilterCode.TrimToNull(); if (filterCode != null) { predicate = predicate.And(n => n.UnderlyingCode.StartsWith(filterCode)); if (filterCode.Length >= 4 && req.MaxShowLength > 10) { req.MaxShowLength = 10; } } else if (req.VarietyId != 0) //品种ID { predicate = predicate.And(n => n.UnderlyingTypeId == req.VarietyId); } return predicate; } } /// /// 标的选择请求Model /// public class UnderlyingSelectRequest { /// /// 最大显示条目数(默认20) /// public int MaxShowLength { get; set; } = 20; /// /// 客户ID(用于客户授信时配置的限制交易品种过滤) /// public int ClientId { get; set; } /// /// 使用角色权限过滤(默认false) /// public bool UseRightFilter { get; set; } /// /// 标的资产类型 /// public IEnumerable InstrumentTypes { get; set; } /// /// 包括组合标的(默认false) /// public bool IncludeSynthetic { get; set; } /// /// 只取组合标的(默认false) /// public bool OnlySynthetic { get; set; } /// /// 包括篮子标的(默认false) /// public bool IncludeBasket { get; set; } /// /// 只取篮子标的(默认false) /// public bool OnlyBasket { get; set; } /// /// 检查标的启用状态(默认true) /// public bool CheckLaunch { get; set; } = true; //--------特殊处理------------------------------ /// /// 使用拼音过滤 /// public bool UsePinYinFilter { get; set; } /// /// 包括已过期标的(默认false)() /// public bool IncludeMatured { get; set; } /// /// 代码过滤(默认null) /// public string FilterCode { get; set; } /// /// 品种ID(只在FilterCode为空时时所用) /// public int VarietyId { get; set; } /// /// 只使用FilterCode精确匹配 /// public bool ExcatCodeFilter { get; set; } /// /// 必须返回一个标的 /// public bool MustRetOne { get; set; } //--------数据用途------------------------------ /// /// 用于交易 /// public bool UseForTrading { get; set; } /// /// 大于0时用于区分互换还是场外 /// public int BlackLimit { get; set; } //--------标的ID------------------------------ /// /// 标的ID /// public int UnderlyingId { get; set; } /// /// 使用场景 /// public string Scenario { get; set; } //--------到期日限定------------------------------ /// /// 最小到期日 /// public DateTime? MinMaturityDate { get; set; } public override string ToString() { return $"{FilterCode}"; } } /// /// 标的选项 /// public class UnderlyingSelectItem { /// /// 标的ID /// public int id { get; set; } /// /// 标的名称 /// public string Name { get; set; } /// /// 标的代码 /// public string Code { get; set; } /// /// 品种ID /// public int VarietyId { get; set; } public override string ToString() { return $"{id}--{Name}--{Code}--{VarietyId}"; } } /// /// 标的选项 /// public class UnderlyingSelectItem2 : UnderlyingSelectItem { /// /// 是否组合标的 /// public bool IsSynthetic { get; set; } /// /// 是否属于篮子标的 /// public bool IsBasket { get; set; } /// /// 资产类型 /// public string InstrumentType { get; set; } /// /// 到期日 /// public string MaturityDate { get; set; } /// /// 份额和数量的乘积因子 /// public int CountRatio { get; set; } = 1; /// /// 合约乘数 /// public double ContractSize { get; set; } = 1; /// /// 最新价格 /// public double Price { get; set; } /// /// 分红率 /// public double? DividendRate { get; set; } /// /// 交易单位 /// public string QuoteUnitString { get; set; } /// /// 当前黑白名单模式 /// 1:黑名单 /// 2:白名单 /// public int BlackWhiteState { get; set; } /// /// 允许选择 /// public bool Disallow { get; set; } /// /// 涨跌停幅度 /// public string UpDownLimit { get; set; } /// /// 涨停价跌停价 /// public double? PrevClosePrice { get; set; } /// /// 债券全名 /// public string UnderlyingFullName { get; set; } /// /// 标的发行量(亿) /// public decimal? IssueSize { get; set; } /// /// 标的证券发行人 /// public string UnderlyingIssuer { get; set; } } }