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

452 lines
24 KiB
C#

using BaseOUDAL;
using System.Data;
using YLErp.BLL.EodSettlement;
using YLErp.Commons;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.ClientModule;
namespace YLErp.Modules.TradeModule.QueryModule
{
/// <summary>
/// 历史交易查询服务(迁移自TradeBLL)
/// </summary>
public class TradeHistoryQueryService : YLBaseService
{
public TradeHistoryQueryService(YLBaseService baseService) : base(baseService)
{
}
public TradeHistoryQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 盯市报告历史交易总数
/// </summary>
public int SearchHistoryCount(TradeReq req)
{
return CreateTradeHistoryQuery(req).Count();
}
public List<trade_contract_group_simple> SearchHistoryListOnly(TradeReq req, bool isFromTradeMarketReport = false)
{
var query = CreateTradeHistoryQuery(req, isFromTradeMarketReport);
List<trade_contract_group_simple> retListResult = query.ToList();
retListResult.ForEach(x =>
{
var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1;
x.CountRatio = CountRatio;
if (x.trade_cash.IsLastAction)
{
if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1)
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
else if (x.trade.TradeType == "收益互换")
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
}
if (x.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
var tcTradeNotional = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
tcTradeNotional += y.UnwindNotional??0.0;
});
x.WinLoss = -(x.trade_cash.Amount + tcTradePrice);
x.trade_cash.UnwindNotional = tcTradeNotional;
}
if (x.TradeMultipleType == "现金流交易")
{
x.trade.OriginalNotional = null;
x.trade.TradeOriginalAmount = null;
x.trade_cash.TradeAmount = null;
x.trade_cash.UnwindTradeAmount = null;
}
});
return retListResult;
}
/// <summary>
/// 查询历史交易
/// </summary>
public SearchListResult<trade_contract_group_simple> SearchHistoryList(TradeReq req, out trade_contract_groupGridSum gsum)
{
var query = CreateTradeHistoryQuery(req);
var retListResult = query.ToSearchList(req, true);
var parentTradeIds = retListResult.rows.Select(x => x.trade.ParentTradeId).ToArray();
var parentTrades = DbContext.trade.Where(x => parentTradeIds.Contains(x.id)).ToArray();
foreach (var x in retListResult.rows)
{
//处理累计换月交易数据
new Modules.TradeModule.OptionTradeActionRestoreService(this.UserInfo).RestoreTradeDataToSpecialDay(x.trade, Convert.ToDateTime(req.ValueDateEnd));
var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1;
x.CountRatio = CountRatio;
if (!ConsTrade.TradeTypesForHedge.Contains(x.trade.TradeType))
{
x.trade.TradeOriginalAmount = x.trade.OriginalNotional / CountRatio;
}
//针对最后一次了结的记录,需要把存续的票息和互换金额算进最后一次的了结金额里
if (x.trade_cash.IsLastAction)
{
if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1)
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
else if (x.trade.TradeType == "收益互换")
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
}
if (x.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
});
x.WinLoss = -(x.trade_cash.Amount + tcTradePrice);
}
if (x.TradeMultipleType == "现金流交易")
{
x.trade.OriginalNotional = null;
x.trade.TradeOriginalAmount = null;
x.trade_cash.TradeAmount = null;
x.trade_cash.UnwindTradeAmount = null;
}
if (x.trade.IsGroup == 2 && x.trade.TradeType == "收益互换")
{
var parentTrade = parentTrades.FirstOrDefault(y => y.id == x.trade.ParentTradeId);
if (parentTrade != null)
{
x.trade.TradeNumber = parentTrade.TradeNumber;
}
}
if (PS.Config.ErpElement.IsSettlementReportAccOptionContainMultiplier && x.TradeType == "累计期权" && x.trade.trade_accumulator_option != null)
{
x.trade.trade_accumulator_option = DbContext.trade_accumulator_option.Where(l => l.TradeId == x.trade.id).FirstOrDefault();
// 累计了结时相应的乘数(标准累计:看涨乘数,看跌乘数;三段式:乘数1,乘数2,乘数3) 当乘数为0不处理
x.ACCMultiplier = ClientAssetDataService.GetTradeAccumulatorOptionMultiplier(x.trade, x.trade_cash.FinalPrice.Value, x.trade_cash.ValueDate);
}
x.trade.UnderlyingAssetName = x.trade.UnderlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.UnderlyingName;
x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate;
}
gsum = new trade_contract_groupGridSum();
if (query.Any())
{
var queryList = query.ToList();
foreach (var item in queryList)
{
if (item.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == item.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && item.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == item.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
});
item.WinLoss = -(item.trade_cash.Amount + tcTradePrice);
}
}
gsum.TradePriceSum =
queryList.Select(x =>
new
{
x.trade.id,
x.trade.TradePrice,
x.trade.BuySell,
x.trade.OptionType,
x.trade.TradeType
})
.Distinct().Sum(q =>
OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0) *
("卖出".Equals(q.BuySell) || q.TradeType == "远期" ? -1 : 1));
gsum.MinusAmountSum = queryList.Sum(q => -q.trade_cash.Amount).FormatValue(2);
gsum.StockEqvNotionalSum = queryList.Select(x => new { x.trade.id, x.trade.OriginalStockEqvNotional }).Distinct().Sum(q => Math.Round((q.OriginalStockEqvNotional ?? 0) * 100) / 100);
gsum.WinLossSum = queryList.Sum(n => n.WinLoss).FormatValue(2);
}
retListResult.Sum = gsum;
return retListResult;
}
private IQueryable<trade_contract_group_simple> CreateTradeHistoryQuery(TradeReq req, bool isFromTradeMarketReport = false)
{
var actionList = new[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费 };
var actionAllList = new[] { ClientCashInCashOut.系统操作_行权费, ClientCashInCashOut.系统操作_平仓费, ClientCashInCashOut.系统操作_期权费 };
IQueryable<trade_contract_group_simple> query;
if (isFromTradeMarketReport && PS.Config.Is申万)
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionAllList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id
where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null
};
}
else if (!req.IsHistoryWithUnconfirmed)
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings
from underlyingInfo in underlyings.DefaultIfEmpty()
join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets
from asset in assets.DefaultIfEmpty()
where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null,
UserGroup = asset.UserGroup
};
DbContext.SetDebugLog();
}
else
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 ) select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings
from underlyingInfo in underlyings.DefaultIfEmpty()
join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets
from asset in assets.DefaultIfEmpty()
where trade.ValidState != "InValid"
&& (tradeCash.ValidState != "InValid" || (trade.TradeStatus == "平仓待复核" && tradeCash.Action == ClientCashInCashOut.系统操作_平仓费) || (trade.TradeStatus == "行权待复核" && tradeCash.Action == ClientCashInCashOut.系统操作_行权费))
&& !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut.系统操作_平仓费 ? tradeCash.UnwindVol : null,
UserGroup = asset.UserGroup
};
}
//if (req.ClientId != null && !EodPnlBLL.IsBaseClient(req.ClientId.Value))
//{
//query = query.Where(d => d.trade.ClientId == req.ClientId);
//}
if (req.ClientId != null && req.ParentFlag)
{
var lists = ClientBalanceUtility.GetSubclientId(req.ClientId.Value);
query = query.Where(d => lists.Contains(d.trade.ClientId));
}
else if (req.ClientId != null && !req.ParentFlag)
{
query = query.Where(d => d.trade.ClientId == req.ClientId);
}
if (req.ValueDateStart.Year > 2000)
{
query = query.Where(d => d.trade_cash.ValueDate >= req.ValueDateStart && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate >= req.ValueDateStart);
}
if (req.ValueDateEnd.Year > 2000)
{
DateTime ValueDateTemp = req.ValueDateEnd.AddDays(1);
query = query.Where(d => d.trade_cash.ValueDate < ValueDateTemp && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate < ValueDateTemp);
}
if (!string.IsNullOrEmpty(req.ClientIds))
{
query = query.Where(d => req.ClientIdsInt.Contains(d.trade.ClientId));
}
if (!string.IsNullOrEmpty(req.TradeTypes))
{
query = query.Where(d => req.TradeTypesList.Contains(d.trade.TradeType) || req.TradeTypesList.Contains(d.trade.StructureType));
}
if (req.NotInTradeTypes != null && req.NotInTradeTypes.Any())
{
query = query.Where(d => !req.NotInTradeTypes.Contains(d.trade.TradeType));
}
if (!string.IsNullOrEmpty(req.UnderlyingIds))
{
query = query.Where(d => req.UnderlyingIdsInt.Contains(d.trade.UnderlyingId));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
query = query.Where(d => d.trade.BuySell.Contains(req.BuySell));
}
if (!string.IsNullOrEmpty(req.OptionType))
{
query = query.Where(d => d.trade.OptionType == req.OptionType);
}
if (!string.IsNullOrEmpty(req.ExerciseMode))
{
query = query.Where(d => d.trade.ExerciseMode == req.ExerciseMode);
}
if (req.TradeDateStart.Year > 2000)
{
query = query.Where(d => d.trade.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd.Year > 2000)
{
DateTime TradeDateTemp = req.TradeDateEnd.AddDays(1);
query = query.Where(d => d.trade.TradeDate < TradeDateTemp);
}
if (req.TabIndex == (int)TradeTabIndexEnum.今日终止)
{
//已平仓,部分平仓,美式期权提前行权
if (req.IsHistoryWithUnconfirmed)
{
query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut.系统操作_平仓费 ||
((d.trade.TradeStatus == ConsTrade.已执行 || d.trade.TradeStatus == ConsTrade.行权待复核) && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权"));
}
else
{
query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut.系统操作_平仓费 ||
(d.trade.TradeStatus == ConsTrade.已执行 && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权"));
}
}
if (req.ExerciseDateStart != null || req.ExerciseDateEnd != null)
{
if (req.ExerciseDateEnd == null)
{
req.ExerciseDateEnd = DateTime.MaxValue;
}
if (req.ExerciseDateStart == null)
{
req.ExerciseDateStart = DateTime.MinValue;
}
//股票的到期日为null
query = query.Where(d => string.IsNullOrEmpty(d.trade.ExerciseMode) || d.trade.ExerciseDate == null ||
((d.trade.ExerciseMode == "European" && d.trade.ExerciseDate >= req.ExerciseDateStart &&
d.trade.ExerciseDate <= req.ExerciseDateEnd)
|| (d.trade.ExerciseMode == "American" &&
((d.trade.ExerciseDate >= req.ExerciseDateStart &&
d.trade.ExerciseDate <= req.ExerciseDateEnd)
|| (d.trade.StartDate >= req.ExerciseDateStart &&
d.trade.StartDate <= req.ExerciseDateEnd)
|| (d.trade.StartDate <= req.ExerciseDateStart &&
d.trade.ExerciseDate >= req.ExerciseDateEnd)
))
));
}
if (!string.IsNullOrEmpty(req.TradeStatus))
{
List<string> statuses = req.TradeStatus.Split(',').ToList();
query = query.Where(d => statuses.Contains(d.trade.TradeStatus));
}
if (req.TradeStatusList != null)
{
query = query.Where(d => req.TradeStatusList.Contains(d.trade.TradeStatus));
}
if (!string.IsNullOrEmpty(req.TraderNames))
{
query = query.Where(d => req.TraderNamesList.Contains(d.trade.TraderId));
}
if (req.AssetIdList.Any())
{
query = query.Where(d => req.AssetIdList.Contains(d.trade.AssetId));
}
if (string.IsNullOrEmpty(req.sidx))
{
query = query.OrderBy(n => n.trade.UnderlyingInstrumentType).ThenByDescending(s => s.trade_cash.id);
}
else if (req.sidx == "trade_cash.ValueDateString")
{
req.sidx = "trade_cash.ValueDate";
}
else
{
query = query.OrderBy(n => n.trade.UnderlyingInstrumentType);
}
return query;
}
}
}