Files
zszq-trs/YLErpDAL/BLL/EodPnlBLL.cs
T
2024-05-09 14:06:26 +08:00

618 lines
28 KiB
C#

using BaseOUDAL;
using YLErp.BLL.Eod;
using YLErp.Configuration;
using YLErp.Model;
using YLErp.Modules;
namespace YLErp.BLL
{
public class EodPnlBLL
{
private readonly YLContext db = new YLContext();
public SearchListResult<EodPnlGroup> SearchListByGroupStr(EodPnlReq req, out EodPnlGridSum gsum, List<int> userAssetIds = null)
{
var query = from tpnl in db.eod_pnl
join tpos in db.eod_trade_position on new { tpnl.ValueDate, tpnl.TradeId } equals new { tpos.ValueDate, tpos.TradeId }
join td in db.trade on tpnl.TradeId equals td.id
select new EodPnlGroup
{
BookId = td.AssetId,
BookName = td.AssetBookName,
TradeType = td.TradeType,
UnderlyingAssetClass = td.UnderlyingAssetClass,
UnderlyingCode = td.UnderlyingCode,
ValueDate = tpnl.ValueDate,
TradeNumber = td.TradeNumber,
OptionType = td.OptionType,
BuySell = td.BuySell,
Strike = td.Strike,
MaturityDate = td.ExerciseDate,
Notional = td.Notional,
TraderId = td.TraderId,
LastPv = tpos.LastPv,
Pv = tpos.Pv,
DailyPnL = tpos.DailyPnL,
PnLPriceResidual = tpnl.PnLPriceResidual,
PnLVolResidual = tpnl.PnLVolResidual,
PnLPrice = tpnl.PnLPrice,
PnLDelta = tpnl.PnLDelta,
PnLGamma = tpnl.PnLGamma,
PnLVega = tpnl.PnLVega,
PnLTheta = tpnl.PnLTheta,
PnLVol = tpnl.PnLVol,
UnexplainedPnL = tpnl.UnexplainedPnL,
ExplainedPnL = tpnl.ExplainedPnL,
OptId = tpnl.OptId,
OptName = tpnl.OptName,
OptDate = tpnl.OptDate,
HedgeUniqueCode = tpnl.HedgeUniqueCode,
RealizedPnL = tpos.ClosedPnL,
PositionPnL = tpos.PositionPnL,
TotalPnl = tpos.TotalPnL,
AccruedTotalPnl = tpos.TotalPnL//该条件只能查询出场外期权的盈亏信息,场外期权的累积总盈亏就是该条交易的总盈亏;
};
//先按用户的权限限制,设置簿记账户
if (userAssetIds != null)
{
query = query.Where(x => userAssetIds.Contains(x.BookId.Value));
}
//如果查询指定了特定簿记账户,再过滤
if (null != req.BookId)
{
query = query.Where(d => d.BookId == req.BookId);
}
//过滤簿记账户
if (null != req.BookIds)
{
query = query.Where(d => req.BookIdList.Contains(d.BookId ?? 0));
}
if (null != req.TraderIds)
{
query = query.Where(d => req.TraderIdList.Contains(d.TraderId ?? 0));
}
if (req.ValueDate != DateTime.MinValue && req.ValueDate != null)
{
query = query.Where(d => d.ValueDate == req.ValueDate);
}
if (!string.IsNullOrEmpty(req.PositionType))
{
query = query.Where(d => d.PositionType.Equals(req.PositionType));
}
if (!string.IsNullOrEmpty(req.TradeTypes))
{
query = query.Where(d => req.TradeTypesList.Contains(d.TradeType));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
query = query.Where(d => req.UnderlyingCode.Equals(d.UnderlyingCode));
}
if (req.OptId != null)
{
query = query.Where(d => d.OptId == req.OptId);
}
if (!string.IsNullOrEmpty(req.OptName))
{
query = query.Where(d => d.OptName.Contains(req.OptName));
}
if (req.OptDateStart != DateTime.MinValue)
{
query = query.Where(d => d.OptDate >= req.OptDateStart);
}
if (req.OptDateEnd != DateTime.MinValue)
{
var OptDateTemp = req.OptDateEnd.AddDays(1);
query = query.Where(d => d.OptDate < OptDateTemp);
}
if (req.ValueDateStart != DateTime.MinValue)
{
if (req.ValueDateStart == req.ValueDateEnd)
{ query = query.Where(d => req.ValueDateStart == d.ValueDate); }
else { query = query.Where(d => req.ValueDateStart <= d.ValueDate); }
}
if (req.ValueDateEnd != DateTime.MinValue &&
req.ValueDateEnd != req.ValueDateStart)
{ query = query.Where(d => req.ValueDateEnd >= d.ValueDate); }
if (req.TradeNumberList != null)
{ query = query.Where(d => req.TradeNumberList.Contains(d.TradeNumber)); }
if (req.BookNameList != null)
{ query = query.Where(d => req.BookNameList.Contains(d.BookName)); }
if (req.LastPvStart != null)
{
if (req.LastPvStart == req.LastPvEnd)
{ query = query.Where(d => req.LastPvStart == d.LastPv); }
else { query = query.Where(d => req.LastPvStart <= d.LastPv); }
}
if (req.LastPvEnd != null && req.LastPvStart != req.LastPvEnd)
{ query = query.Where(d => req.LastPvEnd >= d.LastPv); }
if (req.PvStart != null)
{
if (req.PvStart == req.PvEnd)
{ query = query.Where(d => req.PvStart == d.Pv); }
else { query = query.Where(d => req.PvStart <= d.Pv); }
}
if (req.PvEnd != null && req.PvStart != req.PvEnd)
{ query = query.Where(d => req.PvEnd >= d.Pv); }
if (req.DailyPnLStart != null)
{
if (req.DailyPnLStart == req.DailyPnLEnd)
{ query = query.Where(d => req.DailyPnLStart == d.DailyPnL); }
else { query = query.Where(d => req.DailyPnLStart <= d.DailyPnL); }
}
if (req.DailyPnLEnd != null && req.DailyPnLStart != req.DailyPnLEnd)
{ query = query.Where(d => req.DailyPnLEnd >= d.DailyPnL); }
if (req.RealizedPnLStart != null)
{
if (req.RealizedPnLStart == req.RealizedPnLEnd)
{ query = query.Where(d => req.RealizedPnLStart == d.RealizedPnL); }
else { query = query.Where(d => req.RealizedPnLStart <= d.RealizedPnL); }
}
if (req.RealizedPnLEnd != null && req.RealizedPnLStart != req.RealizedPnLEnd)
{ query = query.Where(d => req.RealizedPnLEnd >= d.RealizedPnL); }
if (req.UnRealizedPnLStart != null)
{
if (req.UnRealizedPnLStart == req.UnRealizedPnLEnd)
{ query = query.Where(d => req.UnRealizedPnLStart == d.UnRealizedPnL); }
else { query = query.Where(d => req.UnRealizedPnLStart <= d.UnRealizedPnL); }
}
if (req.UnRealizedPnLEnd != null && req.UnRealizedPnLStart != req.UnRealizedPnLEnd)
{ query = query.Where(d => req.UnRealizedPnLEnd >= d.UnRealizedPnL); }
if (req.ActualPnLStart != null)
{
if (req.ActualPnLStart == req.ActualPnLEnd)
{ query = query.Where(d => req.ActualPnLStart == d.ActualPnL); }
else { query = query.Where(d => req.ActualPnLStart <= d.ActualPnL); }
}
if (req.ActualPnLEnd != null && req.ActualPnLStart != req.ActualPnLEnd)
{ query = query.Where(d => req.ActualPnLEnd >= d.ActualPnL); }
if (req.EstimatePnLStart != null)
{
if (req.EstimatePnLStart == req.EstimatePnLEnd)
{ query = query.Where(d => req.EstimatePnLStart == d.EstimatePnL); }
else { query = query.Where(d => req.EstimatePnLStart <= d.EstimatePnL); }
}
if (req.EstimatePnLEnd != null && req.EstimatePnLStart != req.EstimatePnLEnd)
{ query = query.Where(d => req.EstimatePnLEnd >= d.EstimatePnL); }
if (req.UnexplainedPnLStart != null)
{
if (req.UnexplainedPnLStart == req.UnexplainedPnLEnd)
{ query = query.Where(d => req.UnexplainedPnLStart == d.UnexplainedPnL); }
else { query = query.Where(d => req.UnexplainedPnLStart <= d.UnexplainedPnL); }
}
if (req.UnexplainedPnLEnd != null && req.UnexplainedPnLStart != req.UnexplainedPnLEnd)
{ query = query.Where(d => req.UnexplainedPnLEnd >= d.UnexplainedPnL); }
if (req.ExplainedPnLStart != null)
{
if (req.ExplainedPnLStart == req.ExplainedPnLEnd)
{ query = query.Where(d => req.ExplainedPnLStart == d.ExplainedPnL); }
else { query = query.Where(d => req.ExplainedPnLStart <= d.ExplainedPnL); }
}
if (req.ExplainedPnLEnd != null && req.ExplainedPnLStart != req.ExplainedPnLEnd)
{ query = query.Where(d => req.ExplainedPnLEnd >= d.ExplainedPnL); }
if (req.PositionPnLStart != null)
{
if (req.PositionPnLStart == req.PositionPnLEnd)
{ query = query.Where(d => req.PositionPnLStart == d.PositionPnL); }
else { query = query.Where(d => req.PositionPnLStart <= d.PositionPnL); }
}
if (req.PositionPnLEnd != null && req.PositionPnLStart != req.PositionPnLEnd)
{ query = query.Where(d => req.PositionPnLEnd >= d.PositionPnL); }
if (req.TotalPnlStart != null)
{
if (req.TotalPnlStart == req.TotalPnlEnd)
{ query = query.Where(d => req.TotalPnlStart == d.TotalPnl); }
else { query = query.Where(d => req.TotalPnlStart <= d.TotalPnl); }
}
if (req.TotalPnlEnd != null && req.TotalPnlStart != req.TotalPnlEnd)
{ query = query.Where(d => req.TotalPnlEnd >= d.TotalPnl); }
if (req.AccruedTotalPnlStart != null)
{
if (req.AccruedTotalPnlStart == req.AccruedTotalPnlEnd)
{ query = query.Where(d => req.AccruedTotalPnlStart == d.AccruedTotalPnl); }
else { query = query.Where(d => req.AccruedTotalPnlStart <= d.AccruedTotalPnl); }
}
if (req.AccruedTotalPnlEnd != null && req.AccruedTotalPnlStart != req.AccruedTotalPnlEnd)
{ query = query.Where(d => req.AccruedTotalPnlEnd >= d.AccruedTotalPnl); }
if (req.TradeTypeList != null)
{ query = query.Where(d => req.TradeTypeList.Contains(d.TradeType)); }
if (req.UnderlyingCodeList != null)
{ query = query.Where(d => req.UnderlyingCodeList.Contains(d.UnderlyingCode)); }
if (req.GroupStr != null)
{
var eodPnlList = query.ToList();
var resultList = new List<EodPnlGroup>();
List<EodPnlGroup> tempList = null;
EodPnlGroup tempObj = null;
if (eodPnlList != null)
{
eodPnlList.ForEach(t =>
{
if (resultList.Count == 0)
{
resultList.Add(t.Clone());
}
else
{
tempList = resultList;
if (req.GroupStr.Contains("标的代码"))
{
tempList = tempList.Where(a => a.UnderlyingCode == t.UnderlyingCode).ToList();
}
if (req.GroupStr.Contains("簿记账户"))
{
tempList = tempList.Where(a => a.BookName == t.BookName).ToList();
}
if (req.GroupStr.Contains("标的品种"))
{
tempList = tempList.Where(a => a.UnderlyingAssetClass == t.UnderlyingAssetClass).ToList();
}
if (req.GroupStr.Contains("结构类型"))
{
tempList = tempList.Where(a => a.TradeType == t.TradeType).ToList();
}
if (tempList != null && tempList.Count > 0)
{
tempObj = tempList.First();
tempObj.Aggregation(t);
}
else
{
resultList.Add(t.Clone());
}
}
});
}
IOrderedEnumerable<EodPnlGroup> orderSource = null;
if (req.GroupStr.Contains("簿记账户"))
{
orderSource = resultList.OrderBy(a => a.BookName);
}
if (req.GroupStr.Contains("标的品种"))
{
if (orderSource != null)
{
orderSource = orderSource.ThenBy(a => a.UnderlyingAssetClass);
}
else
{
orderSource = resultList.OrderBy(a => a.UnderlyingAssetClass);
}
}
if (req.GroupStr.Contains("标的代码"))
{
if (orderSource != null)
{
orderSource = orderSource.ThenBy(a => a.UnderlyingCode);
}
else
{
orderSource = resultList.OrderBy(a => a.UnderlyingCode);
}
}
if (req.GroupStr.Contains("结构类型"))
{
if (orderSource != null)
{
orderSource = orderSource.ThenBy(a => a.TradeType);
}
else
{
orderSource = resultList.OrderBy(a => a.TradeType);
}
}
resultList = orderSource.ToList();
if (req.rows == 0)
{
req.rows = 100000;
}
if (req.page <= 0)
{
req.page = 1;
}
var retListResult1 = new SearchListResult<EodPnlGroup>();
resultList = resultList.OrderBy(t => t.UnderlyingCode).ToList();
retListResult1.records = resultList.Count();
retListResult1.rows = resultList.Skip((req.page - 1) * req.rows).Take(req.rows).ToList();
retListResult1.page = req.page;
retListResult1.total = (retListResult1.records - 1) / req.rows + 1;
gsum = new EodPnlGridSum();
if (query.Any())
{
gsum.LastPvSum = query.Sum(q => q.LastPv);
gsum.PvSum = query.Sum(q => q.Pv);
gsum.DailyPnLSum = query.Sum(q => q.DailyPnL);
gsum.PnLPriceSum = query.Sum(q => q.PnLPrice);
gsum.PnLDeltaSum = query.Sum(q => q.PnLDelta);
gsum.PnLGammaSum = query.Sum(q => q.PnLGamma);
gsum.PnLVegaSum = query.Sum(q => q.PnLVega);
gsum.PnLThetaSum = query.Sum(q => q.PnLTheta);
gsum.PnLVolSum = query.Sum(q => q.PnLVol);
gsum.UnexplainedPnLSum = query.Sum(q => q.UnexplainedPnL);
gsum.ExplainedPnLSum = query.Sum(q => q.ExplainedPnL);
}
retListResult1.Sum = gsum;
return retListResult1;
}
else
{
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "UnderlyingCode";
req.sord = "desc";
}
var retListResult = BllExtension.ToSearchList<EodPnlGroup>(query, req);
gsum = new EodPnlGridSum();
if (query.Any())
{
gsum.LastPvSum = query.Sum(q => q.LastPv);
gsum.PvSum = query.Sum(q => q.Pv);
gsum.DailyPnLSum = query.Sum(q => q.DailyPnL);
gsum.PnLPriceSum = query.Sum(q => q.PnLPrice);
gsum.PnLDeltaSum = query.Sum(q => q.PnLDelta);
gsum.PnLGammaSum = query.Sum(q => q.PnLGamma);
gsum.PnLVegaSum = query.Sum(q => q.PnLVega);
gsum.PnLThetaSum = query.Sum(q => q.PnLTheta);
gsum.PnLVolSum = query.Sum(q => q.PnLVol);
gsum.UnexplainedPnLSum = query.Sum(q => q.UnexplainedPnL);
gsum.ExplainedPnLSum = query.Sum(q => q.ExplainedPnL);
}
retListResult.Sum = gsum;
return retListResult;
}
}
/// <summary>
/// 盯市报告持仓明细总数(除去互换交易)
/// </summary>
public int SearchPositionCount(int clientId, DateTime valueDate)
{
//if (IsBaseClient(clientId))
//{
// clientId = 0;
//}
if (valueDate > EodOperationBase.GetLastSettlementDate(DateTime.Now.Date))
{
var suspensionUnderlyingIdList = db.underlying_manager.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
var query = from trade in db.trade
where ConsTrade.NeedMarginTradeStatusList.Contains(trade.TradeStatus)
&& (trade.TradeType != "结构化交易" || trade.IsGroup == 1)
&& trade.IsGroup != 2
&& trade.TradeType != "收益互换"
&& (trade.ExerciseDate >= valueDate || suspensionUnderlyingIdList.Contains(trade.UnderlyingId))
&& trade.ValidState != "InValid" && !ConsTrade.TradeTypesForHedge.Contains(trade.TradeType)
&& (clientId == 0 || trade.ClientId == clientId)
select trade.id;
return query.Count();
}
else
{
var query = from trade in db.eod_trade
join tradeOrigin in db.trade on trade.TradeId equals tradeOrigin.id
where ConsTrade.NeedMarginTradeStatusList.Contains(trade.TradeStatus)
&& !ConsTrade.TradeTypesForHedge.Contains(trade.TradeType)
&& (tradeOrigin.TradeType != "结构化交易" || tradeOrigin.IsGroup == 1)
&& tradeOrigin.IsGroup != 2
&& tradeOrigin.TradeType != "收益互换"
&& trade.ValueDate == valueDate && (clientId == 0 || trade.ClientId == clientId)
select trade.id;
return query.Count();
}
}
/// <summary>
/// 盯市报告持仓明细互换总数
/// </summary>
/// <param name="clientId"></param>
/// <param name="valueDate"></param>
/// <returns></returns>
public int SearchSwapPositionCount(int clientId, DateTime valueDate)
{
//if (IsBaseClient(clientId))
//{
// clientId = 0;
//}
if (valueDate > EodOperationBase.GetLastSettlementDate(DateTime.Now.Date))
{
var suspensionUnderlyingIdList = db.underlying_manager.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
var query = from trade in db.trade
where ConsTrade.NeedMarginTradeStatusList.Contains(trade.TradeStatus)
&& trade.IsGroup != 1
&& trade.TradeType == "收益互换"
&& (trade.ExerciseDate >= valueDate || suspensionUnderlyingIdList.Contains(trade.UnderlyingId))
&& trade.ValidState != "InValid" && !ConsTrade.TradeTypesForHedge.Contains(trade.TradeType)
&& (clientId == 0 || trade.ClientId == clientId)
select trade.id;
return query.Count();
}
else
{
var query = from trade in db.eod_trade
join tradeOrigin in db.trade on trade.TradeId equals tradeOrigin.id
where ConsTrade.NeedMarginTradeStatusList.Contains(trade.TradeStatus)
&& !ConsTrade.TradeTypesForHedge.Contains(trade.TradeType)
&& tradeOrigin.IsGroup != 1
&& tradeOrigin.TradeType == "收益互换"
&& trade.ValueDate == valueDate && (clientId == 0 || trade.ClientId == clientId)
select trade.id;
return query.Count();
}
}
/// <summary>
/// 获取最新持仓列表信息
/// </summary>
public SearchListResult<eod_position> SearchLatestPositionList(TradeSpanReq req, out EodPnlGridSum gsum)
{
var suspensionUnderlyingIdList = db.underlying_manager.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
var query = from trade in db.trade
where ConsTrade.NeedMarginTradeStatusList.Contains(trade.TradeStatus)
&& (trade.ExerciseDate >= req.ValueDate || suspensionUnderlyingIdList.Contains(trade.UnderlyingId))
&& trade.ValidState != "InValid" && !ConsTrade.TradeTypesForHedge.Contains(trade.TradeType) && trade.ParentTradeId == 0
join underlying in db.underlying_manager on trade.UnderlyingId equals underlying.id
join risk in (from tr in db.realtime_trade_risk where tr.ValueDate == req.ValueDate && tr.VolType == "持仓" select tr) on trade.id equals risk.TradeId
into risks
from risk in risks.DefaultIfEmpty()
select new eod_position
{
TradeId = trade.id,
ClientId = trade.ClientId,
TradeNumber = trade.TradeNumber,
UnderlyingCode = trade.UnderlyingCode,
UnderlyingPrice = underlying.Price,
//tradeOrigin = trade,
ValueDate = req.ValueDate,
TradeJson = "",
Pv = 0,
Pnl = 0,
PvDouble = risk.Pv * -1,
PnlDouble = risk.Pnl * -1,
Vol = risk == null ? 0 : risk.Vol,
Delta = risk == null ? 0 : risk.Delta,
Gamma = risk == null ? 0 : risk.Gamma,
Theta = risk == null ? 0 : risk.Theta,
Vega = risk == null ? 0 : risk.Vega,
Rho = risk == null ? 0 : risk.Rho
};
//var isBaseClient = false;
if (req.ClientId != null)
{
//isBaseClient = IsBaseClient(req.ClientId.Value);
//if (!isBaseClient)
//{
query = query.Where(d => d.ClientId == req.ClientId);
//}
}
if (req.ValueDate != null && req.ValueDate != DateTime.MinValue)
{
query = query.Where(d => d.ValueDate == req.ValueDate);
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeNumber";
req.sord = "desc";
}
else
{
req.sidx = req.sidx.Split(' ')[0];
req.sord = "desc";
}
var retListResult = query.ToSearchList(req);
foreach (var x in retListResult.rows)
{
x.Pv = x.PvDouble;
x.Pnl = x.PnlDouble;
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(x.UnderlyingCode);
x.ContractSize = um?.ContractSize ?? 1;
}
////判断是否 平台方
//if (isBaseClient)
//{
// foreach (var x in retListResult.rows)
// {
// x.Pv = -x.Pv;
// x.Pnl = -x.Pnl;
// }
//}
gsum = new EodPnlGridSum();
if (retListResult.rows.Any())
{
gsum.PvSum = retListResult.rows.Sum(q => q.Pv);
gsum.DailyPnLSum = retListResult.rows.Sum(q => q.Pnl);
gsum.StockEqvNotionalSum = retListResult.rows.Sum(q => q.OriginalStockEqvNotional);
}
retListResult.Sum = gsum;
return retListResult;
}
/// <summary>
/// 判断是否 平台方客户(平台方配置的客户本身)
/// </summary>
public static bool IsBaseClient(int clientId)
{
using (var db = DbContextFactory.GetClientDbContext(null))
{
var baseName = PS.Config.CompanyFullName;
return db.client.Any(t => t.id == clientId && baseName.Equals(t.Name));
}
}
public List<eod_position> GetPositionList(TradeSpanReq req)
{
var eodTradeQuery = from eod_trade in db.eod_trade
where ConsTrade.NeedMarginTradeStatusList.Contains(eod_trade.TradeStatus) && eod_trade.ValueDate == req.ValueDate
select eod_trade;
var query = from tpos in db.eod_trade_position
join trade in eodTradeQuery on new { tpos.TradeId, tpos.ValueDate } equals new { trade.TradeId, trade.ValueDate }
join um in db.underlying_manager on trade.UnderlyingId equals um.id
select new eod_position
{
TradeId = trade.id,
ClientId = trade.ClientId,
TradeNumber = trade.TradeNumber,
UnderlyingCode = trade.UnderlyingCode,
UnderlyingPrice = um.Price,
Pv = tpos.Pv,
Pnl = tpos.DailyPnL,
ValueDate = tpos.ValueDate,
TradeJson = trade.TradeJson
};
if (req.ClientId != null)
{
query = query.Where(d => d.ClientId == req.ClientId);
}
if (req.ValueDate != null && req.ValueDate != DateTime.MinValue)
{
query = query.Where(d => d.ValueDate == req.ValueDate);
}
return query.ToList();
}
}
}