1252 lines
59 KiB
C#
1252 lines
59 KiB
C#
using BaseOUDAL;
|
|
using NPOI.SS.Formula.Functions;
|
|
using System.Data;
|
|
using YLErp.BLL.Eod;
|
|
using YLErp.BLL.EodSettlement;
|
|
using YLErp.Commons;
|
|
using YLErp.DBModels.Consts;
|
|
using YLErp.Model;
|
|
using YLErp.Modules.DataProviderModule;
|
|
using YLErp.Modules.SwapModule;
|
|
using YLErp.Modules.TradeModule;
|
|
using YLErp.QdpModule;
|
|
|
|
namespace YLErp.Modules.ClientModule
|
|
{
|
|
/// <summary>
|
|
/// 客户持仓查询服务
|
|
/// </summary>
|
|
public class ClientPositionQueryService : YLBaseService
|
|
{
|
|
public ClientPositionQueryService(YLBaseService baseService) : base(baseService)
|
|
{
|
|
}
|
|
|
|
public ClientPositionQueryService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// 是否需要确认书合约号,默认true
|
|
/// </summary>
|
|
public bool NeedTradeContractCode { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// API:获取客户持仓
|
|
/// </summary>
|
|
public SearchListResult<eod_position> GetClientPositionAPI(DateTime valueDate, int clientId, int page, int pageRowCount)
|
|
{
|
|
var list = SearchPositionList(new TradeSpanReq
|
|
{
|
|
ValueDate = valueDate,
|
|
ClientId = clientId,
|
|
page = page,
|
|
rows = pageRowCount
|
|
}, null);
|
|
|
|
foreach (var item in list.rows)
|
|
{
|
|
item.Variety = new Variety2
|
|
{
|
|
TradeUnitValue = UnderlyingDataProvider.GetUnderlying(item.UnderlyingCode)?.ContractSize ?? 1
|
|
};
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查询所有客户持仓数据
|
|
/// </summary>
|
|
public List<eod_position> SearchPositionListAll(TradeSpanReq req, IEnumerable<int> userAssetUnits)
|
|
{
|
|
if (!req.ValueDate.HasValue)
|
|
{
|
|
throw new ServiceException("缺少参数:请求日期");
|
|
}
|
|
|
|
IQueryable<eod_position> query = null;
|
|
|
|
var ireq = CreateReq(req, userAssetUnits);
|
|
|
|
var isTodayQuery = ireq.isTodayQuery;
|
|
|
|
if (isTodayQuery)
|
|
{
|
|
query = CreateTodayQuery(ireq);
|
|
}
|
|
else
|
|
{
|
|
query = CreateEodQuery(ireq);
|
|
}
|
|
|
|
//国投要求默认按成交日正序
|
|
if (string.IsNullOrEmpty(req.sidx) && PS.Config.Is国投)
|
|
{
|
|
query = query.OrderBy(n => n.TradeDate).ThenByDescending(n => n.TradeNumber);
|
|
}
|
|
//国君要求先查期货后查权益类
|
|
else if (string.IsNullOrEmpty(req.sidx))
|
|
{
|
|
query = query.OrderBy(n => n.InstrumentType).ThenByDescending(n => n.TradeNumber);
|
|
}
|
|
else
|
|
{
|
|
req.sidx = req.sidx.Split(' ')[0];
|
|
if (string.IsNullOrEmpty(req.sord))
|
|
{
|
|
req.sord = "desc";
|
|
}
|
|
query.SortBy($"{nameof(eod_position.InstrumentType)},{req.sidx} {req.sord}");
|
|
}
|
|
|
|
var queryList = query.ToList();
|
|
SwapEodPositionService swapEodPositionService = new SwapEodPositionService(this);
|
|
queryList.AddRange(swapEodPositionService.GetSwapPositions(req.ClientId??0,req.ValueDate.Value));
|
|
var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource();
|
|
|
|
new TradeExtendService(this).SetTradeExtendWithCnKey(queryList.Select(x => x.trade).ToArray(), true, req.ValueDate);
|
|
|
|
var eodPriceProvider = new Lazy<EodPriceProvider>(() => new EodPriceProvider(req.ValueDate.Value).Initialize());
|
|
var xmxyUseSettlePrice = PS.Config.Is厦门象屿 && req.ValueDate.Value > new DateTime(2021, 12, 30);
|
|
|
|
Dictionary<int, string> contractCodeDic = null;
|
|
if (NeedTradeContractCode)
|
|
{
|
|
var tids = queryList.Select(n => n.TradeId).ToArray();
|
|
var q2 = from aa in DbContext.trade_contract_r
|
|
where tids.Contains(aa.TradeId) && aa.Type == ContractTypeEnum.Trade && aa.IsValid
|
|
orderby aa.id descending
|
|
select new { aa.TradeId, aa.ContractCode };
|
|
contractCodeDic = CollectionHelper.ToDictionary2(q2.ToArray(), n => n.TradeId, n => n.ContractCode);
|
|
}
|
|
|
|
foreach (var x in queryList)
|
|
{
|
|
var um = underlyingDataSource.GetData(x.UnderlyingCode);
|
|
|
|
if (um != null)
|
|
{
|
|
x.CountRatio = um.CountRatio;
|
|
x.ContractSize = um.ContractSize;
|
|
x.QuoteUnitSingle = um.QuoteUnitString;
|
|
x.MarketCode = um.MarketCode;
|
|
x.BBGTicker = um.BBGTicker;
|
|
|
|
//if (isTodayQuery)
|
|
//{
|
|
// x.UnderlyingPrice = um.Price;
|
|
//}
|
|
|
|
if (um.IsSynthetic())
|
|
{
|
|
var sy = underlyingDataSource.GetSyntheticUnderlying(x.UnderlyingCode);
|
|
if (sy != null)
|
|
{
|
|
x.SyntheticUnderlyingTipsInfo = sy.UnderlyingTipsInfo;
|
|
}
|
|
}
|
|
else if (isTodayQuery && um.IsBasket())
|
|
{
|
|
underlyingDataSource.TryGetPrice(x.UnderlyingCode, out var price);
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
x.CountRatio = 1;
|
|
x.ContractSize = 1;
|
|
x.QuoteUnitSingle = "";
|
|
}
|
|
|
|
if (isTodayQuery)
|
|
{
|
|
if (x.IsGroup == 1)
|
|
{
|
|
var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList();
|
|
var childRisks = DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == ireq.valueDate && tr.VolType == "持仓" && childTradeIds.Contains(tr.TradeId ?? 0)).ToList();
|
|
var childPositions = DbContext.intraday_trade_position.Where(tr => tr.ValueDate == ireq.valueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
x.PvDouble = childRisks.Sum(y => -y.Pv);
|
|
x.RoundedPvDouble = childRisks.Sum(y => -y.RoundedPv);
|
|
x.PnlDouble = childRisks.Sum(y => -y.PositionPnl);
|
|
x.RoundedPnlDouble = childRisks.Sum(y => -y.RoundedPositionPnl);
|
|
x.Margin = childPositions.Sum(y => y.Margin);
|
|
x.Delta = childRisks.Sum(y => y.Delta);
|
|
x.Gamma = childRisks.Sum(y => y.Gamma);
|
|
x.Vega = childRisks.Sum(y => y.Vega);
|
|
x.Theta = childRisks.Sum(y => y.Theta);
|
|
x.Rho = childRisks.Sum(y => y.Rho);
|
|
x.GammaCash = childRisks.Sum(y => y.GammaCash);
|
|
}
|
|
|
|
x.Pv = x.PvDouble;
|
|
x.RoundedPv = x.RoundedPvDouble;
|
|
x.Pnl = x.PnlDouble;
|
|
x.RoundedPnl = x.RoundedPnlDouble;
|
|
}
|
|
else
|
|
{
|
|
if (x.IsGroup == 1)
|
|
{
|
|
var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList();
|
|
|
|
if (PS.Config.Is格林大华 || PS.Config.Is伴兴)
|
|
{
|
|
var childEodPositions = DbContext.eod_trade_position_extend.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
var eodTradeRisks = DbContext.eod_trade_risk_extend.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
x.Pv = childEodPositions.Sum(y => -y.Pv);
|
|
x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv);
|
|
x.Pnl = childEodPositions.Sum(y => -y.PositionPnL);
|
|
x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL);
|
|
x.Margin = childEodPositions.Sum(y => y.Margin);
|
|
x.Delta = eodTradeRisks.Sum(y => y.Delta);
|
|
x.Gamma = eodTradeRisks.Sum(y => y.Gamma);
|
|
x.Vega = eodTradeRisks.Sum(y => y.Vega);
|
|
x.Theta = eodTradeRisks.Sum(y => y.Theta);
|
|
x.Rho = eodTradeRisks.Sum(y => y.Rho);
|
|
x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash);
|
|
}
|
|
else if (PS.Config.Is广发商贸)
|
|
{
|
|
var childEodPositions = DbContext.eod_trade_position_hedgevol.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
var eodTradeRisks = DbContext.eod_trade_risk_hedgevol.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
x.Pv = childEodPositions.Sum(y => -y.Pv);
|
|
x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv);
|
|
x.Pnl = childEodPositions.Sum(y => -y.PositionPnL);
|
|
x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL);
|
|
x.Margin = childEodPositions.Sum(y => y.Margin);
|
|
x.Delta = eodTradeRisks.Sum(y => y.Delta);
|
|
x.Gamma = eodTradeRisks.Sum(y => y.Gamma);
|
|
x.Vega = eodTradeRisks.Sum(y => y.Vega);
|
|
x.Theta = eodTradeRisks.Sum(y => y.Theta);
|
|
x.Rho = eodTradeRisks.Sum(y => y.Rho);
|
|
x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash);
|
|
}
|
|
else
|
|
{
|
|
var childEodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
var eodTradeRisks = DbContext.eod_trade_risk.Where(tr => tr.ValueDate == ireq.lastValueDate && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
x.Pv = childEodPositions.Sum(y => -y.Pv);
|
|
x.RoundedPv = childEodPositions.Sum(y => -y.RoundedPv);
|
|
x.Pnl = childEodPositions.Sum(y => -y.PositionPnL);
|
|
x.RoundedPnl = childEodPositions.Sum(y => -y.RoundedPositionPnL);
|
|
x.Margin = childEodPositions.Sum(y => y.Margin);
|
|
x.Delta = eodTradeRisks.Sum(y => y.Delta);
|
|
x.Gamma = eodTradeRisks.Sum(y => y.Gamma);
|
|
x.Vega = eodTradeRisks.Sum(y => y.Vega);
|
|
x.Theta = eodTradeRisks.Sum(y => y.Theta);
|
|
x.Rho = eodTradeRisks.Sum(y => y.Rho);
|
|
x.GammaCash = eodTradeRisks.Sum(y => y.GammaCash);
|
|
}
|
|
|
|
x.PvDouble = x.Pv;
|
|
x.RoundedPvDouble = x.RoundedPv;
|
|
x.PnlDouble = x.Pnl;
|
|
x.RoundedPnlDouble = x.RoundedPnl;
|
|
}
|
|
}
|
|
|
|
if (PS.Config.IsGuoJun)
|
|
{
|
|
var dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate, -1);
|
|
if (isTodayQuery)
|
|
{
|
|
dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate);
|
|
}
|
|
if (x.IsGroup == 1)
|
|
{
|
|
var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList();
|
|
var childEodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && childTradeIds.Contains(tr.TradeId)).ToList();
|
|
x.ChangeMargin = x.Margin - childEodPositions.Sum(y => y.Margin);
|
|
}
|
|
else
|
|
{
|
|
var EodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && tr.TradeId == x.TradeId).ToList();
|
|
x.ChangeMargin = x.Margin - EodPositions.Sum(y => y.Margin);
|
|
}
|
|
}
|
|
|
|
if (PS.Config.Is厦门象屿)
|
|
{
|
|
if (x.IsGroup == 1)
|
|
{
|
|
var childTradeIds = DbContext.trade.Where(y => y.ParentTradeId == x.TradeId && y.ValidState != "InValid").Select(y => y.id).ToList();
|
|
var tradespan = DbContext.trade_span.Where(o => o.ValueDate == ireq.valueDate && childTradeIds.Contains(o.TradeId)).ToList();
|
|
x.MaxlossMargin = tradespan.Sum(y => y.MaxlossMargin);
|
|
}
|
|
else
|
|
{
|
|
var tradespan = DbContext.trade_span.Where(o => o.TradeId == x.TradeId && o.ValueDate == ireq.valueDate)?.FirstOrDefault();
|
|
x.MaxlossMargin = tradespan?.MaxlossMargin;
|
|
}
|
|
|
|
if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode
|
|
, xmxyUseSettlePrice ? SettlementTypeEnum.SettlePrice : x.SettlementType, out var price))
|
|
{
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
}
|
|
else if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode, x.SettlementType, out var price))
|
|
{
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
|
|
if (x.IsGroup == 1)
|
|
{
|
|
var parentTradeCashIds = DbContext.trade_cash.Where(t => (t.Action == "系统操作-票息" || t.Action == "系统操作-互换") && t.ValidState != "InValid" && t.ValueDate <= req.ValueDate && t.TradeId == x.TradeId && !t.IsLastAction).Select(y => y.id).ToArray();
|
|
var childTradeCashs = DbContext.trade_cash.Where(t => parentTradeCashIds.Contains(t.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.PositionRelizedAmount = -((childTradeCashs.Sum(y => (double?)y.Amount) ?? 0) + tcTradePrice);
|
|
}
|
|
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(x.ClientId ?? 0);
|
|
if (client != null)
|
|
{
|
|
x.ClientName = client.Name;
|
|
x.MarginOptionType = client.MarginOptionType;
|
|
}
|
|
|
|
x.dic = x.trade.MetaDic;
|
|
|
|
if (x.TradeMultipleType == "现金流交易")
|
|
{
|
|
x.trade.OriginalNotional = null;
|
|
}
|
|
x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate;
|
|
|
|
if (contractCodeDic != null && contractCodeDic.TryGetValue(x.TradeId, out var contractCode))
|
|
{
|
|
x.TradeContractCode = contractCode;
|
|
}
|
|
|
|
if (PS.Config.Is广发商贸)
|
|
{
|
|
var eps = DbContext.eod_trade_position.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate);
|
|
x.Margin = eps == null ? 0 : eps.Margin;
|
|
var erisk = DbContext.eod_trade_risk.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate);
|
|
x.Vol = erisk == null ? 0 : erisk.Vol;
|
|
}
|
|
}
|
|
|
|
return queryList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 查询所有客户持仓数据
|
|
/// </summary>
|
|
public List<eod_position> SearchPositionChildrenListAll(TradeSpanReq req, IEnumerable<int> userAssetUnits)
|
|
{
|
|
if (!req.ValueDate.HasValue)
|
|
{
|
|
throw new ServiceException("缺少参数:请求日期");
|
|
}
|
|
|
|
IQueryable<eod_position> query = null;
|
|
|
|
var ireq = CreateReq(req, userAssetUnits);
|
|
|
|
var isTodayQuery = ireq.isTodayQuery;
|
|
|
|
if (isTodayQuery)
|
|
{
|
|
query = CreateTodayChildrenQuery(ireq);
|
|
}
|
|
else
|
|
{
|
|
query = CreateEodChildrenQuery(ireq);
|
|
}
|
|
|
|
//国投要求默认按成交日正序
|
|
if (string.IsNullOrEmpty(req.sidx) && PS.Config.Is国投)
|
|
{
|
|
query = query.OrderBy(n => n.TradeDate).ThenByDescending(n => n.TradeNumber);
|
|
}
|
|
//国君要求先查期货后查权益类
|
|
else if (string.IsNullOrEmpty(req.sidx))
|
|
{
|
|
query = query.OrderBy(n => n.InstrumentType).ThenByDescending(n => n.TradeNumber);
|
|
}
|
|
else
|
|
{
|
|
req.sidx = req.sidx.Split(' ')[0];
|
|
if (string.IsNullOrEmpty(req.sord))
|
|
{
|
|
req.sord = "desc";
|
|
}
|
|
query.SortBy($"{nameof(eod_position.InstrumentType)},{req.sidx} {req.sord}");
|
|
}
|
|
|
|
var queryList = query.ToList();
|
|
var underlyingDataSource = DataCacheProvider.GetUnderlyingDataSource();
|
|
|
|
new TradeExtendService(this).SetTradeExtendWithCnKey(queryList.Select(x => x.trade).ToArray(), true, req.ValueDate);
|
|
|
|
var eodPriceProvider = new Lazy<EodPriceProvider>(() => new EodPriceProvider(req.ValueDate.Value).Initialize());
|
|
var xmxyUseSettlePrice = PS.Config.Is厦门象屿 && req.ValueDate.Value > new DateTime(2021, 12, 30);
|
|
|
|
Dictionary<int, string> contractCodeDic = null;
|
|
if (NeedTradeContractCode)
|
|
{
|
|
var tids = queryList.Select(n => n.TradeId).ToArray();
|
|
var q2 = from aa in DbContext.trade_contract_r
|
|
where tids.Contains(aa.TradeId) && aa.Type == ContractTypeEnum.Trade && aa.IsValid
|
|
orderby aa.id descending
|
|
select new { aa.TradeId, aa.ContractCode };
|
|
contractCodeDic = CollectionHelper.ToDictionary2(q2.ToArray(), n => n.TradeId, n => n.ContractCode);
|
|
}
|
|
|
|
foreach (var x in queryList)
|
|
{
|
|
var um = underlyingDataSource.GetData(x.UnderlyingCode);
|
|
|
|
if (um != null)
|
|
{
|
|
x.CountRatio = um.CountRatio;
|
|
x.ContractSize = um.ContractSize;
|
|
x.QuoteUnitSingle = um.QuoteUnitString;
|
|
x.MarketCode = um.MarketCode;
|
|
x.BBGTicker = um.BBGTicker;
|
|
|
|
if (um.IsSynthetic())
|
|
{
|
|
var sy = underlyingDataSource.GetSyntheticUnderlying(x.UnderlyingCode);
|
|
if (sy != null)
|
|
{
|
|
x.SyntheticUnderlyingTipsInfo = sy.UnderlyingTipsInfo;
|
|
}
|
|
}
|
|
else if (isTodayQuery && um.IsBasket())
|
|
{
|
|
underlyingDataSource.TryGetPrice(x.UnderlyingCode, out var price);
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
x.CountRatio = 1;
|
|
x.ContractSize = 1;
|
|
x.QuoteUnitSingle = "";
|
|
}
|
|
|
|
if (isTodayQuery)
|
|
{
|
|
x.Pv = x.PvDouble;
|
|
x.RoundedPv = x.RoundedPvDouble;
|
|
x.Pnl = x.PnlDouble;
|
|
x.RoundedPnl = x.RoundedPnlDouble;
|
|
}
|
|
|
|
if (PS.Config.IsGuoJun)
|
|
{
|
|
var dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate, -1);
|
|
if (isTodayQuery)
|
|
{
|
|
dt = QdpCalendarHelper.BizDayShift(ireq.lastValueDate);
|
|
}
|
|
|
|
var EodPositions = DbContext.eod_trade_position.Where(tr => tr.ValueDate == dt && tr.TradeId == x.TradeId).ToList();
|
|
x.ChangeMargin = x.Margin - EodPositions.Sum(y => y.Margin);
|
|
}
|
|
|
|
if (PS.Config.Is厦门象屿)
|
|
{
|
|
var tradespan = DbContext.trade_span.Where(o => o.TradeId == x.TradeId && o.ValueDate == ireq.valueDate)?.FirstOrDefault();
|
|
x.MaxlossMargin = tradespan?.MaxlossMargin;
|
|
|
|
if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode
|
|
, xmxyUseSettlePrice ? SettlementTypeEnum.SettlePrice : x.SettlementType, out var price))
|
|
{
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
}
|
|
else if (!isTodayQuery && eodPriceProvider.Value.TryGetPrice(x.UnderlyingCode, x.SettlementType, out var price))
|
|
{
|
|
x.UnderlyingPrice = price;
|
|
}
|
|
|
|
var client = DataCacheProvider.GetClientDataSource().GetData(x.ClientId ?? 0);
|
|
if (client != null)
|
|
{
|
|
x.ClientName = client.Name;
|
|
x.MarginOptionType = client.MarginOptionType;
|
|
}
|
|
|
|
x.dic = x.trade.MetaDic;
|
|
|
|
if (x.TradeMultipleType == "现金流交易")
|
|
{
|
|
x.trade.OriginalNotional = null;
|
|
}
|
|
x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate;
|
|
|
|
if (contractCodeDic != null && contractCodeDic.TryGetValue(x.TradeId, out var contractCode))
|
|
{
|
|
x.TradeContractCode = contractCode;
|
|
}
|
|
|
|
if (PS.Config.Is广发商贸)
|
|
{
|
|
var eps = DbContext.eod_trade_position.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate);
|
|
x.Margin = eps == null ? 0 : eps.Margin;
|
|
var erisk = DbContext.eod_trade_risk.FirstOrDefault(n => n.TradeId == x.TradeId && n.ValueDate == req.ValueDate);
|
|
x.Vol = erisk == null ? 0 : erisk.Vol;
|
|
}
|
|
}
|
|
|
|
return queryList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据ValueDate获取客户持仓
|
|
/// </summary>
|
|
public SearchListResult<eod_position> SearchPositionList(TradeSpanReq req, IEnumerable<int> userAssetUnits)
|
|
{
|
|
var queryList = SearchPositionListAll(req, userAssetUnits);
|
|
|
|
var gsum = new EodPnlGridSum();
|
|
|
|
if (queryList.Any())
|
|
{
|
|
gsum.PvSum = queryList.Sum(q => q.Pv);
|
|
gsum.RoundedPvSum = queryList.Sum(q => q.RoundedPv);
|
|
gsum.DailyPnLSum = queryList.Sum(q => q.Pnl);
|
|
gsum.RoundedDailyPnLSum = queryList.Sum(q => q.RoundedPnl);
|
|
gsum.OriginalStockEqvNotionalSum = queryList.Sum(q => q.OriginalStockEqvNotional);
|
|
gsum.StockEqvNotionalSum = queryList.Sum(q => q.StockEqvNotional);
|
|
gsum.TradePriceSum = queryList.Sum(q => OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0));
|
|
gsum.MarginSum = queryList.Sum(q => q.Margin);
|
|
}
|
|
|
|
var searchList = queryList.AsQueryable().ToSearchList(req);
|
|
var tradeIds = searchList.rows.Select(x => x.TradeId).ToList();
|
|
foreach (var item in searchList.rows)
|
|
{
|
|
item.trade.TradeSinglePrice = item.trade.TradeSinglePrice.IsNormalize() ? Math.Abs(item.trade.TradeSinglePrice.Value) : item.trade.TradeSinglePrice;
|
|
//处理累计换月交易数据
|
|
new OptionTradeActionRestoreService(UserInfo).RestoreTradeDataToSpecialDay(item.trade, Convert.ToDateTime(req.ValueDate));
|
|
item.CountRatio = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1;
|
|
}
|
|
|
|
searchList.Sum = gsum;
|
|
return searchList;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 根据ValueDate获取客户持仓
|
|
/// </summary>
|
|
public SearchListResult<eod_position> SearchPositionChildrenList(TradeSpanReq req, IEnumerable<int> userAssetUnits)
|
|
{
|
|
var queryList = SearchPositionChildrenListAll(req, userAssetUnits);
|
|
|
|
var gsum = new EodPnlGridSum();
|
|
|
|
if (queryList.Any())
|
|
{
|
|
gsum.PvSum = queryList.Sum(q => q.Pv);
|
|
gsum.RoundedPvSum = queryList.Sum(q => q.RoundedPv);
|
|
gsum.DailyPnLSum = queryList.Sum(q => q.Pnl);
|
|
gsum.RoundedDailyPnLSum = queryList.Sum(q => q.RoundedPnl);
|
|
gsum.OriginalStockEqvNotionalSum = queryList.Sum(q => q.OriginalStockEqvNotional);
|
|
gsum.StockEqvNotionalSum = queryList.Sum(q => q.StockEqvNotional);
|
|
gsum.TradePriceSum = queryList.Sum(q => OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0));
|
|
gsum.MarginSum = queryList.Sum(q => q.Margin);
|
|
}
|
|
|
|
var searchList = queryList.AsQueryable().ToSearchList(req);
|
|
var tradeIds = searchList.rows.Select(x => x.TradeId).ToList();
|
|
var tradeSwaps = DbContext.trade_swap.Where(x => tradeIds.Contains(x.TradeId)).ToList();
|
|
foreach (var item in searchList.rows)
|
|
{
|
|
item.trade.trade_swap = tradeSwaps.FirstOrDefault(x => x.TradeId == item.TradeId);
|
|
if (item.trade.TradeType == "收益互换")
|
|
{
|
|
if (item.trade.trade_swap.IsGetFloatingProfit)
|
|
{
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.trade_swap.GetUnderlyingId ?? 0);
|
|
if (underlying != null && underlying.ContractSize > 0)
|
|
{
|
|
item.trade.trade_swap.GetContractSize = underlying.ContractSize;
|
|
item.trade.trade_swap.GetCountRatio = underlying.CountRatio;
|
|
}
|
|
}
|
|
else if (item.trade.trade_swap.IsPayFloatingProfit)
|
|
{
|
|
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(item.trade.trade_swap.PayUnderlyingId ?? 0);
|
|
if (underlying != null && underlying.ContractSize > 0)
|
|
{
|
|
item.trade.trade_swap.PayContractSize = underlying.ContractSize;
|
|
item.trade.trade_swap.PayCountRatio = underlying.CountRatio;
|
|
}
|
|
}
|
|
}
|
|
item.trade.TradeSinglePrice = item.trade.TradeSinglePrice.IsNormalize() ? Math.Abs(item.trade.TradeSinglePrice.Value) : item.trade.TradeSinglePrice;
|
|
//处理累计换月交易数据
|
|
new OptionTradeActionRestoreService(UserInfo).RestoreTradeDataToSpecialDay(item.trade, Convert.ToDateTime(req.ValueDate));
|
|
item.CountRatio = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.CountRatio ?? 1;
|
|
}
|
|
|
|
searchList.Sum = gsum;
|
|
return searchList;
|
|
}
|
|
|
|
#region---内部处理----
|
|
|
|
private InnerRequest CreateReq(TradeSpanReq req, IEnumerable<int> userAssetUnits)
|
|
{
|
|
var isBaseClient = false;
|
|
var clientId = req.ClientId ?? 0;
|
|
//if (clientId > 0)
|
|
//{
|
|
// isBaseClient = ClientDataProvider.IsBaseClient(clientId);
|
|
// if (isBaseClient)
|
|
// {
|
|
// clientId = 0;
|
|
// }
|
|
//}
|
|
|
|
if (userAssetUnits != null && !userAssetUnits.Any())
|
|
{
|
|
userAssetUnits = null;
|
|
}
|
|
|
|
var valueDate = req.ValueDate ?? DateTime.MinValue;
|
|
var lastValueDate = EodOperationBase.GetLastSettlementDate(valueDate);
|
|
return new InnerRequest
|
|
{
|
|
clientId = clientId,
|
|
tradeNumber = req.TradeNumber,
|
|
userAssetUnits = userAssetUnits,
|
|
bookIds = req.BookIds,
|
|
tradeTypes = req.TradeTypes,
|
|
notInTradeTypes = req.NotInTradeTypes,
|
|
underlyingIds = req.UnderlyingIds,
|
|
tradeDateStart = req.TradeDateStart,
|
|
tradeDateEnd = req.TradeDateEnd,
|
|
exerciseDateStart = req.ExerciseDateStart,
|
|
exerciseDateEnd = req.ExerciseDateEnd,
|
|
valueDate = valueDate,
|
|
lastValueDate = lastValueDate,
|
|
isBaseClient = isBaseClient,
|
|
ParentFlag = req.ParentFlag
|
|
};
|
|
}
|
|
|
|
private IQueryable<eod_position> CreateTodayQuery(InnerRequest req)
|
|
{
|
|
var suspensionUnderlyingIdList = DataCacheProvider.GetUnderlyingDataSource().AsQueryable()
|
|
.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
|
|
|
|
var predicate = PredicateBuilder.Create<trade>(t => t.ClientId > 0
|
|
&& ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus)
|
|
&& (t.ValidState != "InValid" || t.ValidState == null)
|
|
&& (t.TradeType != "结构化交易" && t.IsGroup != 1 || t.IsGroup == 1 && t.TradeType == "结构化交易")
|
|
&& (t.IsGroup != 2 || t.TradeType != "收益互换")
|
|
&& (t.ExerciseDate >= req.valueDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId)));
|
|
|
|
if (req.clientId > 0 && req.ParentFlag)
|
|
{
|
|
var lists = ClientBalanceUtility.GetSubclientId(req.clientId);
|
|
predicate = predicate.And(t => lists.Contains(t.ClientId));
|
|
|
|
}
|
|
else if (req.clientId > 0 && !req.ParentFlag)
|
|
{
|
|
predicate = predicate.And(t => t.ClientId == req.clientId);
|
|
}
|
|
|
|
if(!string.IsNullOrEmpty(req.tradeNumber))
|
|
{
|
|
predicate = predicate.And(t => t.TradeNumber.Contains(req.tradeNumber));
|
|
}
|
|
|
|
if (req.userAssetUnits != null)
|
|
{
|
|
predicate = predicate.And(t => req.userAssetUnits.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.bookIds != null && req.bookIds.Any())
|
|
{
|
|
predicate = predicate.And(t => req.bookIds.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.tradeTypes != null && req.tradeTypes.Any())
|
|
{
|
|
predicate = predicate.And(t => req.tradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.notInTradeTypes != null && req.notInTradeTypes.Any())
|
|
{
|
|
predicate = predicate.And(t => !req.notInTradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.underlyingIds != null && req.underlyingIds.Any())
|
|
{
|
|
predicate = predicate.And(t => req.underlyingIds.Contains(t.UnderlyingId));
|
|
}
|
|
|
|
if (req.tradeDateStart != null || req.tradeDateEnd != null)
|
|
{
|
|
if (req.tradeDateEnd == null)
|
|
{
|
|
req.tradeDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.tradeDateStart == null)
|
|
{
|
|
req.tradeDateStart = DateTime.MinValue;
|
|
}
|
|
predicate = predicate.And(d => d.TradeDate >= req.tradeDateStart && d.TradeDate <= req.tradeDateEnd);
|
|
}
|
|
|
|
if (req.exerciseDateStart != null || req.exerciseDateEnd != null)
|
|
{
|
|
if (req.exerciseDateEnd == null)
|
|
{
|
|
req.exerciseDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.exerciseDateStart == null)
|
|
{
|
|
req.exerciseDateStart = DateTime.MinValue;
|
|
}
|
|
predicate = predicate.And(d => d.ExerciseDate >= req.exerciseDateStart && d.ExerciseDate <= req.exerciseDateEnd);
|
|
}
|
|
|
|
var volType = PS.Config.Is国投 ? "开仓" : "持仓";
|
|
var query = from t in DbContext.trade.Where(predicate)
|
|
join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on t.ParentTradeId equals parentTrade.id into parentTrades
|
|
from parentTrade in parentTrades.DefaultIfEmpty()
|
|
join risk in DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == req.valueDate && tr.VolType == volType) on t.id equals risk.TradeId into risks
|
|
from risk in risks.DefaultIfEmpty()
|
|
join position in DbContext.intraday_trade_position.Where(tp => tp.ValueDate == req.valueDate) on t.id equals position.TradeId into positions
|
|
from position in positions.DefaultIfEmpty()
|
|
join asset in DbContext.assetunit on t.AssetId equals asset.id into assets
|
|
from asset in assets.DefaultIfEmpty()
|
|
select new eod_position
|
|
{
|
|
TradeId = t.id,
|
|
TradeType = t.IsGroup == 1 ? t.StructureType : t.TradeType,
|
|
ClientId = t.ClientId,
|
|
TradeNumber = parentTrade == null ? t.TradeNumber : parentTrade.TradeNumber,
|
|
TradeDate = t.TradeDate,
|
|
ExerciseDate = t.ExerciseDate,
|
|
UnderlyingCode = t.UnderlyingCode,
|
|
tradeOrigin = t,
|
|
BasisUnderlyingCode = t.BasisUnderlyingCode,
|
|
BasisGap = t.BasisGap ?? 0,
|
|
Lots = t.Lots ?? 0,
|
|
ValueDate = req.valueDate,
|
|
TradeJson = "",
|
|
Pv = 0,
|
|
AnnualizeFactor = t.AnnualizeFactor ?? 0,
|
|
PrincipalRate = t.PrincipalRate ?? 0,
|
|
NoRiskRate = t.NoRiskRate ?? 0,
|
|
ParticipationRate = t.ParticipationRate ?? 0,
|
|
RoundedPv = 0,
|
|
Pnl = 0,
|
|
RoundedPnl = 0,
|
|
UnderlyingPrice = risk.UnderlyingPrice,
|
|
PvDouble = risk.Pv * -1,
|
|
RoundedPvDouble = risk.RoundedPv * -1,
|
|
PnlDouble = risk.PositionPnl * -1,
|
|
RoundedPnlDouble = risk.RoundedPositionPnl * -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,
|
|
GammaCash = risk == null ? 0 : risk.GammaCash,
|
|
Margin = position == null ? 0 : position.Margin,
|
|
PositionRelizedAmount = position == null ? 0 : position.PositionRelizedAmount * -1,
|
|
InstrumentType = t.UnderlyingInstrumentType,
|
|
IsGroup = t.IsGroup,
|
|
SettlementFlag = t.SettlementFlag,
|
|
UserGroup = asset.UserGroup
|
|
};
|
|
return query;
|
|
}
|
|
|
|
private IQueryable<eod_position> CreateTodayChildrenQuery(InnerRequest req)
|
|
{
|
|
var suspensionUnderlyingIdList = DataCacheProvider.GetUnderlyingDataSource().AsQueryable()
|
|
.Where(t => t.UnderlyingStatus == underlying_manager.Status_Suspension).Select(t => t.id).ToList();
|
|
|
|
var predicate = PredicateBuilder.Create<trade>(t => t.ClientId > 0
|
|
&& ConsTrade.NeedMarginTradeStatusList.Contains(t.TradeStatus)
|
|
&& (t.ValidState != "InValid" || t.ValidState == null)
|
|
&& (t.TradeType != "结构化交易" && t.IsGroup != 1 || t.IsGroup == 2)
|
|
&& (t.ExerciseDate >= req.valueDate || suspensionUnderlyingIdList.Contains(t.UnderlyingId)));
|
|
|
|
if (req.clientId > 0 && req.ParentFlag)
|
|
{
|
|
var lists = ClientBalanceUtility.GetSubclientId(req.clientId);
|
|
predicate = predicate.And(t => lists.Contains(t.ClientId));
|
|
|
|
}
|
|
else if (req.clientId > 0 && !req.ParentFlag)
|
|
{
|
|
predicate = predicate.And(t => t.ClientId == req.clientId);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(req.tradeNumber))
|
|
{
|
|
predicate = predicate.And(t => t.TradeNumber.Contains(req.tradeNumber));
|
|
}
|
|
|
|
if (req.userAssetUnits != null)
|
|
{
|
|
predicate = predicate.And(t => req.userAssetUnits.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.bookIds != null && req.bookIds.Any())
|
|
{
|
|
predicate = predicate.And(t => req.bookIds.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.tradeTypes != null && req.tradeTypes.Any())
|
|
{
|
|
predicate = predicate.And(t => req.tradeTypes.Contains(t.StructureType) || req.tradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.notInTradeTypes != null && req.notInTradeTypes.Any())
|
|
{
|
|
predicate = predicate.And(t => !req.notInTradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.underlyingIds != null && req.underlyingIds.Any())
|
|
{
|
|
predicate = predicate.And(t => req.underlyingIds.Contains(t.UnderlyingId));
|
|
}
|
|
|
|
if (req.tradeDateStart != null || req.tradeDateEnd != null)
|
|
{
|
|
if (req.tradeDateEnd == null)
|
|
{
|
|
req.tradeDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.tradeDateStart == null)
|
|
{
|
|
req.tradeDateStart = DateTime.MinValue;
|
|
}
|
|
predicate = predicate.And(d => d.TradeDate >= req.tradeDateStart && d.TradeDate <= req.tradeDateEnd);
|
|
}
|
|
|
|
if (req.exerciseDateStart != null || req.exerciseDateEnd != null)
|
|
{
|
|
if (req.exerciseDateEnd == null)
|
|
{
|
|
req.exerciseDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.exerciseDateStart == null)
|
|
{
|
|
req.exerciseDateStart = DateTime.MinValue;
|
|
}
|
|
predicate = predicate.And(d => d.ExerciseDate >= req.exerciseDateStart && d.ExerciseDate <= req.exerciseDateEnd);
|
|
}
|
|
|
|
var volType = PS.Config.Is国投 ? "开仓" : "持仓";
|
|
var query = from t in DbContext.trade.Where(predicate)
|
|
join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on t.ParentTradeId equals parentTrade.id into parentTrades
|
|
from parentTrade in parentTrades.DefaultIfEmpty()
|
|
join risk in DbContext.realtime_trade_risk.Where(tr => tr.ValueDate == req.valueDate && tr.VolType == volType) on t.id equals risk.TradeId into risks
|
|
from risk in risks.DefaultIfEmpty()
|
|
join position in DbContext.intraday_trade_position.Where(tp => tp.ValueDate == req.valueDate) on t.id equals position.TradeId into positions
|
|
from position in positions.DefaultIfEmpty()
|
|
select new eod_position
|
|
{
|
|
TradeId = t.id,
|
|
TradeType = t.TradeType,
|
|
ClientId = t.ClientId,
|
|
TradeNumber = parentTrade == null ? t.TradeNumber : parentTrade.TradeNumber,
|
|
TradeDate = t.TradeDate,
|
|
ExerciseDate = t.ExerciseDate,
|
|
UnderlyingCode = t.UnderlyingCode,
|
|
tradeOrigin = t,
|
|
BasisUnderlyingCode = t.BasisUnderlyingCode,
|
|
BasisGap = t.BasisGap ?? 0,
|
|
Lots = t.Lots ?? 0,
|
|
ValueDate = req.valueDate,
|
|
TradeJson = "",
|
|
Pv = 0,
|
|
AnnualizeFactor = t.AnnualizeFactor ?? 0,
|
|
PrincipalRate = t.PrincipalRate ?? 0,
|
|
NoRiskRate = t.NoRiskRate ?? 0,
|
|
ParticipationRate = t.ParticipationRate ?? 0,
|
|
RoundedPv = 0,
|
|
Pnl = 0,
|
|
RoundedPnl = 0,
|
|
UnderlyingPrice = risk.UnderlyingPrice,
|
|
PvDouble = risk.Pv * -1,
|
|
RoundedPvDouble = risk.RoundedPv * -1,
|
|
PnlDouble = risk.PositionPnl * -1,
|
|
RoundedPnlDouble = risk.RoundedPositionPnl * -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,
|
|
GammaCash = risk == null ? 0 : risk.GammaCash,
|
|
Margin = position == null ? 0 : position.Margin,
|
|
PositionRelizedAmount = position == null ? 0 : position.PositionRelizedAmount * -1,
|
|
InstrumentType = t.UnderlyingInstrumentType,
|
|
IsGroup = t.IsGroup,
|
|
SettlementFlag = t.SettlementFlag,
|
|
};
|
|
return query;
|
|
}
|
|
|
|
private IQueryable<eod_position> CreateEodQuery(InnerRequest req)
|
|
{
|
|
var eodTradeQuery = DbContext.eod_trade.Where(et =>
|
|
ConsTrade.NeedMarginTradeStatusList.Contains(et.TradeStatus) && et.ValueDate == req.lastValueDate&&et.TradeType!="收益互换");
|
|
|
|
if (req.clientId > 0 && req.ParentFlag)
|
|
{
|
|
var lists = ClientBalanceUtility.GetSubclientId(req.clientId);
|
|
eodTradeQuery = eodTradeQuery.Where(t => lists.Contains(t.ClientId));
|
|
}
|
|
else if (req.clientId > 0 && !req.ParentFlag)
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(n => n.ClientId == req.clientId);
|
|
}
|
|
|
|
if(!string.IsNullOrEmpty(req.tradeNumber))
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(n => n.TradeNumber.Contains(req.tradeNumber));
|
|
}
|
|
|
|
if (req.userAssetUnits != null)
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.userAssetUnits.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.bookIds != null && req.bookIds.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.bookIds.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.tradeTypes != null && req.tradeTypes.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.tradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.notInTradeTypes != null && req.notInTradeTypes.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => !req.notInTradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.underlyingIds != null && req.underlyingIds.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.underlyingIds.Contains(t.UnderlyingId));
|
|
}
|
|
|
|
if (req.tradeDateStart != null || req.tradeDateEnd != null)
|
|
{
|
|
if (req.tradeDateEnd == null)
|
|
{
|
|
req.tradeDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.tradeDateStart == null)
|
|
{
|
|
req.tradeDateStart = DateTime.MinValue;
|
|
}
|
|
|
|
var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.TradeDate >= req.tradeDateStart && d.trade.TradeDate <= req.tradeDateEnd).Select(x => x.TradeId).ToArray();
|
|
|
|
eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId));
|
|
}
|
|
|
|
if (req.exerciseDateStart != null || req.exerciseDateEnd != null)
|
|
{
|
|
if (req.exerciseDateEnd == null)
|
|
{
|
|
req.exerciseDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.exerciseDateStart == null)
|
|
{
|
|
req.exerciseDateStart = DateTime.MinValue;
|
|
}
|
|
|
|
var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.ExerciseDate >= req.exerciseDateStart && d.trade.ExerciseDate <= req.exerciseDateEnd).Select(x => x.TradeId).ToArray();
|
|
|
|
eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId));
|
|
}
|
|
|
|
IQueryable<eod_position> GetQuery<TPosition, TRisk>()
|
|
where TPosition : EodTradePosition where TRisk : EodTradeRisk
|
|
{
|
|
var posQuery = DbContext.Set<TPosition>().Where(t => t.ValueDate == req.lastValueDate && t.TradeId > 0);
|
|
|
|
var tradeOriginQuery = from x in DbContext.trade
|
|
where (x.TradeType != "结构化交易" && x.IsGroup != 1 || x.IsGroup == 1 && x.TradeType == "结构化交易")
|
|
&& (x.IsGroup != 2)
|
|
&& x.ValidState != ConsGlobal.InValid
|
|
select x;
|
|
|
|
return from trade in eodTradeQuery
|
|
join tradeOrigin in tradeOriginQuery on trade.TradeId equals tradeOrigin.id
|
|
join parentTrade in DbContext.trade.Where(x => x.IsGroup == 1 && x.TradeType == "收益互换") on trade.ParentTradeId equals parentTrade.id into parentTrades
|
|
from parentTrade in parentTrades.DefaultIfEmpty()
|
|
join epos in posQuery on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = epos.ValueDate, id = epos.TradeId } into positions
|
|
from epos in positions.DefaultIfEmpty()
|
|
join erisk in DbContext.Set<TRisk>() on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = erisk.ValueDate, id = erisk.TradeId } into t_erisk
|
|
from erisk in t_erisk.DefaultIfEmpty()
|
|
join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets
|
|
from asset in assets.DefaultIfEmpty()
|
|
select new eod_position
|
|
{
|
|
TradeId = tradeOrigin.id,
|
|
TradeType = tradeOrigin.IsGroup == 1 ? tradeOrigin.StructureType : tradeOrigin.TradeType,
|
|
ClientId = tradeOrigin.ClientId,
|
|
TradeNumber = parentTrade == null ? tradeOrigin.TradeNumber : parentTrade.TradeNumber,
|
|
TradeDate = tradeOrigin.TradeDate,
|
|
ExerciseDate = tradeOrigin.ExerciseDate,
|
|
PrincipalRate = tradeOrigin.PrincipalRate ?? 0,
|
|
BasisUnderlyingCode = tradeOrigin.BasisUnderlyingCode,
|
|
BasisGap = tradeOrigin.BasisGap ?? 0,
|
|
Lots = tradeOrigin.Lots ?? 0,
|
|
ParticipationRate = tradeOrigin.ParticipationRate ?? 0,
|
|
NoRiskRate = tradeOrigin.NoRiskRate ?? 0,
|
|
UnderlyingCode = trade.UnderlyingCode,
|
|
UnderlyingPrice = null,
|
|
Pv = epos == null ? 0 : epos.Pv * -1,
|
|
RoundedPv = epos == null ? 0 : epos.RoundedPv * -1,
|
|
Pnl = epos == null ? 0 : epos.PositionPnL * -1,
|
|
RoundedPnl = epos == null ? 0 : epos.RoundedPositionPnL * -1,
|
|
ValueDate = req.lastValueDate,
|
|
TradeJson = trade.TradeJson,
|
|
PvDouble = 0,
|
|
PnlDouble = 0,
|
|
Vol = erisk == null ? 0 : erisk.Vol,
|
|
Delta = erisk == null ? 0 : (double)erisk.Delta,
|
|
Gamma = erisk == null ? 0 : (double)erisk.Gamma,
|
|
Theta = erisk == null ? 0 : (double)erisk.Theta,
|
|
Vega = erisk == null ? 0 : (double)erisk.Vega,
|
|
Rho = erisk == null ? 0 : (double)erisk.Rho,
|
|
GammaCash = erisk == null ? 0 : (double)erisk.GammaCash,
|
|
Margin = epos == null ? 0 : epos.Margin,
|
|
PositionRelizedAmount = epos == null ? 0 : epos.PositionRelizedAmount * -1,
|
|
InstrumentType = tradeOrigin.UnderlyingInstrumentType,
|
|
IsGroup = tradeOrigin.IsGroup,
|
|
SettlementType = tradeOrigin.SettlementType,
|
|
SettlementFlag = tradeOrigin.SettlementFlag,
|
|
UserGroup = asset.UserGroup
|
|
};
|
|
}
|
|
|
|
|
|
if (PS.Config.Is伴兴)
|
|
{
|
|
return GetQuery<eod_trade_position_extend, eod_trade_risk_extend>();
|
|
}
|
|
else if (PS.Config.Is国投)
|
|
{
|
|
return GetQuery<eod_trade_position_openvol, eod_trade_risk_openvol>();
|
|
}
|
|
else if (PS.Config.Is广发商贸)
|
|
{
|
|
return GetQuery<eod_trade_position_hedgevol, eod_trade_risk_hedgevol>();
|
|
}
|
|
|
|
return GetQuery<eod_trade_position, eod_trade_risk>();
|
|
}
|
|
|
|
private IQueryable<eod_position> CreateEodChildrenQuery(InnerRequest req)
|
|
{
|
|
var eodTradeQuery = DbContext.eod_trade.Where(et =>
|
|
ConsTrade.NeedMarginTradeStatusList.Contains(et.TradeStatus) && et.ValueDate == req.lastValueDate);
|
|
|
|
if (req.clientId > 0 && req.ParentFlag)
|
|
{
|
|
var lists = ClientBalanceUtility.GetSubclientId(req.clientId);
|
|
eodTradeQuery = eodTradeQuery.Where(t => lists.Contains(t.ClientId));
|
|
}
|
|
else if (req.clientId > 0 && !req.ParentFlag)
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(n => n.ClientId == req.clientId);
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(req.tradeNumber))
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(n => n.TradeNumber.Contains(req.tradeNumber));
|
|
}
|
|
|
|
if (req.userAssetUnits != null)
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.userAssetUnits.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.bookIds != null && req.bookIds.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.bookIds.Contains(t.AssetId));
|
|
}
|
|
|
|
if (req.tradeTypes != null && req.tradeTypes.Any())
|
|
{
|
|
var tradeIds = eodTradeQuery.ToList().Where(t => req.tradeTypes.Contains(t.trade.StructureType) || req.tradeTypes.Contains(t.TradeType)).Select(x => x.TradeId).ToArray();
|
|
eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId));
|
|
}
|
|
|
|
if (req.notInTradeTypes != null && req.notInTradeTypes.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => !req.notInTradeTypes.Contains(t.TradeType));
|
|
}
|
|
|
|
if (req.underlyingIds != null && req.underlyingIds.Any())
|
|
{
|
|
eodTradeQuery = eodTradeQuery.Where(t => req.underlyingIds.Contains(t.UnderlyingId));
|
|
}
|
|
|
|
if (req.tradeDateStart != null || req.tradeDateEnd != null)
|
|
{
|
|
if (req.tradeDateEnd == null)
|
|
{
|
|
req.tradeDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.tradeDateStart == null)
|
|
{
|
|
req.tradeDateStart = DateTime.MinValue;
|
|
}
|
|
|
|
var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.TradeDate >= req.tradeDateStart && d.trade.TradeDate <= req.tradeDateEnd).Select(x => x.TradeId).ToArray();
|
|
|
|
eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId));
|
|
}
|
|
|
|
if (req.exerciseDateStart != null || req.exerciseDateEnd != null)
|
|
{
|
|
if (req.exerciseDateEnd == null)
|
|
{
|
|
req.exerciseDateEnd = DateTime.MaxValue;
|
|
}
|
|
if (req.exerciseDateStart == null)
|
|
{
|
|
req.exerciseDateStart = DateTime.MinValue;
|
|
}
|
|
|
|
var tradeIds = eodTradeQuery.ToList().Where(d => d.trade.ExerciseDate >= req.exerciseDateStart && d.trade.ExerciseDate <= req.exerciseDateEnd).Select(x => x.TradeId).ToArray();
|
|
|
|
eodTradeQuery = eodTradeQuery.Where(d => tradeIds.Contains(d.TradeId));
|
|
}
|
|
|
|
IQueryable<eod_position> GetQuery<TPosition, TRisk>()
|
|
where TPosition : EodTradePosition where TRisk : EodTradeRisk
|
|
{
|
|
var posQuery = DbContext.Set<TPosition>().Where(t => t.ValueDate == req.lastValueDate && t.TradeId > 0);
|
|
|
|
var tradeOriginQuery = from x in DbContext.trade
|
|
where (x.TradeType != "结构化交易" && x.IsGroup != 1 || x.IsGroup == 2)
|
|
&& x.ValidState != ConsGlobal.InValid
|
|
select x;
|
|
|
|
return from trade in eodTradeQuery
|
|
join tradeOrigin in tradeOriginQuery on trade.TradeId equals tradeOrigin.id
|
|
join epos in posQuery on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = epos.ValueDate, id = epos.TradeId } into positions
|
|
from epos in positions.DefaultIfEmpty()
|
|
join erisk in DbContext.Set<TRisk>() on new { valueDate = trade.ValueDate, id = trade.TradeId } equals new { valueDate = erisk.ValueDate, id = erisk.TradeId } into t_erisk
|
|
from erisk in t_erisk.DefaultIfEmpty()
|
|
select new eod_position
|
|
{
|
|
TradeId = tradeOrigin.id,
|
|
TradeType = tradeOrigin.TradeType,
|
|
ClientId = tradeOrigin.ClientId,
|
|
TradeNumber = tradeOrigin.TradeNumber,
|
|
TradeDate = tradeOrigin.TradeDate,
|
|
ExerciseDate = tradeOrigin.ExerciseDate,
|
|
PrincipalRate = tradeOrigin.PrincipalRate ?? 0,
|
|
BasisUnderlyingCode = tradeOrigin.BasisUnderlyingCode,
|
|
BasisGap = tradeOrigin.BasisGap ?? 0,
|
|
Lots = tradeOrigin.Lots ?? 0,
|
|
ParticipationRate = tradeOrigin.ParticipationRate ?? 0,
|
|
NoRiskRate = tradeOrigin.NoRiskRate ?? 0,
|
|
UnderlyingCode = trade.UnderlyingCode,
|
|
UnderlyingPrice = null,
|
|
Pv = epos == null ? 0 : epos.Pv * -1,
|
|
RoundedPv = epos == null ? 0 : epos.RoundedPv * -1,
|
|
Pnl = epos == null ? 0 : epos.PositionPnL * -1,
|
|
RoundedPnl = epos == null ? 0 : epos.RoundedPositionPnL * -1,
|
|
ValueDate = req.lastValueDate,
|
|
TradeJson = trade.TradeJson,
|
|
PvDouble = 0,
|
|
PnlDouble = 0,
|
|
Vol = erisk == null ? 0 : erisk.Vol,
|
|
Delta = erisk == null ? 0 : (double)erisk.Delta,
|
|
Gamma = erisk == null ? 0 : (double)erisk.Gamma,
|
|
Theta = erisk == null ? 0 : (double)erisk.Theta,
|
|
Vega = erisk == null ? 0 : (double)erisk.Vega,
|
|
Rho = erisk == null ? 0 : (double)erisk.Rho,
|
|
GammaCash = erisk == null ? 0 : (double)erisk.GammaCash,
|
|
Margin = epos == null ? 0 : epos.Margin,
|
|
PositionRelizedAmount = epos == null ? 0 : epos.PositionRelizedAmount * -1,
|
|
InstrumentType = tradeOrigin.UnderlyingInstrumentType,
|
|
IsGroup = tradeOrigin.IsGroup,
|
|
SettlementType = tradeOrigin.SettlementType,
|
|
SettlementFlag = tradeOrigin.SettlementFlag
|
|
};
|
|
}
|
|
|
|
|
|
if (PS.Config.Is伴兴)
|
|
{
|
|
return GetQuery<eod_trade_position_extend, eod_trade_risk_extend>();
|
|
}
|
|
else if (PS.Config.Is国投)
|
|
{
|
|
return GetQuery<eod_trade_position_openvol, eod_trade_risk_openvol>();
|
|
}
|
|
else if (PS.Config.Is广发商贸)
|
|
{
|
|
return GetQuery<eod_trade_position_hedgevol, eod_trade_risk_hedgevol>();
|
|
}
|
|
|
|
return GetQuery<eod_trade_position, eod_trade_risk>();
|
|
}
|
|
|
|
class InnerRequest
|
|
{
|
|
public int clientId { get; set; }
|
|
|
|
public string tradeNumber { get; set; }
|
|
|
|
public IEnumerable<string> tradeTypes { get; set; }
|
|
|
|
public IEnumerable<string> notInTradeTypes { get; set; }
|
|
|
|
public IEnumerable<int> userAssetUnits { get; set; }
|
|
|
|
public IEnumerable<int> bookIds { get; set; }
|
|
|
|
public IEnumerable<int> underlyingIds { get; set; }
|
|
|
|
public DateTime? tradeDateStart { get; set; }
|
|
|
|
public DateTime? tradeDateEnd { get; set; }
|
|
|
|
public DateTime? exerciseDateStart { get; set; }
|
|
|
|
public DateTime? exerciseDateEnd { get; set; }
|
|
|
|
public DateTime valueDate { get; set; }
|
|
|
|
public DateTime lastValueDate { get; set; }
|
|
|
|
public bool isBaseClient { get; set; }
|
|
|
|
public bool isTodayQuery => valueDate > lastValueDate;
|
|
|
|
public bool ParentFlag { get; set; }
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|