Files
zszq-trs/YLErpDAL/Modules/TradeModule/QueryModule/TradeQueryService.cs
T
2024-05-09 14:06:26 +08:00

1188 lines
51 KiB
C#

using BaseOUDAL;
using System.Linq;
using System.Linq.Expressions;
using YLErp.BLL;
using YLErp.BLL.MarginCalculation;
using YLErp.DBModels.Consts;
using YLErp.DBModels.Helpers;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Models;
using YLErp.Modules.RiskModule;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeModule
{
/// <summary>
/// 交易查询服务
/// </summary>
public class TradeQueryService : YLBaseService
{
public TradeQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
public TradeQueryService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
/// 查询trade
/// </summary>
public SearchListResult<trade> SearchList(TradeReq req, TradeQueryRequest req2 = null)
{
Dictionary<int, DateTime> settleTcDict = null;
SubstandardTradeRule rule = null;
if (req.SubstandardType.HasValue)
{
//获取不合规交易的ID
req.TradeIds = GetSubstandardTradeIds(req.SubstandardType.Value, out settleTcDict, out rule);
}
var query = CreateTradeQuery(req, req2);
var retListResult = query.ToSearchList(req);
if (req2.GetSum)
{
var gsum = new tradeGridSum();
if (query.Any())
{
gsum.TradePriceSum = query.Sum(q => q.TradePrice);
}
retListResult.Sum = gsum;
}
//获取销售提成信息
foreach (var item in retListResult.rows)
{
item.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(item.id);
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.SalesCommission?.Commission != null)
{
item.SalesCommission.Commission = item.SalesCommission.Commission * item.SalesCommission.SalesIds.Count();
}
if (req.SubstandardType.HasValue)
{//用于不合规交易页面,展示不合规项;
item.MetaDic["IsStrikeOffset"] = (rule?.StrikeOffset == null || item.Strike == null ? false : item.IsMoneynessOptionData ? Math.Abs((item.Strike ?? 0) - 1) > rule.StrikeOffset : Math.Abs((item.Strike ?? 0) / (item.SpotPrice ?? 0) - 1) > rule.StrikeOffset).ToString();
item.MetaDic["IsMinTradingDay"] = (rule?.MinTradingDay == null ? false : (item.ExerciseDate - item.TradeDate).Value.Days < rule.MinTradingDay).ToString();
item.MetaDic["IsLockTradingDay"] = (settleTcDict != null && settleTcDict.ContainsKey(item.id)).ToString();
}
}
return retListResult;
}
/// <summary>
/// 查询trade
/// </summary>
public SearchListResult<trade> SearchListWithGroup(TradeReq req, TradeQueryRequest req2 = null)
{
Dictionary<int, DateTime> settleTcDict = null;
SubstandardTradeRule rule = null;
if (req.SubstandardType.HasValue)
{
//获取不合规交易的ID
req.TradeIds = GetSubstandardTradeIds(req.SubstandardType.Value, out settleTcDict, out rule);
//这里让它能选择显示子交易 req添加某值设置
req2.withGroupChildren = true;
}
var query = CreateTradeQueryWithGroup(req, req2);
if (req.sidx == "TradeOriginalAmount")//页面需要 有效成交数量 排序,TradeOriginalAmount排序报错,所以用OriginalNotional代替
{
query = req.sord == "desc" ? query.OrderByDescending(a => a.OriginalNotional) : query.OrderBy(a => a.OriginalNotional);
req.sidx = null;
}
var retListResult = query.ToSearchList(req);
if (req2.GetSum)
{
var gsum = new tradeGridSum();
if (query.Any())
{
gsum.TradePriceSum = query.Sum(q => q.TradePrice);
}
retListResult.Sum = gsum;
}
if (retListResult == null || retListResult.rows == null || !retListResult.rows.Any())
{
return retListResult;
}
Dictionary<int, TradeSalesCommissionInfo> dicSaleCommissionList;
using (var commssionService = new SalesModule.SalesCommissionDataService(OptUser))
{
dicSaleCommissionList = commssionService.GetTradeCommissionInfoByTradeIds(retListResult.rows.Select(p => p.id).ToList());
}
if (dicSaleCommissionList == null)
{
dicSaleCommissionList = new Dictionary<int, TradeSalesCommissionInfo>();
}
List<trade_barrier_option> tradeBarrierOptionList = null;
if (retListResult.rows.Any(p => "障碍期权".Equals(p.TradeType)))
{
var barrierTradeIds = retListResult.rows.Where(p => "障碍期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
if (barrierTradeIds != null && barrierTradeIds.Any())
{
tradeBarrierOptionList = DbContext.trade_barrier_option.AsNoTracking().Where(p => barrierTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeBarrierOptionList == null)
{
tradeBarrierOptionList = new List<trade_barrier_option>();
}
List<trade_double_sharkfin_option> tradeDoublesharkfinOptionList = null;
if (retListResult.rows.Any(p => "双鲨期权".Equals(p.TradeType)))
{
var doubleSharkfinTradeIds = retListResult.rows.Where(p => "双鲨期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
if (doubleSharkfinTradeIds != null && doubleSharkfinTradeIds.Any())
{
tradeDoublesharkfinOptionList = DbContext.trade_double_sharkfin_option.AsNoTracking().Where(p => doubleSharkfinTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeDoublesharkfinOptionList == null)
{
tradeDoublesharkfinOptionList = new List<trade_double_sharkfin_option>();
}
List<trade_autocall> tradeAutocallList = null;
if (retListResult.rows.Any(p => "凤凰期权".Equals(p.TradeType)))
{
var autocallTradeIds = retListResult.rows.Where(p => "凤凰期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
if (autocallTradeIds != null && autocallTradeIds.Any())
{
tradeAutocallList = DbContext.trade_autocall.AsNoTracking().Where(p => autocallTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeAutocallList == null)
{
tradeAutocallList = new List<trade_autocall>();
}
List<trade_snowball> tradeSnowballList = null;
if (retListResult.rows.Any(p => "雪球期权".Equals(p.TradeType)))
{
var snowballTradeIds = retListResult.rows.Where(p => "雪球期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
if (snowballTradeIds != null && snowballTradeIds.Any())
{
tradeSnowballList = DbContext.trade_snowball.AsNoTracking().Where(p => snowballTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeSnowballList == null)
{
tradeSnowballList = new List<trade_snowball>();
}
List<trade_airbag> tradeAirbagList = null;
if (retListResult.rows.Any(p => "气囊结构".Equals(p.TradeType) || "气囊结构".Equals(p.StructureType)))
{
var airbagTradeIds = retListResult.rows.Where(p => "气囊结构".Equals(p.TradeType) || "气囊结构".Equals(p.StructureType)).Select(p => p.id).Distinct().ToList();
if (airbagTradeIds != null && airbagTradeIds.Any())
{
tradeAirbagList = DbContext.trade_airbag.AsNoTracking().Where(p => airbagTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeAirbagList == null)
{
tradeAirbagList = new List<trade_airbag>();
}
List<trade_accumulator_option> tradeAccumulatorOptionList = null;
if (retListResult.rows.Any(p => "累计期权".Equals(p.TradeType)))
{
var accumulatorOptionTradeIds = retListResult.rows.Where(p => "累计期权".Equals(p.TradeType)).Select(p => p.id).Distinct().ToList();
if (accumulatorOptionTradeIds != null && accumulatorOptionTradeIds.Any())
{
tradeAccumulatorOptionList = DbContext.trade_accumulator_option.AsNoTracking().Where(p => accumulatorOptionTradeIds.Contains(p.TradeId)).ToList();
}
}
if (tradeAccumulatorOptionList == null)
{
tradeAccumulatorOptionList = new List<trade_accumulator_option>();
}
//获取销售提成信息
foreach (var item in retListResult.rows)
{
if (item.TradeType == "障碍期权")
{
//var option = DbContext.trade_barrier_option.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeBarrierOptionList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
else if (item.TradeType == "双鲨期权")
{
//var option = DbContext.trade_double_sharkfin_option.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeDoublesharkfinOptionList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
else if (item.TradeType == "凤凰期权")
{
//var option = DbContext.trade_autocall.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeAutocallList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
else if (item.TradeType == "雪球期权")
{
//var option = DbContext.trade_snowball.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeSnowballList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
else if (item.TradeType == "气囊结构" || item.StructureType == "气囊结构")
{
//var option = DbContext.trade_airbag.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeAirbagList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
else if (item.TradeType == "累计期权")
{
//var option = DbContext.trade_accumulator_option.FirstOrDefault(x => x.TradeId == item.id);
var option = tradeAccumulatorOptionList.FirstOrDefault(d => d.TradeId == item.id);
item.KnockInOutStatusObservation = option?.KnockInOutStatusCn;
}
//item.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(item.id);
if (dicSaleCommissionList.ContainsKey(item.id))
{
item.SalesCommission = dicSaleCommissionList[item.id];
}
else
{
item.SalesCommission = new TradeSalesCommissionInfo { SalesIds = new List<int>() };
}
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.SalesCommission?.Commission != null)
{
item.SalesCommission.Commission = item.SalesCommission.Commission * item.SalesCommission.SalesIds.Count();
}
if (req.SubstandardType.HasValue)
{//用于不合规交易页面,展示不合规项;
item.MetaDic["IsStrikeOffset"] = (rule?.StrikeOffset == null || item.Strike == null ? false : item.IsMoneynessOptionData ? Math.Abs((item.Strike ?? 0) - 1) > rule.StrikeOffset : Math.Abs((item.Strike ?? 0) / (item.SpotPrice ?? 0) - 1) > rule.StrikeOffset).ToString();
item.MetaDic["IsMinTradingDay"] = (rule?.MinTradingDay == null ? false : (item.ExerciseDate - item.TradeDate).Value.Days < rule.MinTradingDay).ToString();
item.MetaDic["IsLockTradingDay"] = (settleTcDict != null && settleTcDict.ContainsKey(item.id)).ToString();
}
if (item.CountRatio == null)
{
item.CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1;
}
item.StockEqvNotionalMax = item.StockEqvNotionalMax.HasValue ? item.StockEqvNotionalMax : item.StockEqvNotional;
}
return retListResult;
}
public SearchListResult<GroupAction> SearchGroupActionList(TradeReq req)
{
var predicate = CreateGroupActionPredicate(req);
var query = from source in DbContext.trade.AsNoTracking().Where(predicate)
join tc in DbContext.trade_cash.Where(x => x.ValidState != "InValid" && x.Status == null && x.Action != "系统操作-期权费") on source.id equals tc.TradeId
select new GroupAction { id = source.id + "_" + tc.id, trade = source, trade_cash = tc };
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "trade.id";
req.sord = "desc";
}
var retListResult = query.ToSearchList(req);
return retListResult;
}
public List<trade> SearchGroupChildrenList(int id)
{
var trades = DbContext.trade.Where(x => x.ParentTradeId == id && x.ValidState != "InValid").ToList();
return trades;
}
public List<GroupAction> SearchGroupActionChildrenList(SearchGroupActionChildrenListReq req)
{
var childTradeIds = DbContext.trade_cash_group_action.Where(x => x.ParentTradeCashId == req.TradeCashId).Select(x => x.TradeId).ToList();
var query = from source in DbContext.trade.AsNoTracking().Where(x => childTradeIds.Contains(x.id))
join gc in DbContext.trade_cash_group_action.AsNoTracking().Where(x => x.ParentTradeCashId == req.TradeCashId) on source.id equals gc.TradeId
select new GroupAction { id = source.id + "_" + req.TradeCashId, trade = source, trade_cash_group_action = gc };
return query.ToList();
}
public SearchListResult<TradeMarginTemplate> SearchTradeMarginTemplateList(TradeMarginTemplateReq req)
{
var predicate = CreateTradeMarginTmplateQueryWhere(req);
var query = from trade in DbContext.trade.Where(predicate)
join tmt in (from t in DbContext.trade_margin_template where t.IsLatest select t) on trade.id equals tmt.TradeId into tmts
from tmt in tmts.DefaultIfEmpty()
join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id into mts
from mt in mts.DefaultIfEmpty()
select new TradeMarginTemplate()
{
TradeId = trade.id,
ClientId = trade.ClientId,
TradeNumber = trade.TradeNumber,
ClientName = trade.ClientName,
TradeType = trade.ParentTradeId > 0 ? trade.StructureType : trade.TradeType,
TradeStatus = trade.TradeStatus,
InitialMargin = trade.InitialMargin,
MarginTemplateId = tmt == null ? -1 : tmt.MarginTemplateId,
MarginRuleType = mt == null ? -1 : mt.RuleType,
MarginTemplateName = mt == null ? "" : mt.Name,
ValueDate = tmt == null ? DateTime.MinValue : tmt.ValueDate,
TradeDate = trade.TradeDate,
BuySell = trade.BuySell,
UnWindDate = trade.UnWindDate,
ExerciseDate = trade.ExerciseDate
};
if (req.MarginTemplate != null && req.MarginTemplate.Any())
{
query = query.Where(x => req.MarginTemplate.Contains((int)x.MarginTemplateId));
}
if (req.MarginRuleType != null)
{
query = query.Where(x => x.MarginRuleType == req.MarginRuleType);
}
if (req.IsDefault != null)
{
if (req.IsDefault == 1)
{
query = query.Where(x => x.MarginTemplateId <= 0);
}
else
{
query = query.Where(x => x.MarginTemplateId > 0);
}
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeId";
req.sord = "desc";
}
else
{
if ("MarginRuleTypeName".Equals(req.sidx))
{
req.sidx = "MarginRuleType";
}
}
SearchListResult<TradeMarginTemplate> retListResult = query.ToSearchList(req);
return retListResult;
}
private Expression<Func<trade, bool>> CreateTradeMarginTmplateQueryWhere(TradeMarginTemplateReq req)
{
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && t.TradeType != "结构化交易");
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(t => req.UserAssets.Contains(t.AssetId) || req.UserClients.Contains(t.ClientId));
}
if (req.ClientId != null)
{
predicate = predicate.And(x => x.ClientId == req.ClientId);
}
if (!string.IsNullOrEmpty(req.ClientName))
{
predicate = predicate.And(x => x.ClientName.Contains(req.ClientName));
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
predicate = predicate.And(x => x.TradeNumber.Contains(req.TradeNumber));
}
if (req.DateFromTradeDate != null)
{
predicate = predicate.And(x => x.TradeDate >= req.DateFromTradeDate);
}
if (req.DateToTradeDate != null)
{
req.DateToTradeDate = ((DateTime)req.DateToTradeDate).AddDays(1);
predicate = predicate.And(x => x.TradeDate < req.DateToTradeDate);
}
if (req.DateFromExerciseDate != null)
{
predicate = predicate.And(x => x.ExerciseDate >= req.DateFromExerciseDate);
}
if (req.DateToExerciseDate != null)
{
req.DateToExerciseDate = ((DateTime)req.DateToExerciseDate).AddDays(1);
predicate = predicate.And(x => x.ExerciseDate < req.DateToExerciseDate);
}
if (req.TradeTypes != null && req.TradeTypes.Any())
{
predicate = predicate.And(x => req.TradeTypes.Contains(x.TradeType) || req.TradeTypes.Contains(x.StructureType));
}
if (req.TradeStatus != null && req.TradeStatus.Any())
{
predicate = predicate.And(x => req.TradeStatus.Contains(x.TradeStatus));
}
if (req.DateFromUnwindDate != null)
{
predicate = predicate.And(x => x.UnWindDate != null && x.UnWindDate >= req.DateFromUnwindDate);
}
if (req.DateToUnwindDate != null)
{
req.DateToUnwindDate = ((DateTime)req.DateToUnwindDate).AddDays(1);
predicate = predicate.And(x => x.UnWindDate != null && x.UnWindDate < req.DateToUnwindDate);
}
if (!string.IsNullOrEmpty(req.BuySell))
{
predicate = predicate.And(x => x.BuySell.Equals(req.BuySell));
}
if (req.InitialMargin > 0)
{
if (req.InitialMargin == 1)
{
predicate = predicate.And(x => x.InitialMargin == 0 || x.InitialMargin == null);
}
else
{
predicate = predicate.And(x => x.InitialMargin > 0 || x.InitialMargin < 0);
}
}
return predicate;
}
/// <summary>
/// 批量设置预付金
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public bool BatchSetInitialMargin(TradeMarginTemplateReq req)
{
var predicate = CreateTradeMarginTmplateQueryWhere(req);
predicate = predicate.And(x => x.InitialMargin == null && x.ClientId > 0 && x.IsGroup != 1);
var query = from trade in DbContext.trade.Where(predicate)
join tmt in (from t in DbContext.trade_margin_template where t.IsLatest select t) on trade.id equals tmt.TradeId into tmts
from tmt in tmts.DefaultIfEmpty()
join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id into mts
from mt in mts.DefaultIfEmpty()
select new TradeMarginTemplate()
{
TradeId = trade.id,
ClientId = trade.ClientId,
TradeNumber = trade.TradeNumber,
ClientName = trade.ClientName,
TradeType = trade.TradeType,
TradeStatus = trade.TradeStatus,
InitialMargin = trade.InitialMargin,
MarginTemplateId = tmt == null ? -1 : tmt.MarginTemplateId,
MarginRuleType = mt == null ? -1 : mt.RuleType,
MarginTemplateName = mt == null ? "" : mt.Name,
ValueDate = tmt == null ? DateTime.MinValue : tmt.ValueDate,
TradeDate = trade.TradeDate,
BuySell = trade.BuySell,
UnWindDate = trade.UnWindDate,
ExerciseDate = trade.ExerciseDate
};
if (req.MarginTemplate != null && req.MarginTemplate.Any())
{
query = query.Where(x => req.MarginTemplate.Contains((int)x.MarginTemplateId));
}
if (req.MarginRuleType != null)
{
query = query.Where(x => x.MarginRuleType == req.MarginRuleType);
}
if (req.IsDefault != null)
{
if (req.IsDefault == 1)
{
query = query.Where(x => x.MarginTemplateId <= 0);
}
else
{
query = query.Where(x => x.MarginTemplateId > 0);
}
}
var list = query.ToList();
if (list == null || list.Count == 0)
{
return true;
}
var tradeIds = list.Select(p => p.TradeId).Distinct().ToList();
var tradesWithOutGroup = DbContext.trade.Where(p => tradeIds.Contains(p.id)).ToList();
tradesWithOutGroup.ForEach(x =>
{
x.InitialMargin = MarginDefault.GetInitialMarginWithPreHandle(x);
});
DbContext.SaveChanges();
//更新组合交易主预付金初始预付金
var parentTradeIds = tradesWithOutGroup.Where(p => p.ParentTradeId > 0).Select(p => p.ParentTradeId).Distinct().ToList();
if (parentTradeIds != null && parentTradeIds.Any())
{
var tradesGroup = DbContext.trade.Where(x => x.ValidState != "InValid" && parentTradeIds.Contains(x.id)).ToList();
tradesGroup.ForEach(x =>
{
x.InitialMargin = DbContext.trade.Where(y => y.ValidState != "InValid" && y.ParentTradeId == x.id).Sum(y => y.InitialMargin);
});
DbContext.SaveChanges();
}
return true;
}
public List<TradeMarginTemplate> SearchTradeMarginTemplateList(int tradeId)
{
var query = from tmt in DbContext.trade_margin_template
join mt in DbContext.margin_template_v2 on tmt.MarginTemplateId equals mt.id
select new TradeMarginTemplate()
{
TradeId = tmt.TradeId,
MarginTemplateId = tmt.MarginTemplateId,
MarginTemplateName = mt.Name,
ValueDate = tmt.ValueDate,
MarginRuleType = mt.RuleType,
MarginType = mt.MarginType,
Comments = mt.Comments,
OptDate = tmt.OptDate
};
query = query.Where(x => x.TradeId == tradeId);
var retListResult = query.OrderBy(x => x.ValueDate).ToList();
return retListResult;
}
class SubstandardTradeDto
{
public int id;
public DateTime? ExerciseDate;
public DateTime? TradeDate;
public double? Strike;
public double SpotPrice;
public string IsMoneynessOption;
}
private string GetSubstandardTradeIds(int substandardTradeType, out Dictionary<int, DateTime> closeTcDict, out SubstandardTradeRule rule)
{
var obj = new SubstandardTradeRuleService(OptUser).QueryCurrentRule();
rule = obj;
closeTcDict = null;
List<int> codes = new List<int>();
var query = from t in DbContext.trade
where ConsTrade.TradeStatusAfterConfirmed.Contains(t.TradeStatus)
&& t.ClientId > 0 && t.TradeType != "远期" && t.TradeType != "收益互换" && (t.TradeType != "结构化交易" || t.IsGroup == 1)
&& t.ValidState != "InValid"
select new SubstandardTradeDto()
{
id = t.id,
ExerciseDate = t.ExerciseDate,
TradeDate = t.TradeDate,
Strike = t.Strike,
SpotPrice = t.SpotPrice ?? 0,
IsMoneynessOption = t.IsMoneynessOption
};
if ((substandardTradeType == 0 || substandardTradeType == 1) && obj.StrikeOffset.HasValue)
{
codes.AddRange(query.Where(O =>
O.Strike != null &&
((O.IsMoneynessOption == "是" && Math.Abs((O.Strike ?? 0) - 1) > obj.StrikeOffset) ||
(O.IsMoneynessOption != "是" && Math.Abs((O.Strike ?? 0) / O.SpotPrice - 1) > obj.StrikeOffset)))
.Select(O => O.id).ToList());
}
if ((substandardTradeType == 0 || substandardTradeType == 2) && obj.MinTradingDay.HasValue)
{
codes.AddRange(query.ToList().Where(O => (O.ExerciseDate - O.TradeDate) < new TimeSpan(obj.MinTradingDay.Value, 0, 0, 0))
.Select(O => O.id).ToList());
}
if (obj.LockTradingDay.HasValue)
{
var queryTc = DbContext.trade_cash.Where(O => O.ValidState != ConsGlobal.InValid && !O.IsDeleted);
queryTc = TradeHelper.GetSettleTradeCash(queryTc);
var query1 = (from openTc in query
join closeTc in queryTc
on openTc.id equals closeTc.TradeId
select new { openTc.id, openDt = openTc.TradeDate, closeDt = closeTc.HappenedDate ?? closeTc.ValueDate })
.ToList().Where(O => (O.closeDt - O.openDt.Value).Days < obj.LockTradingDay);
closeTcDict = query1.AsEnumerable().GroupBy(O => O.id).ToDictionary(K => K.Key, V => V.First().closeDt);
if ((substandardTradeType == 0 || substandardTradeType == 3) && obj.LockTradingDay.HasValue)
{
codes.AddRange(query1.Select(O => O.id));
}
}
if (codes.Count == 0)
{
codes.Add(0);
}
return string.Join(",", codes);
}
protected IQueryable<trade> CreateTradeQuery(TradeReq req, TradeQueryRequest req2)
{
var predicate = CreateTradePredicate(req, req2);
var query = DbContext.trade.AsNoTracking().Where(predicate);
if (!string.IsNullOrEmpty(req.ContractCode))
{
query = from source in DbContext.trade
join tcrConfirm in DbContext.trade_contract_r.Where(aa => aa.Type == ContractTypeEnum.Trade && aa.IsValid) on new { id = source.ParentTradeId > 0 ? source.ParentTradeId : source.id } equals new { id = tcrConfirm.TradeId } into tcrConfirms
from tcrConfirm in tcrConfirms.DefaultIfEmpty()
where tcrConfirm.ContractCode.Contains(req.ContractCode)
select source;
}
if (req.UnWindTimes != null)
{
//根据了结日期,了结次数进行筛选
var tcGQuery = from tc in DbContext.trade_cash
where tc.ValidState != "Invalid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
group tc by tc.TradeId into tcg
select new
{
tid = tcg.Key,
UnWindTimes = tcg.Count()
};
var tcpGQuery = from tc in DbContext.trade_cash
where tc.ValidState != "Invalid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
group tc by tc.ParentTradeId into tcpg
select new
{
tid = tcpg.Key,
UnWindTimes = tcpg.Count()
};
if (req.UnWindTimes == 0)
{
var tdids = tcGQuery.Where(tg => tg.UnWindTimes >= 1).Select(n => n.tid);
var tdPids = tcpGQuery.Where(tg => tg.UnWindTimes >= 1).Select(n => n.tid);
query = query.Where(q => !tdids.Contains(q.id) && !tdPids.Contains(q.id));
}
else
{
query = from q in query
join tcg in tcGQuery on q.id equals tcg.tid into tcgs
from tcg in tcgs.DefaultIfEmpty()
join tcpg in tcpGQuery on q.id equals tcpg.tid into tcpgs
from tcpg in tcpgs.DefaultIfEmpty()
where tcg != null && tcg.UnWindTimes == req.UnWindTimes || tcpg != null && tcpg.UnWindTimes == req.UnWindTimes
select q;
}
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
query = query.OrderByDescending(s => s.OptDate);
return query;
}
protected IQueryable<trade> CreateTradeQueryWithGroup(TradeReq req, TradeQueryRequest req2)
{
var predicate = CreateTradePredicate(req, req2, true, req2.withGroupChildren);
//DbContext.SetDebugLog();
var query = DbContext.trade.AsNoTracking().Where(predicate);
//if (!string.IsNullOrEmpty(req.ContractCode))
//{
// query = from source in DbContext.trade
// join tcrConfirm in DbContext.trade_contract_r.Where(aa => aa.Type == ContractTypeEnum.Trade && aa.IsValid) on new { id = source.ParentTradeId > 0 ? source.ParentTradeId : source.id } equals new { id = tcrConfirm.TradeId } into tcrConfirms
// from tcrConfirm in tcrConfirms.DefaultIfEmpty()
// where tcrConfirm.ContractCode.Contains(req.ContractCode)
// select source;
//}
if (req.UnWindTimes != null)
{
//根据了结日期,了结次数进行筛选
var tcGQuery = from tc in DbContext.trade_cash.AsNoTracking()
where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
group tc by tc.TradeId into tcg
select new
{
tid = tcg.Key,
UnWindTimes = tcg.Count()
};
//var tcGQuery = from t in query
// join tc in DbContext.trade_cash.AsNoTracking()
// on t.id equals tc.TradeId
// where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
// select new
// {
// Trade = t,
// TradeCash = tc
// };
var tcpGQuery = from tc in DbContext.trade_cash.AsNoTracking()
where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
group tc by tc.ParentTradeId into tcpg
select new
{
tid = tcpg.Key,
UnWindTimes = tcpg.Count()
};
//var tcpGQuery = from t in query
// join tc in DbContext.trade_cash.AsNoTracking()
// on t.id equals tc.ParentTradeId
// where tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费")
// select t;
if (req.UnWindTimes == 0)
{
var tdids = tcGQuery.Union(tcpGQuery).Select(n => n.tid);
query = query.Where(q => !tdids.Contains(q.id));
}
else
{
//var tdids = tcGQuery.Where(tg => tg.UnWindTimes == req.UnWindTimes).Select(n => n.tid).ToHashSet();
//var tdPids = tcpGQuery.Where(tg => tg.UnWindTimes == req.UnWindTimes).Select(n => n.tid).ToHashSet();
query = from t in query
join tc in tcGQuery.Union(tcpGQuery)
on t.id equals tc.tid
where tc.UnWindTimes == req.UnWindTimes
select t;
//var ids = tdids.Union(tdPids).ToSearchList(req).rows.ToHashSet();
//query = query.Where(q => ids.Contains(q.id));
//query = query.Where(q => tdids.Contains(q.id) || tdPids.Contains(q.id));
}
}
if (req.TagIds != null && req.TagIds.Count > 0)
{
var tradeTagIdQuery = from tt in DbContext.trade_tag
where req.TagIds.Contains(tt.TagId)
select tt.TradeId;
query = query.Where(p => tradeTagIdQuery.Contains(p.id));
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
query = query.OrderByDescending(s => s.OptDate);
return query;
}
protected Expression<Func<trade, bool>> CreateTradePredicate(TradeReq req, TradeQueryRequest req2, bool withGroup = false, bool withGroupChildren = false)
{
if (req2 == null)
{
req2 = new TradeQueryRequest { };
}
var valueDate = valuedateBLL.ValueDate;
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && t.TradeType != "结构化交易");
if (withGroup)
{
if (withGroupChildren)
{
predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1));
}
else
{
predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2);
}
}
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(t => req.UserAssets.Contains(t.AssetId) || req.UserClients.Contains(t.ClientId));
}
//----------------交易ID----------------
if (!string.IsNullOrEmpty(req.TradeIds))
{
predicate = req2.StructureQueryFlag == StructureTradeQueryFlag.QueryMaster
? predicate.And(d => req.TradeIdList.Contains(d.id))
: predicate.And(d => req.TradeIdList.Contains(d.id) || req.TradeIdList.Contains(d.ParentTradeId));
if (req.onlyTradeIds)
{
return predicate;
}
}
//if (req.ParentTradeId.HasValue)
//{
// predicate = predicate.And(q => q.ParentTradeId == req.ParentTradeId.Value);
//}
//else
//{
// predicate = req2.StructureQueryFlag == StructureTradeQueryFlag.QueryMaster
// ? predicate.And(t => "结构化交易" != t.TradeType)
// : predicate.And(t => t.ParentTradeId == null || t.ParentTradeId == 0);
//}
//----------------行权方式----------------
if (!string.IsNullOrEmpty(req.ExerciseMode))
{
predicate = predicate.And(d => d.ExerciseMode.Contains(req.ExerciseMode));
}
//----------------交易标的----------------
if (!string.IsNullOrEmpty(req.UnderlyingAssetClass))
{
predicate = predicate.And(d => d.UnderlyingAssetClass.Contains(req.UnderlyingAssetClass));
}
if (!string.IsNullOrEmpty(req.UnderlyingInstrumentTypes))
{
predicate = predicate.And(d => req.UnderlyingInstrumentTypesList.Contains(d.UnderlyingInstrumentType));
}
if (req.UnderlyingId != null)
{
predicate = predicate.And(d => d.UnderlyingId == req.UnderlyingId);
}
if (!string.IsNullOrEmpty(req.UnderlyingIds))
{
predicate = predicate.And(d => req.UnderlyingIdsInt.Contains(d.UnderlyingId));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate = predicate.And(d => d.UnderlyingCode.Contains(req.UnderlyingCode));
}
if (req.UnderlyingCodeList != null && req.UnderlyingCodeList.Any())
{
predicate = predicate.And(d => req.UnderlyingCodeList.Contains(d.UnderlyingCode));
}
//--------------------------------
if (!string.IsNullOrEmpty(req.TraderNames))
{
predicate = predicate.And(d => req.TraderNamesList.Contains(d.TraderId));
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
var tradequery = DbContext.trade.Where(t => t.TradeNumber.Equals(req.TradeNumber));
predicate = predicate.And(d => d.TradeNumber.Contains(req.TradeNumber) || tradequery.Select(x => x.ParentTradeId).Contains(d.id) || tradequery.Select(x => x.ParentTradeId).Contains(d.ParentTradeId) && d.ParentTradeId > 0);
}
if (req.ClientId != null)
{
predicate = predicate.And(d => d.ClientId == req.ClientId);
}
if (!string.IsNullOrEmpty(req.ClientName))
{
predicate = predicate.And(d => d.ClientName.Contains(req.ClientName));
}
if (!string.IsNullOrEmpty(req.TradeType))
{
predicate = predicate.And(d => d.TradeType.Equals(req.TradeType));
}
if (!string.IsNullOrEmpty(req.StructureType))
{
predicate = predicate.And(d => d.StructureType.Contains(req.StructureType));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
predicate = predicate.And(d => d.BuySell.Contains(req.BuySell));
}
if (!string.IsNullOrEmpty(req.OptionType))
{
predicate = predicate.And(d => d.OptionType == req.OptionType);
}
if (req.StartDateStart != DateTime.MinValue)
{
predicate = predicate.And(d => d.StartDate >= req.StartDateStart);
}
if (req.StartDateEnd != DateTime.MinValue)
{
var StartDateTemp = req.StartDateEnd.AddDays(1);
predicate = predicate.And(d => d.StartDate < StartDateTemp);
}
if (!string.IsNullOrEmpty(req.OptIds))
{
predicate = predicate.And(d => req.OptIdsList.Contains(d.OptId + ""));
}
if (!string.IsNullOrEmpty(req.Comments))
{
predicate = predicate.And(d => d.Comments.Contains(req.Comments));
}
if (!string.IsNullOrEmpty(req.GroupNames))
{
predicate = predicate.And(d => req.GroupNamesList.Contains(d.GroupName));
}
//---------是否有配对交易---------
if (req.IsPairTrade == true)
{
predicate = predicate.And(q => !string.IsNullOrEmpty(q.PairTrade));
}
else if (req.IsPairTrade == false)
{
predicate = predicate.And(q => string.IsNullOrEmpty(q.PairTrade));
}
//---------了结日期---------
if (req.UnWindDateStart.HasValue)
{
predicate = predicate.And(t => t.UnWindDate >= req.UnWindDateStart);
}
if (req.UnWindDateEnd.HasValue)
{
predicate = predicate.And(t => t.UnWindDate <= req.UnWindDateEnd);
}
if (req.TagIds != null && req.TagIds.Count > 0)
{
var tradeTagIdQuery = from tt in DbContext.trade_tag
where req.TagIds.Contains(tt.TagId)
select tt.TradeId;
predicate = predicate.And(p => tradeTagIdQuery.Contains(p.id));
}
//----------------交易类型----------------
if (!string.IsNullOrEmpty(req.TradeTypes))
{
var typeList = req.TradeTypesList;
predicate = predicate.And(d => typeList.Contains(d.TradeType) || typeList.Contains(d.StructureType) || (typeList.Contains("黑箱结构") && d.IsGroup == 1));
}
switch (req.TabIndex)
{
case (int)TradeTabIndexEnum.今日成交:
predicate = predicate.And(d => d.ClientId > 0);
break;
case (int)TradeTabIndexEnum.场外成交记录:
predicate = predicate.And(d => d.ClientId > 0 && d.TradeType != "远期" && d.TradeType != "收益互换");
break;
case (int)TradeTabIndexEnum.场外衍生品交易:
predicate = predicate.And(d => d.TradeType == "远期");
break;
}
//获取当日成交的数据
//当日成交包括操作日期和交易日为当前系统日期的数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日成交)
{
var optDateStart = valueDate;
var optDateEnd = valueDate.AddDays(1);
var tradeDateStart = valueDate;
var tradeDateEnd = valueDate.AddDays(1);
predicate = predicate.And(d => (d.TradeDate >= tradeDateStart && d.TradeDate < tradeDateEnd) || (d.OptDate >= optDateStart && d.OptDate < tradeDateEnd));
}
else
{
if (req.TradeDateStart > DateTime.MinValue)
{
predicate = predicate.And(d => d.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd > DateTime.MinValue)
{
var TradeDateTemp = req.TradeDateEnd.AddDays(1);
predicate = predicate.And(d => d.TradeDate < TradeDateTemp);
}
if (req.OptDateStart > DateTime.MinValue)
{
predicate = predicate.And(d => d.OptDate >= req.OptDateStart);
}
if (req.OptDateEnd > DateTime.MinValue)
{
var OptDateTemp = req.OptDateEnd.AddDays(1);
predicate = predicate.And(d => d.OptDate < OptDateTemp);
}
}
//获取当日到期日数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日到期)
{
predicate = predicate.And(d => d.ExerciseDate == valueDate);
}
//获取明日到期日数据
else if (req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
var tommorow = QdpCalendarHelper.GetNonHoliday(valueDate.AddDays(1));
predicate = predicate.And(d => d.ExerciseDate == tommorow);
}
else
{
if (req2.IsExerciseDateReport)
{
predicate = predicate.And(d => d.ExerciseDate != null);
}
if (req.ExerciseDateStart.HasValue)
{
predicate = predicate.And(d => d.ExerciseDate >= req.ExerciseDateStart);
}
if (req.ExerciseDateEnd.HasValue)
{
predicate = predicate.And(d => d.ExerciseDate <= req.ExerciseDateEnd);
}
}
//过滤已平仓,已到期,已执行数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日到期 || req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
predicate = predicate.And(d => d.TradeStatus != ConsTrade.已平仓 && d.TradeStatus != ConsTrade.已到期 && d.TradeStatus != ConsTrade.已执行);
}
else if (!string.IsNullOrEmpty(req.TradeStatus))
{
var statuses = req.TradeStatus.Split(',').ToList();
predicate = predicate.And(d => statuses.Contains(d.TradeStatus));
}
else if (req.TradeStatusList != null && req.TradeStatusList.Any(n => !string.IsNullOrEmpty(n)))
{
predicate = predicate.And(d => req.TradeStatusList.Contains(d.TradeStatus));
}
if (!string.IsNullOrEmpty(req.OptName))
{
predicate = predicate.And(d => d.OptName.Contains(req.OptName));
}
//---------行权价---------
if (!string.IsNullOrEmpty(req.Strike))
{
double.TryParse(req.Strike, out var strike);
predicate = predicate.And(d => d.Strike == strike);
}
if (req.AssetIdList.Any())
{
predicate = predicate.And(d => req.AssetIdList.Contains(d.AssetId));
}
if (req.ClientIdsInt.Any())
{
predicate = predicate.And(d => req.ClientIdsInt.Contains(d.ClientId));
}
if (req.TradePrice != null)
{
predicate = predicate.And(d => req.TradePrice.Value == d.TradePrice);
}
return predicate;
}
protected Expression<Func<trade, bool>> CreateGroupActionPredicate(TradeReq req)
{
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && t.IsGroup == 1 && t.TradeType != "收益互换");
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(d => req.UserAssets.Contains(d.AssetId) || req.UserClients.Contains(d.ClientId));
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
var childquery = DbContext.trade.Where(t => t.TradeNumber.Equals(req.TradeNumber) && t.ParentTradeId != 0);
predicate = predicate.And(d => d.TradeNumber.Contains(req.TradeNumber) || childquery.Select(x => x.ParentTradeId).Contains(d.id));
}
if (req.ClientIdsInt.Any())
{
predicate = predicate.And(d => req.ClientIdsInt.Contains(d.ClientId));
}
return predicate;
}
}
public class TradeQueryRequest
{
/// <summary>
/// 显示所有交易
/// </summary>
public bool ShowAllTrades { get; set; }
/// <summary>
///
/// </summary>
public List<int> UserAssetUnits { get; set; }
/// <summary>
/// 结构化交易过滤选项
/// </summary>
public StructureTradeQueryFlag StructureQueryFlag { get; set; } = StructureTradeQueryFlag.QueryMaster;
/// <summary>
///
/// </summary>
public bool GetSum { get; set; }
/// <summary>
/// 是否来自行权报告
/// </summary>
public bool IsExerciseDateReport { get; set; }
public string VolType { get; set; }
public bool withGroupChildren { get; set; }
}
/// <summary>
/// 结构化交易过滤选项枚举
/// </summary>
public enum StructureTradeQueryFlag
{
/// <summary>
/// 只查询主交易
/// </summary>
QueryMaster = 1,
/// <summary>
/// 只查询子交易
/// </summary>
QuerySubs = 2
}
}