Files
zszq-trs/YLErpDAL/Modules/RiskModule/RealtimePositionRisksQueryService.cs
2024-05-09 14:06:26 +08:00

758 lines
42 KiB
C#

using BaseOUDAL;
using NPOI.POIFS.Properties;
using NPOI.SS.Formula.Functions;
using OfficeOpenXml.FormulaParsing.ExpressionGraph;
using Org.BouncyCastle.Ocsp;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using YLErp.BLL;
using YLErp.Commons;
using YLErp.DBModels;
using YLErp.DBModels.Helpers;
using YLErp.Model;
using YLErp.Modules.DataProviderModule;
using YLErp.Modules.UnderlyingModule;
using YLErp.Office.ExcelModule;
namespace YLErp.Modules.RiskModule
{
public class RealtimePositionRisksQueryService : YLBaseService
{
public RealtimePositionRisksQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
public SearchListResult<RealTimePositionRisksDTO> SearchList(RealTimePositionRisksReq req)
{
if (req?.IsParentTrade == true)
{
return SearchRealTimeOptionPostionRisksList(req);
}
else
{
return SearchRealTimePostionRisksList(req);
}
}
/// <summary>
/// 是否主交易 是
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public SearchListResult<RealTimePositionRisksDTO> SearchRealTimeOptionPostionRisksList(RealTimePositionRisksReq req)
{
var voltype = req?.VolType ?? string.Empty;
var statusList = new List<string> { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 };
var realtimePredicate = BuildPredicateOfRealTime(req);
var tradePredicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2);
if (req.UserAssets != null && req.UserClients != null)
{
tradePredicate = tradePredicate.And(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId));
}
if (req.TraderIds != null && req.TraderIds.Any(x => x > 0))
{
tradePredicate = tradePredicate.And(q => req.TraderIds.Contains(q.TraderId));
}
if (req.TradeTypes != null && req.TradeTypes.Any(x => !string.IsNullOrWhiteSpace(x)))
{
tradePredicate = tradePredicate.And(d => req.TradeTypes.Contains(d.StructureType) || req.TradeTypes.Contains(d.TradeType) || (req.TradeTypes.Contains("黑箱结构") && d.IsGroup != 0));
}
if (!string.IsNullOrWhiteSpace(req.TradeNumber))
{
realtimePredicate = realtimePredicate.And(n => n.TradeId > 0);
tradePredicate = tradePredicate.And(q => q.TradeNumber.Contains(req.TradeNumber));
}
if (req.SettlementFlags != null && req.SettlementFlags.Any())
{
tradePredicate = tradePredicate.And(d => req.SettlementFlags.Contains(d.SettlementFlag));
}
if (!string.IsNullOrEmpty(req.GroupNames) && req.GroupNamesList != null && req.GroupNamesList.Count > 0)
{
var gname = req.GroupNamesList[0];
var groupNamePredicate = PredicateBuilder.Create<trade>(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname.ToString()));
if (req.GroupNamesList.Count > 1)
{
for (int i = 1; i < req.GroupNamesList.Count; i++)
{
var gname1 = req.GroupNamesList[i];
groupNamePredicate = groupNamePredicate.Or(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname1.ToString()));
}
}
tradePredicate = tradePredicate.And(groupNamePredicate);
}
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;
tradePredicate = tradePredicate.And(p => tradeTagIdQuery.Contains(p.id));
}
var tradeList = new List<string> { "收益互换", "远期", "掉期", "现金流交易" };
var query = from intradayTrade in DbContext.intraday_trade_position.Where(realtimePredicate)
join trade in DbContext.trade.Where(tradePredicate) on intradayTrade.TradeId equals trade.id
join tr in DbContext.trade_contract_r.Where(O => O.Type == "交易确认书" && O.IsValid) on trade.id equals tr.TradeId into trs
from tr in trs.DefaultIfEmpty()
join realtimeRisk in DbContext.realtime_trade_risk on intradayTrade.TradeId equals realtimeRisk.TradeId into realtimeRisk_t
from realtimeRisk in realtimeRisk_t.DefaultIfEmpty()
join assetUnit in DbContext.assetunit on trade.AssetId equals assetUnit.id into assetUnits
from assetUnit in assetUnits.DefaultIfEmpty()
join parentTrade in DbContext.trade.Where(tr => tr.ValidState != "InValid") on trade.ParentTradeId equals parentTrade.id into parentTrades
from parentTrade in parentTrades.DefaultIfEmpty()
join binary in DbContext.trade_binary_option on intradayTrade.TradeId equals binary.TradeId into binary_t
from binary in binary_t.DefaultIfEmpty()
join asian in DbContext.trade_asian_option on intradayTrade.TradeId equals asian.TradeId into asian_t
from asian in asian_t.DefaultIfEmpty()
join barrier in DbContext.trade_barrier_option on intradayTrade.TradeId equals barrier.TradeId into barrier_t
from barrier in barrier_t.DefaultIfEmpty()
join um in DbContext.underlying_manager on intradayTrade.UnderlyingCode equals um.UnderlyingCode into um_t
from um in um_t.DefaultIfEmpty()
where !statusList.Contains(intradayTrade.TradeStatus)
&& (!req.VarietyIds.Any() || um != null && req.VarietyIds.Contains(um.UnderlyingTypeId))
&& (!req.UnderlyingIds.Any() || um != null && req.UnderlyingIds.Contains(um.id))
&& !tradeList.Contains(intradayTrade.TradeType)
&& realtimeRisk.VolType == voltype
select new RealTimePositionRisksDTO
{
GroupName = trade.GroupName,
id = trade.id,
OptionType = trade.OptionType,
ClientName = trade.ClientName,
TraderName = trade.TraderName,
AssetBookName = assetUnit != null ? assetUnit.Name : null,
CurrentVolatility = realtimeRisk.Vol,
PositionPnl = intradayTrade != null ? intradayTrade.PositionPnL : 0,//浮动盈亏
RoundedPositionPnl = intradayTrade != null ? intradayTrade.RoundedPositionPnl : 0,
PV = intradayTrade != null ? (double)intradayTrade.Pv : 0,
RoundedPV = intradayTrade != null ? (double)intradayTrade.RoundedPv : 0,
Vega = realtimeRisk.Vega, //实现盈亏
Theta = realtimeRisk.Theta,
Rho = realtimeRisk.Rho,
Delta = realtimeRisk.Delta,
Gamma = realtimeRisk.Gamma,
DeltaCash = realtimeRisk.DeltaCash,
GammaCash = realtimeRisk.GammaCash,
VegaCash = realtimeRisk.VegaCash,
ExerciseDate = trade.ExerciseDate,
ExerciseMode = trade.ExerciseMode,
Notional = intradayTrade != null ? intradayTrade.Amount : 0,
StockEqvNotionalMax = trade.StockEqvNotionalMax,
OriginalStockEqvNotional = trade.OriginalStockEqvNotional,
Strike = trade.Strike,
IsMoneynessOption = trade.IsMoneynessOption,
ExchangeOptionCode = intradayTrade != null ? intradayTrade.ExchangeOptionCode : "",
IsUsePremiumRate = trade.IsUsePremiumRate,
PremiumRate = trade.PremiumRate,
TradeDate = trade.TradeDate,
ParentTradeNumber = parentTrade != null ? parentTrade.TradeNumber : trade.TradeNumber,
ContractCode = tr.ContractCode,
TradeNumber = trade.TradeNumber,
ParentTradeId = trade.ParentTradeId,
TradePrice = trade.TradePrice,
BuySell = trade.BuySell,
TradeSinglePrice = trade.TradeSinglePrice,
TradeType = trade.TradeType,
StructureType = trade.StructureType != "结构化交易" ? trade.StructureType : null,
UnderlyingCode = intradayTrade.UnderlyingCode,
IsGroup = trade.IsGroup,
Margin = intradayTrade != null ? intradayTrade.Margin : 0,
Exposure = realtimeRisk.CreditExposure,
RealizedPnl = realtimeRisk != null ? realtimeRisk.RealizedPnl.Value : 0,
HedgeUniqueCode = intradayTrade != null ? intradayTrade.HedgeUniqueCode : "",
OriginalPrincipalSum = trade.OriginalPrincipalSum,
SurvivingNominalPrincipal = trade.SpotPrice * intradayTrade.Amount,
UnderlyingPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0,
CalSpotPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0,
trade = trade,
OptDate = realtimeRisk.OptDate
};
query = query.OrderByDescending(O => O.id).ThenBy(O => O.ParentTradeNumber).ThenBy(O => O.TradeNumber);
//所有子交易
var childTradeList = query.Where(n => n.ParentTradeId > 0).ToList();
//过滤掉所有子交易
//query = query.Where(n => n.ParentTradeId == 0);
var searchResult = query.ToSearchList(req);
var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费,
ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他};
BLL.tradeBLL.SetFieldsByTradeType(searchResult.rows.Select(o => o.trade));
foreach (var r in searchResult.rows)
{
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode);
if (um == null)
{
um = new underlying_manager();
}
else
{
r.UnderlyingPrice = um.Price ?? 0;
r.UnderlyingId = um.id;
r.VarietyId = um.UnderlyingTypeId;
r.UnderlyingAssetName = um.UnderlyingName;
r.CountRatio = um.CountRatio;
if (PS.Config.IsGuoJun)
{
r.UnderlyingVariety = UnderlyingHelper.GetUnderlyingVarietyCode(r.UnderlyingCode);
}
}
if (r.IsGroup == 1 || r.TradeType == "结构化交易")
{
var cTrades = childTradeList.Where(n => n.ParentTradeId == r.id).ToList();
if (cTrades.Count() == 0)
{
var childTradeIds = DbContext.trade.Where(n => n.ParentTradeId == r.id).Select(n => n.id).ToList();
cTrades = (from childRealTimeRisk in DbContext.realtime_trade_risk
join childIntradayTrade in DbContext.intraday_trade_position on childRealTimeRisk.TradeId equals childIntradayTrade.TradeId
where childTradeIds.Contains(childRealTimeRisk.TradeId.Value)
select new RealTimePositionRisksDTO
{
PV = childRealTimeRisk.Pv,
RoundedPV = childRealTimeRisk.RoundedPv,
PositionPnl = childRealTimeRisk.PositionPnl,
RoundedPositionPnl = childRealTimeRisk.RoundedPositionPnl,
RealizedPnl = childRealTimeRisk.RealizedPnl ?? 0,
Margin = childIntradayTrade.Margin,
Delta = childRealTimeRisk.Delta,
Gamma = childRealTimeRisk.Gamma,
Vega = childRealTimeRisk.Vega,
Theta = childRealTimeRisk.Theta,
Rho = childRealTimeRisk.Rho,
}).ToList();
}
r.PV = cTrades.Sum(y => y.PV);
r.RoundedPV = cTrades.Sum(y => y.RoundedPV);
r.PositionPnl = cTrades.Sum(y => y.PositionPnl);
r.RoundedPositionPnl = cTrades.Sum(y => y.RoundedPositionPnl);
r.RealizedPnl = cTrades.Sum(n => n.RealizedPnl);
r.Margin = cTrades.Sum(y => y.Margin);
r.Delta = cTrades.Sum(y => y.Delta);
r.Gamma = cTrades.Sum(y => y.Gamma);
r.Vega = cTrades.Sum(y => y.Vega);
r.Theta = cTrades.Sum(y => y.Theta);
r.Rho = cTrades.Sum(y => y.Rho);
r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100;
r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate;
r.OriginalNotional = r.trade?.OriginalNotional;
r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio;
r.TradeStatus = r.trade?.TradeStatus;
r.StockEqvNotional = r.trade?.StockEqvNotional;
r.InitialSpotPrice = r.trade?.SpotPrice;
r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional);
r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional
, PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false);
if (um != null)
{
r.GammaLots = (r.Gamma ?? 0) / um.ContractSize;
r.DeltaLots = (r.Delta ?? 0) / um.ContractSize;
}
}
else
{
r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100;
r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate;
r.OriginalNotional = r.trade?.OriginalNotional;
r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio;
r.TradeStatus = r.trade?.TradeStatus;
r.StockEqvNotional = r.trade?.StockEqvNotional;
r.InitialSpotPrice = r.trade?.SpotPrice;
r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional);
r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional
, PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false);
if (um != null)
{
r.GammaLots = (r.Gamma ?? 0) / um.ContractSize;
r.DeltaLots = (r.Delta ?? 0) / um.ContractSize;
}
}
if (r.ParentTradeId > 0)
{
var childTrades = DbContext.trade.Where(x => x.ParentTradeId == r.ParentTradeId).OrderBy(x => x.TradeNumber).Select(x => x.id).ToList();
r.ChildLeg = (childTrades.IndexOf(r.id) + 1).ToString();
}
r.ClientNumber = DataCacheProvider.GetClientDataSource().GetData(r.trade.ClientId)?.Number;
switch (r.TradeType)
{
case "雪球期权":
r.KnockInOutStatus = r.trade?.trade_snowball.KnockInOutStatusCn;
break;
case "凤凰期权":
r.KnockInOutStatus = r.trade?.trade_autocall.KnockInOutStatusCn;
break;
case "双鲨期权":
r.KnockInOutStatus = r.trade?.trade_double_sharkfin_option.KnockInOutStatusCn;
break;
case "障碍期权":
r.KnockInOutStatus = r.trade?.trade_barrier_option.KnockInOutStatusCn;
break;
case "气囊结构":
r.KnockInOutStatus = r.trade?.trade_airbag.KnockInOutStatusCn;
break;
case "累计期权":
r.Strike = r.trade?.Strike;
var settleMode = DbContext.autocall_observation.Where(n => n.TradeId == r.id && n.EndDate <= req.ValueDate)
.OrderByDescending(n => n.EndDate).Select(n => n.SettlementMode).FirstOrDefault();
r.KnockInOutStatus = settleMode == "敲出" ? "敲出" : "观察中";
break;
}
r.Rho *= 100;
}
if (searchResult.rows.Count() > 0)
{
searchResult.Msg = searchResult.rows.FirstOrDefault().OptDate?.ToString("yyyy-MM-dd HH:mm:ss");
}
return searchResult;
}
/// <summary>
/// 是否主交易 否
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public SearchListResult<RealTimePositionRisksDTO> SearchRealTimePostionRisksList(RealTimePositionRisksReq req)
{
var voltype = req?.VolType ?? string.Empty;
var statusList = new List<string> { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 };
var realtimePredicate = BuildPredicateOfRealTime(req);
var tradePredicate = PredicateBuilder.Create<trade>(t => t.ValidState != "InValid" && t.TradeType != "结构化交易" && t.IsGroup != 1);
if (req.UserAssets != null && req.UserClients != null)
{
tradePredicate = tradePredicate.And(a => req.UserAssets.Contains(a.AssetId) || req.UserClients.Contains(a.ClientId));
}
if (req.TraderIds != null && req.TraderIds.Any(x => x > 0))
{
tradePredicate = tradePredicate.And(q => req.TraderIds.Contains(q.TraderId));
}
if (req.TradeTypes != null && req.TradeTypes.Any(x => !string.IsNullOrWhiteSpace(x)))
{
tradePredicate = tradePredicate.And(d => req.TradeTypes.Contains(d.StructureType) || req.TradeTypes.Contains(d.TradeType) || (req.TradeTypes.Contains("黑箱结构") && d.IsGroup != 0));
}
if (!string.IsNullOrWhiteSpace(req.TradeNumber))
{
realtimePredicate = realtimePredicate.And(n => n.TradeId > 0);
tradePredicate = tradePredicate.And(q => q.TradeNumber.Contains(req.TradeNumber));
}
if (req.SettlementFlags != null && req.SettlementFlags.Any())
{
tradePredicate = tradePredicate.And(d => req.SettlementFlags.Contains(d.SettlementFlag));
}
if (!string.IsNullOrEmpty(req.GroupNames) && req.GroupNamesList != null && req.GroupNamesList.Count > 0)
{
var gname = req.GroupNamesList[0];
var groupNamePredicate = PredicateBuilder.Create<trade>(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname.ToString()));
if (req.GroupNamesList.Count > 1)
{
for (int i = 1; i < req.GroupNamesList.Count; i++)
{
var gname1 = req.GroupNamesList[i];
groupNamePredicate = groupNamePredicate.Or(t => !string.IsNullOrEmpty(t.GroupName) && t.GroupName.Contains(gname1.ToString()));
}
}
tradePredicate = tradePredicate.And(groupNamePredicate);
}
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;
tradePredicate = tradePredicate.And(p => tradeTagIdQuery.Contains(p.id));
}
var tradeList = new List<string> { "收益互换", "远期", "掉期", "现金流交易" };
var query = from intradayTrade in DbContext.intraday_trade_position.Where(realtimePredicate)
join trade in DbContext.trade.Where(tradePredicate) on intradayTrade.TradeId equals trade.id
join tr in DbContext.trade_contract_r.Where(O => O.Type == "交易确认书" && O.IsValid) on trade.id equals tr.TradeId into trs
from tr in trs.DefaultIfEmpty()
join realtimeRisk in DbContext.realtime_trade_risk on intradayTrade.TradeId equals realtimeRisk.TradeId into realtimeRisk_t
from realtimeRisk in realtimeRisk_t.DefaultIfEmpty()
join assetUnit in DbContext.assetunit on trade.AssetId equals assetUnit.id into assetUnits
from assetUnit in assetUnits.DefaultIfEmpty()
join parentTrade in DbContext.trade.Where(tr => tr.ValidState != "InValid") on trade.ParentTradeId equals parentTrade.id into parentTrades
from parentTrade in parentTrades.DefaultIfEmpty()
join binary in DbContext.trade_binary_option on intradayTrade.TradeId equals binary.TradeId into binary_t
from binary in binary_t.DefaultIfEmpty()
join asian in DbContext.trade_asian_option on intradayTrade.TradeId equals asian.TradeId into asian_t
from asian in asian_t.DefaultIfEmpty()
join barrier in DbContext.trade_barrier_option on intradayTrade.TradeId equals barrier.TradeId into barrier_t
from barrier in barrier_t.DefaultIfEmpty()
join um in DbContext.underlying_manager on intradayTrade.UnderlyingCode equals um.UnderlyingCode into um_t
from um in um_t.DefaultIfEmpty()
where !statusList.Contains(intradayTrade.TradeStatus)
&& (!req.VarietyIds.Any() || um != null && req.VarietyIds.Contains(um.UnderlyingTypeId))
&& (!req.UnderlyingIds.Any() || um != null && req.UnderlyingIds.Contains(um.id))
&& !tradeList.Contains(intradayTrade.TradeType)
&& realtimeRisk.VolType == voltype
select new RealTimePositionRisksDTO
{
GroupName = trade.GroupName,
id = trade.id,
OptionType = trade.OptionType,
ClientName = trade.ClientName,
TraderName = trade.TraderName,
AssetBookName = assetUnit != null ? assetUnit.Name : null,
CurrentVolatility = realtimeRisk.Vol,
PositionPnl = intradayTrade != null ? intradayTrade.PositionPnL : 0,//浮动盈亏
RoundedPositionPnl = intradayTrade != null ? intradayTrade.RoundedPositionPnl : 0,
PV = intradayTrade != null ? (double)intradayTrade.Pv : 0,
RoundedPV = intradayTrade != null ? (double)intradayTrade.RoundedPv : 0,
Vega = realtimeRisk.Vega, //实现盈亏
Theta = realtimeRisk.Theta,
Rho = realtimeRisk.Rho,
Delta = realtimeRisk.Delta,
Gamma = realtimeRisk.Gamma,
DeltaCash = realtimeRisk.DeltaCash,
GammaCash = realtimeRisk.GammaCash,
VegaCash = realtimeRisk.VegaCash,
ExerciseDate = trade.ExerciseDate,
ExerciseMode = trade.ExerciseMode,
Notional = intradayTrade != null ? intradayTrade.Amount : 0,
StockEqvNotionalMax = trade.StockEqvNotionalMax,
OriginalStockEqvNotional = trade.OriginalStockEqvNotional,
Strike = trade.Strike,
IsMoneynessOption = trade.IsMoneynessOption,
ExchangeOptionCode = intradayTrade != null ? intradayTrade.ExchangeOptionCode : "",
IsUsePremiumRate = trade.IsUsePremiumRate,
PremiumRate = trade.PremiumRate,
TradeDate = trade.TradeDate,
ParentTradeNumber = parentTrade != null ? parentTrade.TradeNumber : trade.TradeNumber,
ContractCode = tr.ContractCode,
TradeNumber = trade.TradeNumber,
ParentTradeId = trade.ParentTradeId,
TradePrice = trade.TradePrice,
BuySell = trade.BuySell,
TradeSinglePrice = trade.TradeSinglePrice,
TradeType = trade.TradeType,
StructureType = trade.TradeType == "自定义交易" ? trade.StructureType : trade.TradeType,
UnderlyingCode = intradayTrade.UnderlyingCode,
IsGroup = trade.IsGroup,
Margin = intradayTrade != null ? intradayTrade.Margin : 0,
Exposure = realtimeRisk.CreditExposure,
RealizedPnl = realtimeRisk != null ? realtimeRisk.RealizedPnl.Value : 0,
HedgeUniqueCode = intradayTrade != null ? intradayTrade.HedgeUniqueCode : "",
OriginalPrincipalSum = trade.OriginalPrincipalSum,
SurvivingNominalPrincipal = trade.SpotPrice * intradayTrade.Amount,
UnderlyingPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0,
CalSpotPrice = realtimeRisk != null ? realtimeRisk.UnderlyingPrice.Value : 0,
trade = trade,
OptDate = realtimeRisk.OptDate
};
query = query.OrderByDescending(O => O.id).ThenBy(O => O.ParentTradeNumber).ThenBy(O => O.TradeNumber);
var searchResult = query.ToSearchList(req);
var tcActions = new[] { ClientCashInCashOut.系统操作_平仓费,
ClientCashInCashOut.系统操作_行权费,ClientCashInCashOut.系统操作_票息,ClientCashInCashOut.系统操作_互换,ClientCashInCashOut.人工操作_其他};
BLL.tradeBLL.SetFieldsByTradeType(searchResult.rows.Select(o => o.trade));
foreach (var r in searchResult.rows)
{
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(r.UnderlyingCode);
if (um == null)
{
um = new underlying_manager();
}
else
{
r.UnderlyingPrice = um.Price ?? 0;
r.UnderlyingId = um.id;
r.VarietyId = um.UnderlyingTypeId;
r.UnderlyingAssetName = um.UnderlyingName;
r.CountRatio = um.CountRatio;
if (PS.Config.IsGuoJun)
{
r.UnderlyingVariety = UnderlyingHelper.GetUnderlyingVarietyCode(r.UnderlyingCode);
}
}
r.RiskFreeRate = r.trade?.NoRiskRate ?? valuedateBLL.RiskFreeRate / 100;
r.DividendRate = r.trade?.DividendRate ?? r.RiskFreeRate;
r.OriginalNotional = r.trade?.OriginalNotional;
r.TradeOriginalAmount = r.OriginalNotional / um.CountRatio;
r.TradeStatus = r.trade?.TradeStatus;
r.StockEqvNotional = r.trade?.StockEqvNotional;
r.InitialSpotPrice = r.trade?.SpotPrice;
switch (r.TradeType)
{
case "雪球期权":
r.KnockInOutStatus = r.trade?.trade_snowball.KnockInOutStatusCn;
break;
case "凤凰期权":
r.KnockInOutStatus = r.trade?.trade_autocall.KnockInOutStatusCn;
break;
case "双鲨期权":
r.KnockInOutStatus = r.trade?.trade_double_sharkfin_option.KnockInOutStatusCn;
break;
case "障碍期权":
r.KnockInOutStatus = r.trade?.trade_barrier_option.KnockInOutStatusCn;
break;
case "气囊结构":
r.KnockInOutStatus = r.trade?.trade_airbag.KnockInOutStatusCn;
break;
case "累计期权":
r.Strike = r.trade?.Strike;
var settleMode = DbContext.autocall_observation.Where(n => n.TradeId == r.id && n.EndDate <= req.ValueDate)
.OrderByDescending(n => n.EndDate).Select(n => n.SettlementMode).FirstOrDefault();
r.KnockInOutStatus = settleMode == "敲出" ? "敲出" : "观察中";
break;
}
r.etcTradePrice = r.TradePrice * (r.trade == null ? r.Notional / r.OriginalNotional : r.trade?.StockEqvNotional / r.trade?.OriginalStockEqvNotional);
if (r.trade != null)
{
r.SinglePV = TradeHelper.GetTradeSinglePriceByTradePrice(PS.Config.IsPVRounded ? r.RoundedPV : r.PV, r.Notional
, PS.Config.ErpElement.IsPVIncludePrincipal ? r.trade.PrincipalSum() : 0, r.trade.BuySell, r.trade.TradeType, false);
}
if (r.trade != null)
{
r.ClientNumber = DataCacheProvider.GetClientDataSource().GetData(r.trade.ClientId)?.Number;
}
if (r.trade != null && r.trade.IsGroup == 1)
{
var eodtrade = DbContext.eod_trade.Where(x => x.ValueDate == req.ValueDate && x.ParentTradeId == r.id && ConsTrade.LiveTradeStatusList.Contains(x.TradeStatus)).ToList();
r.etcTradePrice = eodtrade.Select(x => (x.trade.BuySell == "买入" ? -1 : 1) * x.trade.TradePrice * x.trade.StockEqvNotional / x.trade.OriginalStockEqvNotional).Sum();
}
if (r.ParentTradeId > 0)
{
var childTrades = DbContext.trade.Where(x => x.ParentTradeId == r.ParentTradeId).OrderBy(x => x.TradeNumber).Select(x => x.id).ToList();
r.ChildLeg = (childTrades.IndexOf(r.id) + 1).ToString();
}
if (um != null)
{
r.GammaLots = (r.Gamma ?? 0) / um.ContractSize;
r.DeltaLots = (r.Delta ?? 0) / um.ContractSize;
}
r.Rho *= 100;
}
if (searchResult.rows.Count() > 0)
{
searchResult.Msg = searchResult.rows.FirstOrDefault().OptDate?.ToString("yyyy-MM-dd HH:mm:ss");
}
return searchResult;
}
public Expression<Func<intraday_trade_position, bool>> BuildPredicateOfRealTime(RealTimePositionRisksReq reqModel)
{
var predicate = PredicateBuilder.Create<intraday_trade_position>(t => t.ValueDate == valuedateBLL.ValueDate);
if (reqModel.UserAssets != null || reqModel.UserClients != null)
{
predicate = predicate.And(t => reqModel.UserAssets.Contains(t.BookId) || reqModel.UserClients.Contains(t.ClientId));
}
if (reqModel.ClientIds != null && reqModel.ClientIds.Any(x => x > 0))
{
predicate = predicate.And(q => reqModel.ClientIds.Contains(q.ClientId));
}
if (reqModel.BookIds != null && reqModel.BookIds.Any(x => x > 0))
{
predicate = predicate.And(q => reqModel.BookIds.Contains(q.BookId));
}
if (reqModel.TradeIds != null && reqModel.TradeIds.Any(x => x != 0))
{
predicate = predicate.And(q => reqModel.TradeIds.Contains(q.TradeId));
}
reqModel.VarietyIds = reqModel.VarietyIds == null ? Enumerable.Empty<int>() : reqModel.VarietyIds.Where(n => n > 0).ToArray();
reqModel.UnderlyingIds = reqModel.UnderlyingIds == null ? Enumerable.Empty<int>() : reqModel.UnderlyingIds.Where(n => n > 0).ToArray();
reqModel.SettlementFlags = reqModel.SettlementFlags == null ? Enumerable.Empty<int>() : reqModel.SettlementFlags.ToArray();
return predicate;
}
public byte[] ExportRealtimePositionRisksToExcel(RealTimePositionRisksReq req)
{
var results = GettRealtimePositionRisksDataHandle(req);
var list2 = results.Select(n => new ExpandoDictionary<string, string>(n)).ToArray();
var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/实时持仓风险.xlsx");
return ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = list2 }).GenerateBytes();
}
public List<Dictionary<string, string>> GettRealtimePositionRisksDataHandle(RealTimePositionRisksReq req)
{
if (req.TradeIds == null || !req.TradeIds.Any())
{
req.page = 0;
req.rows = 10000;
}
req.IsOnlyExport = true;
IEnumerable<RealTimePositionRisksDTO> sList = null;
sList = SearchList(req).rows;
if (sList == null || sList.Count() == 0)
{
throw new ServiceException("没有可导出的数据");
}
var isPvRounded = PS.Config.IsPVRounded;
var results = new List<Dictionary<string, string>>(sList.Count());
foreach (var item in sList)
{
var dic = new Dictionary<string, string>();
if (string.IsNullOrWhiteSpace(item.UnderlyingCode))
{
item.DeltaLots = 0;
item.GammaLots = 0;
}
dic.Add("交易编号", item.TradeNumber);
dic.Add("分组名", item.GroupName);
dic.Add("确认书编号", item.ContractCode);
dic.Add("期权代码", item.ExchangeOptionCode);
dic.Add("多腿编号", item.ChildLeg);
dic.Add("浮动盈亏", (isPvRounded ? item.RoundedPositionPnl : item.PositionPnl).OtcFormatMoney());
dic.Add("实现盈亏", item.RealizedPnl.OtcFormatMoney());
dic.Add("TraderName", item.TraderName);
dic.Add("当前波动率", item.CurrentVolatility.OtcFormatFlex(2, 2, percent: true));
dic.Add("Delta", OtcFormatExtensions.OtcFormat(item.Delta, OtcFormatFlag.greek));
dic.Add("Delta手数", OtcFormatExtensions.OtcFormat(item.DeltaLots, OtcFormatFlag.notional));
dic.Add("Gamma", OtcFormatExtensions.OtcFormat(item.Gamma, OtcFormatFlag.greek));
dic.Add("Gamma手数", OtcFormatExtensions.OtcFormat(item.GammaLots, OtcFormatFlag.notional));
dic.Add("Theta", OtcFormatExtensions.OtcFormat(item.Theta, OtcFormatFlag.greek));
dic.Add("Rho", OtcFormatExtensions.OtcFormat(item.Rho, OtcFormatFlag.greek));
dic.Add("Vega", OtcFormatExtensions.OtcFormat(item.Vega, OtcFormatFlag.greek));
dic.Add("到期日期", item.ExerciseDate.OtcFormatDate());
dic.Add("行权方式", TradeHelper.GetExerciseModeCn(item.ExerciseMode));
dic.Add("结构类型", item.StructureType);
dic.Add("观察状态", item.KnockInOutStatus);
dic.Add("交易对手方", item.ClientName);
dic.Add("交易对手编号", item.ClientNumber);
dic.Add("簿记账户", item.AssetBookName);
dic.Add("成交日期", item.TradeDate.OtcFormatDate());
dic.Add("看涨看跌", item.OptionType);
dic.Add("买卖方向", item.BuySell);
dic.Add("标的代码", item.UnderlyingCode);
dic.Add("标的品种", item.UnderlyingVariety);
dic.Add("标的名称", item.UnderlyingAssetName);
dic.Add("期初标的价格", item.InitialSpotPrice.OtcFormatUmPrice());
dic.Add("保底收益总额", item.OriginalPrincipalSum.OtcFormatUmPrice());
if (item.TradeType == "自定义交易")
{
dic.Add("执行价格", string.Empty);
}
else
{
dic.Add("执行价格", item.Strike.OtcFormatUmPrice(item.IsMoneynessOption == "是"));
}
if (item.IsUsePremiumRate == true)
{
dic.Add("权利金成交", item.PremiumRate.OtcFormat(OtcFormatFlag.premiumRateP));
}
else
{
dic.Add("权利金成交", (item.TradeSinglePrice ?? 0).OtcFormat(OtcFormatFlag.tradeSinglePrice));
}
var tradeOriginalAmount = PS.Config.IsUseDisplayNotional ? Math.Abs((item.TradeOriginalAmount ?? 0) * (item.CountRatio ?? 1)) : Math.Abs(item.TradeOriginalAmount ?? 0);
var strTradeOriginalAmount = tradeOriginalAmount.OtcFormatNotional();
dic.Add("有效成交数量", strTradeOriginalAmount);
if (item.trade != null)
{
strTradeOriginalAmount = Math.Abs(CalculationModule.TradeCalcHelper.GetTradeAmountV(item.trade, tradeOriginalAmount, 1)).OtcFormatNotional();
}
dic.Add("成交数量", strTradeOriginalAmount);
var tradeDirection = item.BuySell == "买入" || item.BuySell == "多头开仓" || item.BuySell == "空头开仓" ? -1 : 1;
dic.Add("成交金额", (item.TradePrice * tradeDirection).OtcFormatMoney());
dic.Add("存续成本", (item.IsGroup == 1 ? item.etcTradePrice : item.etcTradePrice * tradeDirection).OtcFormatMoney());
dic.Add("名义本金", item.StockEqvNotionalToShow.OtcFormat(OtcFormatFlag.StockEqvNotional));
dic.Add("存续名义本金", item.SurvivingNominalPrincipal.OtcFormat(OtcFormatFlag.StockEqvNotional));
dic.Add("最新标的价格", item.UnderlyingPrice.OtcFormatUmPrice());
dic.Add("无风险利率", item.RiskFreeRate.OtcFormatFlex(2, 2, percent: true));
dic.Add("分红率", item.DividendRate.OtcFormatFlex(2, 2, percent: true));
if (item.IsUsePremiumRate == true)
{
var dd = TradeHelper.GetPremiumRateByTradeSinglePrice(item.SinglePV, item.InitialSpotPrice);
dic.Add("权利金存续", dd.OtcFormat(OtcFormatFlag.premiumRateP));
}
else
{
dic.Add("权利金存续", item.SinglePV.HasValue ? Convert.ToDouble(item.SinglePV.Value).OtcFormat(OtcFormatFlag.tradePrice) : "");
}
var tradeAmount = PS.Config.IsUseDisplayNotional ? Math.Abs((item.TradeAmount * (item.CountRatio ?? 1)) ?? 0) : Math.Abs(item.TradeAmount ?? 0);
var strTradeAmount = tradeAmount.OtcFormatNotional();
dic.Add("有效存续数量", strTradeAmount);
if (item.trade != null)
{
strTradeAmount = Math.Abs(CalculationModule.TradeCalcHelper.GetTradeAmountV(item.trade, tradeAmount, 1)).OtcFormatNotional();
}
dic.Add("存续数量", strTradeAmount);
var pv = Convert.ToDouble((isPvRounded ? item.RoundedPV : item.PV) ?? 0);
dic.Add("存续市值", pv.OtcFormatMoney());
dic.Add("计算标的价格", item.CalSpotPrice.OtcFormatMoney());
dic.Add("维持预付金", item.Margin.OtcFormatMoney());
results.Add(dic);
}
return results;
}
}
}