从山证v2.3.0拷贝
This commit is contained in:
@@ -0,0 +1,512 @@
|
||||
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
|
||||
{
|
||||
/// <summary>
|
||||
/// 标的选项服务
|
||||
/// </summary>
|
||||
public class UnderlyingSelectService : YLBaseService
|
||||
{
|
||||
public UnderlyingSelectService(YLBaseService baseService) : base(baseService)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public UnderlyingSelectService(OptUserInfo userInfo) : base(userInfo)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取标的选项
|
||||
/// </summary>
|
||||
public IEnumerable<UnderlyingSelectItem> GetSelectItems(UnderlyingSelectRequest req)
|
||||
{
|
||||
if (req.MaxShowLength < 1) req.MaxShowLength = 1;
|
||||
|
||||
IEnumerable<UnderlyingSelectItem> datas = null;
|
||||
|
||||
var predicate = BuildPredicate(req);
|
||||
var query = DataCacheProvider.GetUnderlyingDataSource().AsQueryable().Where(predicate).Take(req.MaxShowLength).ToList();
|
||||
if (req.UseForTrading)
|
||||
{
|
||||
List<string> 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<UnderlyingBond>(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<List<BasketUnderlyingItem>>(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<Func<underlying_manager, bool>> BuildPredicate(UnderlyingSelectRequest req)
|
||||
{
|
||||
if (req.UnderlyingId > 0)
|
||||
{
|
||||
return PredicateBuilder.Create<underlying_manager>(n => n.id == req.UnderlyingId);
|
||||
}
|
||||
|
||||
if (req.ExcatCodeFilter)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(req.FilterCode)
|
||||
? PredicateBuilder.False<underlying_manager>()
|
||||
: PredicateBuilder.Create<underlying_manager>(n => n.UnderlyingCode==req.FilterCode);
|
||||
}
|
||||
|
||||
var predicate = PredicateBuilder.True<underlying_manager>();
|
||||
|
||||
//标的品种
|
||||
|
||||
IEnumerable<int> 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<underlying_manager>();
|
||||
}
|
||||
predicate = predicate.And(n => varietyids.Contains(n.UnderlyingTypeId));
|
||||
}
|
||||
|
||||
//是否启用
|
||||
if (req.CheckLaunch)
|
||||
{
|
||||
predicate = predicate.And(n => n.LaunchState == "1");
|
||||
}
|
||||
|
||||
//资产类型
|
||||
List<string> 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<string>();
|
||||
}
|
||||
|
||||
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<underlying_manager>();
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标的选择请求Model
|
||||
/// </summary>
|
||||
public class UnderlyingSelectRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// 最大显示条目数(默认20)
|
||||
/// </summary>
|
||||
public int MaxShowLength { get; set; } = 20;
|
||||
|
||||
/// <summary>
|
||||
/// 客户ID(用于客户授信时配置的限制交易品种过滤)
|
||||
/// </summary>
|
||||
public int ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用角色权限过滤(默认false)
|
||||
/// </summary>
|
||||
public bool UseRightFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标的资产类型
|
||||
/// </summary>
|
||||
public IEnumerable<string> InstrumentTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 包括组合标的(默认false)
|
||||
/// </summary>
|
||||
public bool IncludeSynthetic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 只取组合标的(默认false)
|
||||
/// </summary>
|
||||
public bool OnlySynthetic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 包括篮子标的(默认false)
|
||||
/// </summary>
|
||||
public bool IncludeBasket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 只取篮子标的(默认false)
|
||||
/// </summary>
|
||||
public bool OnlyBasket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 检查标的启用状态(默认true)
|
||||
/// </summary>
|
||||
public bool CheckLaunch { get; set; } = true;
|
||||
|
||||
//--------特殊处理------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 使用拼音过滤
|
||||
/// </summary>
|
||||
public bool UsePinYinFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 包括已过期标的(默认false)()
|
||||
/// </summary>
|
||||
public bool IncludeMatured { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 代码过滤(默认null)
|
||||
/// </summary>
|
||||
public string FilterCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 品种ID(只在FilterCode为空时时所用)
|
||||
/// </summary>
|
||||
public int VarietyId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 只使用FilterCode精确匹配
|
||||
/// </summary>
|
||||
public bool ExcatCodeFilter { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 必须返回一个标的
|
||||
/// </summary>
|
||||
public bool MustRetOne { get; set; }
|
||||
|
||||
//--------数据用途------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 用于交易
|
||||
/// </summary>
|
||||
public bool UseForTrading { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 大于0时用于区分互换还是场外
|
||||
/// </summary>
|
||||
public int BlackLimit { get; set; }
|
||||
|
||||
//--------标的ID------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 标的ID
|
||||
/// </summary>
|
||||
public int UnderlyingId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 使用场景
|
||||
/// </summary>
|
||||
public string Scenario { get; set; }
|
||||
|
||||
//--------到期日限定------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// 最小到期日
|
||||
/// </summary>
|
||||
public DateTime? MinMaturityDate { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{FilterCode}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标的选项
|
||||
/// </summary>
|
||||
public class UnderlyingSelectItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 标的ID
|
||||
/// </summary>
|
||||
public int id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标的名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标的代码
|
||||
/// </summary>
|
||||
public string Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 品种ID
|
||||
/// </summary>
|
||||
public int VarietyId { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{id}--{Name}--{Code}--{VarietyId}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 标的选项
|
||||
/// </summary>
|
||||
public class UnderlyingSelectItem2 : UnderlyingSelectItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否组合标的
|
||||
/// </summary>
|
||||
public bool IsSynthetic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否属于篮子标的
|
||||
/// </summary>
|
||||
public bool IsBasket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 资产类型
|
||||
/// </summary>
|
||||
public string InstrumentType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 到期日
|
||||
/// </summary>
|
||||
public string MaturityDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 份额和数量的乘积因子
|
||||
/// </summary>
|
||||
public int CountRatio { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 合约乘数
|
||||
/// </summary>
|
||||
public double ContractSize { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 最新价格
|
||||
/// </summary>
|
||||
public double Price { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分红率
|
||||
/// </summary>
|
||||
public double? DividendRate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 交易单位
|
||||
/// </summary>
|
||||
public string QuoteUnitString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前黑白名单模式
|
||||
/// <para>1:黑名单</para>
|
||||
/// <para>2:白名单</para>
|
||||
/// </summary>
|
||||
public int BlackWhiteState { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 允许选择
|
||||
/// </summary>
|
||||
public bool Disallow { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 涨跌停幅度
|
||||
/// </summary>
|
||||
public string UpDownLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 涨停价跌停价
|
||||
/// </summary>
|
||||
public double? PrevClosePrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 债券全名
|
||||
/// </summary>
|
||||
public string UnderlyingFullName { get; set; }
|
||||
/// <summary>
|
||||
/// 标的发行量(亿)
|
||||
/// </summary>
|
||||
public decimal? IssueSize { get; set; }
|
||||
/// <summary>
|
||||
/// 标的证券发行人
|
||||
/// </summary>
|
||||
public string UnderlyingIssuer { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user