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

2178 lines
112 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using YLErp.BLL.Eod;
using YLErp.BLL;
using YLErp.Modules.RiskExposure;
using YLErp.Modules.MarketRiskMoudule.Dto;
using Dapper;
using YLErp.Modules.RiskExposure.Dto;
using YLErp.Modules.CalculationModule;
using System.Data.Common;
using NPOI.OpenXmlFormats.Dml;
using MathNet.Numerics.Distributions;
using NPOI.SS.Formula.Functions;
using YLErp.Modules.DataProviderModule;
using System.Diagnostics;
using System.Linq.Extend;
using YLErp.Modules.EodModule;
using Microsoft.Office.Interop.Word;
using System.Linq.Expressions;
using YLErp.Model;
using YLErp.DBModels;
using YLErp.Modules.ReportModule;
using Qdp.Foundation.Implementations;
using MySqlConnector;
using NPOI.Util;
using Qdp.Foundation.Utilities;
using static iTextSharp.text.pdf.XfaForm;
namespace YLErp.Modules.MarketRiskMoudule
{
/// <summary>
/// 市场风险服务,查询市场风险数据
/// </summary>
/// <typeparam name="eodPosition"></typeparam>
public class MarketRiskService<eodPosition> : YLBaseService where eodPosition : EodTradePosition
{
public MarketRiskService(OptUserInfo userInfo) : base(userInfo)
{ }
/// <summary>
/// 查询市场风险数据
/// </summary>
/// <typeparam name="eodRisk"></typeparam>
/// <typeparam name="eodPnl"></typeparam>
/// <param name="reqModel"></param>
/// <returns></returns>
public RiskExposureReportModel SearchMarketRiskData<eodRisk, eodPnl>(RiskRequestModel reqModel) where eodRisk : EodTradeRisk where eodPnl : EodPnl
{
reqModel = new RiskExposureReportService<eodPosition>(OptUser).CheckModel(reqModel);
// 1、确定三点 T1 T1~T2 T2
// T1
var startDate = EodOperationBase.GetLastSettlementDate(reqModel.ValueDateStart ?? valuedateBLL.SystemDate.AccruedTotalPnlStartDate ?? DateTime.Today);
var dateT1 = EodOperationBase.GetLastSettlementDate(startDate.AddDays(-1));
// T2
var dateT2 = reqModel.ValueDateEnd;
var preDateT2 = EodOperationBase.GetLastSettlementDate(dateT2, true);
List<T1DataDto> t1Datas = null;
List<T2PositionDataDto> t2PositionDatas = null;
List<T2RiskDataDto> t2RiskDatas = null;
List<T2PnlDataDto> t2PnlDatas = null;
List<T1ToT2DataDto> t1ToT2Datas = null;
List<EodTradeJsonDto> eodDatas = null;
List<PreDateT2DataDto> preDateT2Datas = null;
// 2、查询三点数据
GetT1AndT2SourceData<eodRisk, eodPnl>(reqModel, dateT1, dateT2, preDateT2, out t1Datas, out t2PositionDatas, out t2RiskDatas, out t2PnlDatas, out t1ToT2Datas, out eodDatas,out preDateT2Datas);
// 3、数组组装
var riskExposureItemModels = GetRisExposureItemList(t1Datas, t2PositionDatas, t2RiskDatas, t2PnlDatas, t1ToT2Datas, eodDatas,preDateT2Datas);
var result= GetRiskExposureReportModel<eodRisk>(reqModel, startDate, dateT1, riskExposureItemModels, t1ToT2Datas, t2PositionDatas, t2RiskDatas, t2PnlDatas, t1Datas);
return result;
}
public void MakeCondition(RiskRequestModel reqModel, out string tradeWhere, out string onSiteTradeWhere, out string predicateWhere,out string inSiteWhere)
{
tradeWhere = "IFNULL(ValidState,'')<>'InValid'";
onSiteTradeWhere = " IsValid=1";
predicateWhere = " ValueDate=@EndTime and TradeType<>'结构化交易' and TradeType<>'现金流交易'";
tradeWhere += " and TradeType<>'结构化交易' and TradeType<>'现金流交易'";
inSiteWhere= "TradeType<>'结构化交易' and TradeType<>'现金流交易'";
if (reqModel.UserAssets != null && reqModel.UserAssets.Count > 0 && !(reqModel.UserClients != null && reqModel.UserClients.Count > 0))
{
tradeWhere += " and AssetId in @UserAssets";
predicateWhere += " and BookId in @UserAssets";
onSiteTradeWhere += " and AssetBookId in @UserAssets";
inSiteWhere += " and BookId in @UserAssets";
}
if (!(reqModel.UserAssets != null && reqModel.UserAssets.Count > 0) && (reqModel.UserClients != null && reqModel.UserClients.Count > 0))
{
tradeWhere += " and ClientId in @UserClients";
predicateWhere += " and ClientId in @UserClients";
inSiteWhere += " and ClientId in @UserClients";
}
if ((reqModel.UserAssets != null && reqModel.UserAssets.Count > 0) && (reqModel.UserClients != null && reqModel.UserClients.Count > 0))
{
tradeWhere += " and (AssetId in @UserAssets or ClientId in @UserClients)";
predicateWhere += " and (BookId in @UserAssets or ClientId in @UserClients)";
onSiteTradeWhere += " and AssetBookId in @UserAssets";
inSiteWhere += " and (BookId in @UserAssets or ClientId in @UserClients)";
}
if (reqModel.ClientIds != null && reqModel.ClientIds.Count > 0)
{
predicateWhere += " and ClientId in @ClientIds";
tradeWhere += " and ClientId in @ClientIds";
inSiteWhere += " and ClientId in @ClientIds";
}
if (reqModel.BookIds != null && reqModel.BookIds.Count > 0)
{
predicateWhere += " and BookId in @BookIds";
tradeWhere += " and AssetId in @BookIds";
onSiteTradeWhere += " and AssetBookId in @BookIds";
inSiteWhere += " and BookId in @BookIds";
}
if (reqModel.TradeTypes != null && reqModel.TradeTypes.Any())
{
predicateWhere += " and ((IFNULL(StructureType,'')='' and TradeType in @TradeTypes) or (IFNULL(StructureType,'')<>'' and StructureType in @TradeTypes))";
tradeWhere += " and ((IFNULL(StructureType,'')='' and TradeType in @TradeTypes) or (IFNULL(StructureType,'')<>'' and StructureType in @TradeTypes))";
inSiteWhere += " and ((IFNULL(StructureType,'')='' and TradeType in @TradeTypes) or (IFNULL(StructureType,'')<>'' and StructureType in @TradeTypes))";
}
if (reqModel.TraderIds != null && reqModel.TraderIds.Any())
{
predicateWhere += " and TradeId>0";
tradeWhere += " and TraderId in @TraderIds";
inSiteWhere += " and TradeId>0";
}
if (reqModel.TagIds != null && reqModel.TagIds.Count > 0)
{
tradeWhere += " and id in (select TradeId from trade_tag where TagId in @TagIds)";
}
if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any() && reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
inSiteWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
}
else
{
if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
inSiteWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
}
if (reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
inSiteWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
}
}
predicateWhere += String.Format(" and (TradeId<1 or TradeId in (select id from trade where {0}))", tradeWhere);
}
public RiskExposureReportModel GetRiskExposureReportModel<eodRisk>(RiskRequestModel reqModel, DateTime startDate, DateTime preDate, List<RiskExposureItemModel> eodPnlListEnd, List<T1ToT2DataDto> t1ToT2Datas,List<T2PositionDataDto> t2PositionDatas,List<T2RiskDataDto> t2RiskDatas,List<T2PnlDataDto> t2PnlDatas, List<T1DataDto> t1Datas) where eodRisk : EodTradeRisk
{
RiskExposureReportModel result;
var dataProvider = new EodRiskCalcDataProvider(reqModel.ValueDateEnd, startDate);
//合并处理
var underlyingGroup = eodPnlListEnd.GroupBy(e => e.UnderlyingCode.ToUpperInvariant());
var underlyingIdList = underlyingGroup.Select(g => g.Key).ToList();
var underlyingRiskList = new List<UnderlyingRiskModel>();
var exchangeOptionRisks = CalculateExchangeListOptionRisks<eodRisk>(reqModel.ValueDateEnd, reqModel,t2PositionDatas,t2RiskDatas,t2PnlDatas);//获取场内交易数据
var settlementType = ConsGlobal.SettlePriceMode.GetSettlementType(reqModel.EodSettlePriceMode.TrimToNull() ?? valuedateBLL.SystemDate.EodSettlePriceMode);
List<underlying_manager> umList = null;
List<Variety> varietyList = null;
List<VarietyLimit> limitList = null;
var umCodeList = underlyingGroup.Select(p => p.Key).Distinct().ToList();
if (umCodeList != null && umCodeList.Count > 0)
{
umList = DbContext.underlying_manager.AsNoTracking().Where(p => umCodeList.Contains(p.UnderlyingCode)).ToList();
if (umList != null && umList.Count > 0)
{
var umTypeIds = umList.Select(p => p.UnderlyingTypeId).Distinct().ToList();
varietyList = DbContext.variety.AsNoTracking().Where(p => umTypeIds.Contains(p.id)).ToList();
}
if (varietyList != null && varietyList.Count > 0)
{
var varietyCodes = varietyList.Select(p => p.VarietyCode).Distinct().ToList();
limitList = DbContext.variety_limit.AsNoTracking().Where(p => varietyCodes.Contains(p.VarietyCode)).ToList();
}
}
if (umList == null)
{
umList = new List<underlying_manager>();
}
if (varietyList == null)
{
varietyList = new List<Variety>();
}
if (limitList == null)
{
limitList = new List<VarietyLimit>();
}
#region 1.对于最后一日有持仓数据的合约
foreach (var groupItem in underlyingGroup)
{
dataProvider.TryGetEodPrice(groupItem.Key, settlementType, out var price);
var underlyingRisk = new UnderlyingRiskModel();
var underlying = umList.FirstOrDefault(d => d.UnderlyingCode.Equals(groupItem.Key));
Variety variety = null;
if (underlying != null)
{
variety = varietyList.FirstOrDefault(d => d.id == underlying.UnderlyingTypeId);
//var variety_limit = variety == null ? null : DbContext.variety_limit.FirstOrDefault(o => o.VarietyCode == variety.VarietyCode);
var variety_limit = variety == null ? null : limitList.FirstOrDefault(o => o.VarietyCode == variety.VarietyCode);
underlyingRisk.UnderlyingId = underlying.id;
underlyingRisk.UnderlyingCode = underlying.UnderlyingCode;
underlyingRisk.UnderlyingPrice = price;
underlyingRisk.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType;
underlyingRisk.VarietyCode = underlying.CommodityCode == "组合标的" ? "组合标的" : (variety == null ? underlying.UnderlyingType : variety.VarietyCode);
underlyingRisk.VarietyOpenLimitIcon = variety == null || !(variety_limit?.IsPercent ?? false) ? "¥" : "%";
underlyingRisk.VarietyLimit = variety_limit;
}
else
{
underlying = dataProvider.GetUnderlying(groupItem.Key);
if (underlying == null)
{
throw new ServiceException("标的数据不存在:" + groupItem.Key);
}
variety = DbContext.variety.Find(underlying.UnderlyingTypeId);
var variety_limit = variety == null ? null : DbContext.variety_limit.FirstOrDefault(o => o.VarietyCode == variety.VarietyCode);
underlyingRisk.UnderlyingId = underlying.id;
underlyingRisk.UnderlyingCode = underlying.UnderlyingCode;
underlyingRisk.UnderlyingPrice = price;
underlyingRisk.UnderlyingInstrumentType = underlying.UnderlyingInstrumentType;
underlyingRisk.VarietyCode = underlying.CommodityCode == "组合标的" ? "组合标的" : (variety == null ? underlying.UnderlyingType : variety.VarietyCode);
underlyingRisk.VarietyOpenLimitIcon = variety == null || !(variety_limit?.IsPercent ?? false) ? "¥" : "%";
underlyingRisk.VarietyLimit = variety_limit;
}
if (underlying.CommodityCode == "组合标的")
{
underlyingRisk.SyntheticUnderlyingTipsInfo = synthetic_underlyingBLL.GetUnderlyingTipsInfo(underlying.UnderlyingCode);
}
var otcOptionsTradeType = ConsTrade.OptionTradeTypes.ToList();
otcOptionsTradeType.Add("结构化交易");
otcOptionsTradeType.AddRange(DbContext.Structure_Info.Select(o => o.StructureName));
otcOptionsTradeType.Remove("收益互换");
//场外期权
var otcRiskList = groupItem.Where(g => otcOptionsTradeType.Contains(g.TradeType));
underlyingRisk.OtcRisk = new EodRiskModel
{
StockEqvNotional = otcRiskList.SumDouble(r => r.StockEqvNotional),
StockEqvNotionalReal = otcRiskList.SumDouble(r => r.StockEqvNotionalReal),
Pnl = otcRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0),
Delta = otcRiskList.SumDouble(r => r.Delta ?? 0),
DeltaCash = otcRiskList.SumDouble(r => r.DeltaCash ?? 0),
GammaCash = otcRiskList.SumDouble(r => r.GammaCash ?? 0),
PositionStockEqvNotional = otcRiskList.SumDouble(r => (r.Amount * r.SpotPrice) ?? 0),
Gamma = otcRiskList.SumDouble(r => r.Gamma ?? 0),
Theta = otcRiskList.SumDouble(r => r.Theta ?? 0),
Vega = otcRiskList.SumDouble(r => r.Vega ?? 0),
Rho = otcRiskList.SumDouble(r => r.Rho ?? 0),
DailyPnl = otcRiskList.SumDouble(r => r.DailyPnl ?? 0),
dPnlDelta = otcRiskList.SumDouble(r => r.dPnlDelta),
dPnlGamma = otcRiskList.SumDouble(r => r.dPnlGamma),
dPnlTheta = otcRiskList.SumDouble(r => r.dPnlTheta),
dPnlVega = otcRiskList.SumDouble(r => r.dPnlVega),
dPnlPsi = otcRiskList.SumDouble(r => r.dPnlPsi),
CumulativeFloatProfitLoss = otcRiskList.SumDouble(r => r.CumulativeFloatProfitLoss)
};
underlyingRisk.OtcRisk.DeltaInLots = TradeLotsCalc.CalcDeltaInLots(Convert.ToDouble(underlyingRisk.OtcRisk.Delta), variety, underlying);
underlyingRisk.OtcRisk.GammaInLots = TradeLotsCalc.CalcGammaInLots(Convert.ToDouble(underlyingRisk.OtcRisk.Gamma), variety, underlying);
//场内期权
var exchangeRiskList = groupItem.Where(g => g.TradeType == "场内期权");
//var preValueDateCommissionExOptSum = underlyingPreValueDateCommissionList.Where(x => x.AssetType == "场内期权").SumDouble(x => x.TotalCommission);
var underlyingExchangeRisks = exchangeOptionRisks.Where(r => r.UnderlyingCode.Equals(groupItem.Key, StringComparison.OrdinalIgnoreCase));
underlyingRisk.ExOptionRisk = new EodRiskModel
{
Pnl = exchangeRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0),
Delta = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize((double)r.Delta)),
DeltaCash = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize(r.DeltaCash)),
GammaCash = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize(r.GammaCash)),
StockEqvNotional = exchangeRiskList.SumDouble(r =>
{
var exoption = DataCacheProvider.GetExchangeListOptionDataSource().GetData(r.OptionCode);
return exoption == null ? 0 : NumberHelper.Abs(r.Amount * exoption.Strike);
}),
Gamma = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize((double)r.Gamma)),
Theta = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize((double)r.Theta)),
Vega = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize((double)r.Vega)),
Rho = underlyingExchangeRisks.SumDouble(r => NumberHelper.Normalize((double)r.Rho)),
DailyCommission = exchangeRiskList.SumDouble(r => r.DailyCommission),//当日累计 - 昨日累计 = 当日手续费
DailyPnl = exchangeRiskList.SumDouble(r => r.DailyPnl ?? 0),
dPnlDelta = exchangeRiskList.SumDouble(r => r.dPnlDelta),
dPnlGamma = exchangeRiskList.SumDouble(r => r.dPnlGamma),
dPnlTheta = exchangeRiskList.SumDouble(r => r.dPnlTheta),
dPnlVega = exchangeRiskList.SumDouble(r => r.dPnlVega),
dPnlPsi = exchangeRiskList.SumDouble(r => r.dPnlPsi),
CumulativeFloatProfitLoss = exchangeRiskList.SumDouble(r => r.CumulativeFloatProfitLoss),
Commission = exchangeRiskList.SumDouble(r => r.Commission)
};
underlyingRisk.ExOptionRisk.StockEqvNotionalReal = underlyingRisk.ExOptionRisk.StockEqvNotional;
underlyingRisk.ExOptionRisk.DeltaInLots = TradeLotsCalc.CalcDeltaInLots(Convert.ToDouble(underlyingRisk.ExOptionRisk.Delta), variety, underlying);
underlyingRisk.ExOptionRisk.GammaInLots = TradeLotsCalc.CalcGammaInLots(Convert.ToDouble(underlyingRisk.ExOptionRisk.Gamma), variety, underlying);
//标的交易
var hedgeRiskList = groupItem.Where(g => g.TradeType == "商品期货" || g.TradeType == "股票" || g.TradeType == "商品现货");
underlyingRisk.FuturesRisk = new EodRiskModel
{
Pnl = hedgeRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0),
Position = hedgeRiskList.SumDouble(r => r.Amount),
StockEqvNotional = hedgeRiskList.SumDouble(r => NumberHelper.Abs(r.Amount * price)),
Commission = hedgeRiskList.SumDouble(r => r.Commission),
DailyCommission = hedgeRiskList.SumDouble(r => r.DailyCommission),//当日累计 - 昨日累计 = 当日手续费
DailyPnl = hedgeRiskList.SumDouble(r => r.DailyPnl ?? 0)
};
underlyingRisk.FuturesRisk.StockEqvNotionalReal = underlyingRisk.FuturesRisk.StockEqvNotional;
underlyingRisk.FuturesRisk.PositionInLots = TradeLotsCalc.CalcDeltaInLots(Convert.ToDouble(underlyingRisk.FuturesRisk.Position), variety, underlying);
underlyingRisk.FuturesRisk.PositionIncrementInLots = underlyingRisk.FuturesRisk.PositionInLots - 0;// tartPositionInLots;
underlyingRisk.FuturesRisk.Delta = underlyingRisk.FuturesRisk.Position;
underlyingRisk.FuturesRisk.DeltaCash = underlyingRisk.UnderlyingPrice * underlyingRisk.FuturesRisk.Delta ?? 0;
underlyingRisk.FuturesRisk.GammaCash = underlyingRisk.UnderlyingPrice * underlyingRisk.FuturesRisk.Gamma ?? 0;
underlyingRisk.FuturesRisk.DeltaInLots = underlyingRisk.FuturesRisk.PositionInLots;
//远期统计
var forwardRiskList = groupItem.Where(g => g.TradeType == "远期");
underlyingRisk.ForwardRisk = new EodRiskModel
{
Pnl = forwardRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0),
Delta = forwardRiskList.SumDouble(r => r.Delta ?? 0),
DeltaCash = forwardRiskList.SumDouble(r => r.DeltaCash ?? 0),
GammaCash = forwardRiskList.SumDouble(r => r.GammaCash ?? 0),
PositionStockEqvNotional = forwardRiskList.SumDouble(r => (r.Amount * r.SpotPrice) ?? 0),
DailyPnl = forwardRiskList.SumDouble(r => r.DailyPnl ?? 0)
};
underlyingRisk.ForwardRisk.DeltaInLots = TradeLotsCalc.CalcDeltaInLots(Convert.ToDouble(underlyingRisk.ForwardRisk.Delta), variety, underlying);
//收益互换统计
var swapRiskList = groupItem.Where(g => g.TradeType == "收益互换");
underlyingRisk.SwapRisk = new EodRiskModel
{
StockEqvNotional = swapRiskList.SumDouble(r => NumberHelper.Abs(r.StockEqvNotional)),
StockEqvNotionalReal = swapRiskList.SumDouble(r => NumberHelper.Abs(r.StockEqvNotionalReal)),
Pnl = swapRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0),
Delta = swapRiskList.SumDouble(r => r.Delta ?? 0),
DeltaCash = swapRiskList.SumDouble(r => r.DeltaCash ?? 0),
GammaCash = swapRiskList.SumDouble(r => r.GammaCash ?? 0),
PositionStockEqvNotional = swapRiskList.SumDouble(r => (r.Amount * r.SpotPrice) ?? 0),
DailyPnl = swapRiskList.SumDouble(r => r.DailyPnl ?? 0)
};
underlyingRisk.SwapRisk.DeltaInLots = TradeLotsCalc.CalcDeltaInLots(Convert.ToDouble(underlyingRisk.SwapRisk.Delta), variety, underlying);
//汇总合计
underlyingRisk.PortfolioRisk = new EodRiskModel
{
StockEqvNotional = underlyingRisk.OtcRisk.StockEqvNotional + underlyingRisk.ExOptionRisk.StockEqvNotional + underlyingRisk.FuturesRisk.StockEqvNotional + /*underlyingRisk.ForwardRisk.StockEqvNotional +*/ underlyingRisk.SwapRisk.StockEqvNotional,
StockEqvNotionalReal = underlyingRisk.OtcRisk.StockEqvNotionalReal + underlyingRisk.ExOptionRisk.StockEqvNotionalReal + underlyingRisk.FuturesRisk.StockEqvNotionalReal + /*underlyingRisk.ForwardRisk.StockEqvNotionalReal +*/ underlyingRisk.SwapRisk.StockEqvNotionalReal,
OtcStockEqvNotional = underlyingRisk.OtcRisk.StockEqvNotional + underlyingRisk.SwapRisk.StockEqvNotional,
OtcStockEqvNotionalReal = underlyingRisk.OtcRisk.StockEqvNotionalReal + underlyingRisk.SwapRisk.StockEqvNotionalReal,
Pnl = underlyingRisk.OtcRisk.Pnl + underlyingRisk.ExOptionRisk.Pnl + underlyingRisk.FuturesRisk.Pnl + underlyingRisk.ForwardRisk.Pnl + underlyingRisk.SwapRisk.Pnl,
Delta = underlyingRisk.OtcRisk.Delta + underlyingRisk.ExOptionRisk.Delta + underlyingRisk.FuturesRisk.Delta + underlyingRisk.ForwardRisk.Delta + underlyingRisk.SwapRisk.Delta,
DeltaCash = underlyingRisk.OtcRisk.DeltaCash + underlyingRisk.ExOptionRisk.DeltaCash + underlyingRisk.FuturesRisk.DeltaCash + underlyingRisk.ForwardRisk.DeltaCash + underlyingRisk.SwapRisk.DeltaCash,
GammaCash = underlyingRisk.OtcRisk.GammaCash + underlyingRisk.ExOptionRisk.GammaCash + underlyingRisk.FuturesRisk.GammaCash + underlyingRisk.ForwardRisk.GammaCash + underlyingRisk.SwapRisk.GammaCash,
PositionStockEqvNotional = underlyingRisk.OtcRisk.PositionStockEqvNotional + underlyingRisk.ExOptionRisk.PositionStockEqvNotional + underlyingRisk.ForwardRisk.PositionStockEqvNotional + underlyingRisk.SwapRisk.PositionStockEqvNotional,
DeltaInLots = underlyingRisk.OtcRisk.DeltaInLots + underlyingRisk.ExOptionRisk.DeltaInLots + underlyingRisk.FuturesRisk.DeltaInLots + underlyingRisk.ForwardRisk.DeltaInLots + underlyingRisk.SwapRisk.DeltaInLots,
DailyPnl = underlyingRisk.OtcRisk.DailyPnl + underlyingRisk.ExOptionRisk.DailyPnl + underlyingRisk.FuturesRisk.DailyPnl + +underlyingRisk.ForwardRisk.DailyPnl + +underlyingRisk.SwapRisk.DailyPnl,
Commission = underlyingRisk.ExOptionRisk.Commission + underlyingRisk.FuturesRisk.Commission,
Gamma = underlyingRisk.OtcRisk.Gamma + underlyingRisk.ExOptionRisk.Gamma,
Theta = underlyingRisk.OtcRisk.Theta + underlyingRisk.ExOptionRisk.Theta,
Vega = underlyingRisk.OtcRisk.Vega + underlyingRisk.ExOptionRisk.Vega,
Rho = underlyingRisk.OtcRisk.Rho + underlyingRisk.ExOptionRisk.Rho,
dPnlDelta = underlyingRisk.OtcRisk.dPnlDelta + underlyingRisk.ExOptionRisk.dPnlDelta,
dPnlGamma = underlyingRisk.OtcRisk.dPnlGamma + underlyingRisk.ExOptionRisk.dPnlGamma,
dPnlTheta = underlyingRisk.OtcRisk.dPnlTheta + underlyingRisk.ExOptionRisk.dPnlTheta,
dPnlVega = underlyingRisk.OtcRisk.dPnlVega + underlyingRisk.ExOptionRisk.dPnlVega,
dPnlPsi = underlyingRisk.OtcRisk.dPnlPsi + underlyingRisk.ExOptionRisk.dPnlPsi,
CumulativeFloatProfitLoss = underlyingRisk.OtcRisk.CumulativeFloatProfitLoss + underlyingRisk.ExOptionRisk.CumulativeFloatProfitLoss,
};
underlyingRiskList.Add(underlyingRisk);
}
#endregion
underlyingRiskList = underlyingRiskList.OrderBy(u => u, new UnderlyingRiskModelSortComparer()).ToList();
var varietyRiskExposureReports = underlyingRiskList.GroupBy(u => new { u.VarietyCode, u.VarietyOpenLimit, u.VarietyOpenLimitIcon }).Select(g =>
{
var list = g.ToList();
var portfolioSum = new EodRiskModel
{
StockEqvNotional = list.SumDouble(l => l.PortfolioRisk.StockEqvNotional),
StockEqvNotionalReal = list.SumDouble(l => l.PortfolioRisk.StockEqvNotionalReal),
OtcStockEqvNotional = list.SumDouble(l => l.PortfolioRisk.OtcStockEqvNotional),
OtcStockEqvNotionalReal = list.SumDouble(l => l.PortfolioRisk.OtcStockEqvNotionalReal),
Pnl = list.SumDouble(l => l.PortfolioRisk.Pnl),
Delta = list.SumDouble(l => l.PortfolioRisk.Delta),
DeltaCash = list.SumDouble(l => l.PortfolioRisk.DeltaCash),
GammaCash = list.SumDouble(l => l.PortfolioRisk.GammaCash),
PositionStockEqvNotional = list.SumDouble(l => l.PortfolioRisk.PositionStockEqvNotional),
DeltaInLots = list.SumDouble(l => l.PortfolioRisk.DeltaInLots),
DailyPnl = list.SumDouble(l => l.PortfolioRisk.DailyPnl),
Commission = list.SumDouble(l => l.PortfolioRisk.Commission),
Gamma = list.SumDouble(l => l.PortfolioRisk.Gamma),
Theta = list.SumDouble(l => l.PortfolioRisk.Theta),
Vega = list.SumDouble(l => l.PortfolioRisk.Vega),
Rho = list.SumDouble(l => l.PortfolioRisk.Rho),
dPnlDelta = list.SumDouble(l => l.PortfolioRisk.dPnlDelta),
dPnlGamma = list.SumDouble(l => l.PortfolioRisk.dPnlGamma),
dPnlTheta = list.SumDouble(l => l.PortfolioRisk.dPnlTheta),
dPnlVega = list.SumDouble(l => l.PortfolioRisk.dPnlVega),
dPnlPsi = list.SumDouble(l => l.PortfolioRisk.dPnlPsi),
CumulativeFloatProfitLoss = list.SumDouble(l => l.PortfolioRisk.CumulativeFloatProfitLoss),
};
var otcSum = new EodRiskModel
{
StockEqvNotional = list.SumDouble(l => l.OtcRisk.StockEqvNotional),
StockEqvNotionalReal = list.SumDouble(l => l.OtcRisk.StockEqvNotionalReal),
Pnl = list.SumDouble(l => l.OtcRisk.Pnl),
Delta = list.SumDouble(l => l.OtcRisk.Delta),
DeltaInLots = list.SumDouble(l => l.OtcRisk.DeltaInLots),
Gamma = list.SumDouble(l => l.OtcRisk.Gamma),
GammaInLots = list.SumDouble(l => l.OtcRisk.GammaInLots),
Theta = list.SumDouble(l => l.OtcRisk.Theta),
Vega = list.SumDouble(l => l.OtcRisk.Vega),
Rho = list.SumDouble(l => l.OtcRisk.Rho),
DailyPnl = list.SumDouble(l => l.OtcRisk.DailyPnl),
DeltaCash = list.SumDouble(l => l.OtcRisk.DeltaCash),
dPnlDelta = list.SumDouble(l => l.OtcRisk.dPnlDelta),
dPnlGamma = list.SumDouble(l => l.OtcRisk.dPnlGamma),
dPnlTheta = list.SumDouble(l => l.OtcRisk.dPnlTheta),
dPnlVega = list.SumDouble(l => l.OtcRisk.dPnlVega),
dPnlPsi = list.SumDouble(l => l.OtcRisk.dPnlPsi),
CumulativeFloatProfitLoss = list.SumDouble(l => l.OtcRisk.CumulativeFloatProfitLoss),
};
var exchangeListOptionSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.ExOptionRisk.Pnl),
Delta = list.SumDouble(l => l.ExOptionRisk.Delta),
DeltaInLots = list.SumDouble(l => l.ExOptionRisk.DeltaInLots),
Gamma = list.SumDouble(l => l.ExOptionRisk.Gamma),
GammaInLots = list.SumDouble(l => l.ExOptionRisk.GammaInLots),
Theta = list.SumDouble(l => l.ExOptionRisk.Theta),
Vega = list.SumDouble(l => l.ExOptionRisk.Vega),
Rho = list.SumDouble(l => l.ExOptionRisk.Rho),
Commission = list.SumDouble(l => l.ExOptionRisk.Commission),
DailyPnl = list.SumDouble(l => l.ExOptionRisk.DailyPnl),
DailyCommission = list.SumDouble(l => l.ExOptionRisk.DailyCommission),
DeltaCash = list.SumDouble(l => l.ExOptionRisk.DeltaCash),
StockEqvNotional = list.SumDouble(l => l.ExOptionRisk.StockEqvNotional),
StockEqvNotionalReal = list.SumDouble(l => l.ExOptionRisk.StockEqvNotionalReal),
dPnlDelta = list.SumDouble(l => l.ExOptionRisk.dPnlDelta),
dPnlGamma = list.SumDouble(l => l.ExOptionRisk.dPnlGamma),
dPnlTheta = list.SumDouble(l => l.ExOptionRisk.dPnlTheta),
dPnlVega = list.SumDouble(l => l.ExOptionRisk.dPnlVega),
dPnlPsi = list.SumDouble(l => l.ExOptionRisk.dPnlPsi),
CumulativeFloatProfitLoss = list.SumDouble(l => l.ExOptionRisk.CumulativeFloatProfitLoss),
};
var futuresSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.FuturesRisk.Pnl),
Position = list.SumDouble(l => l.FuturesRisk.Position),
PositionInLots = list.SumDouble(l => l.FuturesRisk.PositionInLots),
PositionIncrementInLots = list.SumDouble(l => l.FuturesRisk.PositionIncrementInLots),
Commission = list.SumDouble(l => l.FuturesRisk.Commission),
DailyPnl = list.SumDouble(l => l.FuturesRisk.DailyPnl),
DailyCommission = list.SumDouble(l => l.FuturesRisk.DailyCommission),
StockEqvNotional = list.SumDouble(l => l.FuturesRisk.StockEqvNotional),
StockEqvNotionalReal = list.SumDouble(l => l.FuturesRisk.StockEqvNotionalReal)
};
var forwardSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.ForwardRisk.Pnl),
Delta = list.SumDouble(l => l.ForwardRisk.Delta),
DeltaInLots = list.SumDouble(l => l.ForwardRisk.DeltaInLots),
DailyPnl = list.SumDouble(l => l.ForwardRisk.DailyPnl)
};
var swapSum = new EodRiskModel
{
StockEqvNotional = list.SumDouble(l => l.SwapRisk.StockEqvNotional),
StockEqvNotionalReal = list.SumDouble(l => l.SwapRisk.StockEqvNotionalReal),
Pnl = list.SumDouble(l => l.SwapRisk.Pnl),
Delta = list.SumDouble(l => l.SwapRisk.Delta),
DeltaInLots = list.SumDouble(l => l.SwapRisk.DeltaInLots),
DailyPnl = list.SumDouble(l => l.SwapRisk.DailyPnl)
};
VarietyLimit varietyLimit = list.First().VarietyLimit;
//varietyLimit = limitList.FirstOrDefault(o => o.VarietyCode == g.Key.VarietyCode);
//if (varietyLimit == null)
//{
// varietyLimit= DbContext.variety_limit.FirstOrDefault(o => o.VarietyCode == g.Key.VarietyCode);
//}
return new VarietyRiskExposureModel
{
VarietyCode = g.Key.VarietyCode,
VarietyOpenLimit = g.Key.VarietyOpenLimit,
VarietyOpenLimitIcon = g.Key.VarietyOpenLimitIcon,
VarietySum = new RiskExposureReportSumModel
{
PortfolioSum = portfolioSum,
OtcSum = otcSum,
ExOptionSum = exchangeListOptionSum,
FuturesSum = futuresSum,
ForwardSum = forwardSum,
SwapSum = swapSum
},
UnderlyingRiskList = list,
varietyLimit = varietyLimit ?? new VarietyLimit()
};
}).ToList();
result = new RiskExposureReportModel
{
ReportModels = varietyRiskExposureReports,
//总和盈亏比例计算元素取值逻辑
TotalPnlRate = PS.Config.Is格林大华? CalcTotalPnlRate(startDate, reqModel.ValueDateEnd,t1ToT2Datas,t2PositionDatas, t1Datas):0,
Sum = new RiskExposureReportSumModel
{
PortfolioSum = varietyRiskExposureReports.Select(r => r.VarietySum.PortfolioSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
OtcSum = varietyRiskExposureReports.Select(r => r.VarietySum.OtcSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
ExOptionSum = varietyRiskExposureReports.Select(r => r.VarietySum.ExOptionSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
FuturesSum = varietyRiskExposureReports.Select(r => r.VarietySum.FuturesSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
ForwardSum = varietyRiskExposureReports.Select(r => r.VarietySum.ForwardSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
SwapSum = varietyRiskExposureReports.Select(r => r.VarietySum.SwapSum).Aggregate(new EodRiskModel(), (p, n) => p + n)
}
};
return result;
}
/// <summary>
/// 计算综合盈亏比例: ((收取的权利金 - 支付的权利金) + 对冲盈亏 - 期权估值)/对冲账户成本
/// </summary>
/// <param name="startDate">开始日期(包括)</param>
/// <param name="endDate">结束日期(包括)</param>
public double CalcTotalPnlRate(DateTime startDate, DateTime endDate, List<T1ToT2DataDto> t1ToT2Datas, List<T2PositionDataDto> t2PositionDatas,List<T1DataDto> t1Datas)
{
//对冲盈亏
var totalHedgePnl = GetTotalPnlOfExchangeOption(t1ToT2Datas,t2PositionDatas,t1Datas) + GetTotalPnlSumOfFutures(t1ToT2Datas, t2PositionDatas, t1Datas);
//公司角度期权估值(场外期权)
var totalPv = GetTotalPvOfOptions(t2PositionDatas,t1Datas);
//公司角度(收取的权利金 - 支付的权利金)
var allTotalTradePrice = -(DbContext.ClientBalanceDaily.Where(x => x.BalanceDate == endDate)
.Sum(x => x.OptionPremiumSum) ?? 0) - (DbContext.ClientBalanceDaily.Where(x => x.BalanceDate == endDate)
.Sum(x => x.OptionPremiumSwapSum) ?? 0);
var preStartDate = GetPreDate(startDate);
var lastSettleDateStartDateTotalTradePrice = -(DbContext.ClientBalanceDaily.Where(x => x.BalanceDate == preStartDate)
.Sum(x => x.OptionPremiumSum) ?? 0) - (DbContext.ClientBalanceDaily.Where(x => x.BalanceDate == preStartDate)
.Sum(x => x.OptionPremiumSwapSum) ?? 0);
var totalTradePrice = allTotalTradePrice - lastSettleDateStartDateTotalTradePrice;
//对冲账户成本
var totalInitialCost = DbContext.exchange_account.Sum(x => x.InitialCost) ?? 0;
if (totalInitialCost < 1)
{
totalInitialCost = 1;
}
return (totalTradePrice + totalHedgePnl - Convert.ToDouble(totalPv)) / totalInitialCost;
}
private DateTime GetPreDate(DateTime date)
{
var tmpDate = DbContext.Set<eodPosition>().Where(n => n.ValueDate < date).Max(t => (DateTime?)t.ValueDate);
return tmpDate.HasValue ? tmpDate.Value.Date : DateTime.MinValue;
}
/// <summary>
/// 获取取值日的期权估值(公司角度)
/// </summary>
public double GetTotalPvOfOptions(List<T2PositionDataDto> t2PositionDatas,List<T1DataDto> t1Datas)
{
//当前持仓-起算前
var query = from t1 in t2PositionDatas.Where(n => n.TradeId > 0)
join t2 in t1Datas.Where(n => n.TradeId > 0)
on t1.TradeId equals t2.TradeId into tt
from t2 in tt.DefaultIfEmpty()
select t1.Pv - (t2 == null ? 0 : t2.Pv);
return query.Sum(n => (double?)n) ?? 0;
}
/// <summary>
/// 获取区间内的商品期货pnl合计
/// </summary>
/// <param name="startDate">开始日期(包括)</param>
/// <param name="endDate">结束日期(包括)</param>
public double GetTotalPnlSumOfFutures(List<T1ToT2DataDto> t1ToT2Datas, List<T2PositionDataDto> t2PositionDatas, List<T1DataDto> t1Datas)
{
//------------------------------
// 取值日的持仓统计
//------------------------------
var positionQuery = from eodPnl in t2PositionDatas
where eodPnl.TradeType == "商品期货"
group eodPnl by eodPnl.UnderlyingCode into g
select new
{
g.Key,
totalPnl = g.Sum(n => n.TotalPnL)
};
//------------------------------
// 区间内的过期标的统计
//------------------------------
var finishedQuery = from eodPnl in t1ToT2Datas
where eodPnl.TradeType == "商品期货"
group eodPnl by eodPnl.UnderlyingCode into g
select new
{
g.Key,
totalPnl = g.Sum(n => n.TotalPnL)
};
//------------------------------
// 起算日前一交易日的累计数据
//------------------------------
//var preStartDate = GetPreDate(startDate);
var preStartQuery = from n in t1Datas
where n.TradeType == "商品期货"
select new { n.UnderlyingCode, TotalPnL = (double?)n.TotalPnL };
//------------------------------
// 区间内的数据合计(持仓+到期-起始)
//------------------------------
var totalPnlQuery = from t1 in positionQuery.Concat(finishedQuery)
join t2 in preStartQuery on t1.Key equals t2.UnderlyingCode into tt
from t2 in tt.DefaultIfEmpty()
select t1.totalPnl - (t2?.TotalPnL ?? 0);
return totalPnlQuery.Sum(n => (double?)n) ?? 0;
}
/// <summary>
/// 获取区间内的场内期权pnl合计
/// </summary>
/// <param name="startDate">开始日期(包括)</param>
/// <param name="endDate">结束日期(包括)</param>
public double GetTotalPnlOfExchangeOption(List<T1ToT2DataDto> t1ToT2Datas, List<T2PositionDataDto> t2PositionDatas, List<T1DataDto> t1Datas)
{
//------------------------------
// 取值日的当前持仓统计
//------------------------------
var positionQuery = (from eodPnl in t2PositionDatas
where eodPnl.TradeType == "场内期权"
group eodPnl by eodPnl.ExchangeOptionCode into g
select new
{
g.Key,
totalPnl = g.Sum(n => n.TotalPnL)
}).ToList();
// 已了结交易 统计
var finishedQuery =(from eodPnl in t1ToT2Datas
where eodPnl.TradeType == "场内期权"
group eodPnl by eodPnl.ExchangeOptionCode into g
select new
{
g.Key,
totalPnl = g.Sum(n => n.TotalPnL)
}).ToList();
//------------------------------
// 起算日前一交易日的累计数据
//------------------------------
var preStartQuery = from n in t1Datas
where n.TradeType == "场内期权"
select new { n.ExchangeOptionCode, TotalPnL = (double?)n.TotalPnL };
//------------------------------
// 区间内的累计数据(持仓+到期-起始)
//------------------------------
var totalPnlQuery = from t1 in positionQuery.Concat(finishedQuery)
join t2 in preStartQuery on t1.Key equals t2.ExchangeOptionCode into tt
from t2 in tt.DefaultIfEmpty()
select t1.totalPnl - (t2?.TotalPnL ?? 0);
return totalPnlQuery.Sum(n => (double?)n) ?? 0;
}
private IEnumerable<EodPositionRisksDTO> CalculateExchangeListOptionRisks<eodRisk>(DateTime settleDate, RiskRequestModel reqModel, List<T2PositionDataDto> t2PositionDatas, List<T2RiskDataDto> t2RiskDatas, List<T2PnlDataDto> t2PnlDatas) where eodRisk : EodTradeRisk
{
if (reqModel.ClientIds.Any(n => n > 0) || reqModel.TradeTypes.Any() && !reqModel.TradeTypes.Contains("场内期权"))
{
return Enumerable.Empty<EodPositionRisksDTO>();
}
if (t2PositionDatas == null || t2PositionDatas.Count == 0)
{
return new List<EodPositionRisksDTO>();
}
var varietyIds = reqModel.VarietyIds != null && reqModel.VarietyIds.Any(n => n > 0) ? reqModel.VarietyIds : Enumerable.Empty<int>();
var underlyingIds = reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any(n => n > 0) ? reqModel.UnderlyingIds : Enumerable.Empty<int>();
var onSitePositionDatas = t2PositionDatas.Where(t => t.TradeId < 1 && t.TradeType == "场内期权").ToList();
if (onSitePositionDatas == null || onSitePositionDatas.Count == 0)
{
return new List<EodPositionRisksDTO>();
}
var hedgeUniqueCodeList = onSitePositionDatas.Select(p => p.HedgeUniqueCode).Distinct().ToList();
List<T2RiskDataDto> onSiteRiskDatas = null;
if (t2RiskDatas != null && t2RiskDatas.Count > 0)
{
onSiteRiskDatas = t2RiskDatas.Where(p => hedgeUniqueCodeList.Contains(p.HedgeUniqueCode)).ToList();
}
if (onSiteRiskDatas == null)
{
onSiteRiskDatas = new List<T2RiskDataDto>();
}
var umCodes = onSitePositionDatas.Select(p => p.UnderlyingCode).Distinct().ToList();
List<underlying_manager> umList = null;
if (umCodes != null && umCodes.Count > 0)
{
umList = DbContext.underlying_manager.AsNoTracking().Where(p => umCodes.Contains(p.UnderlyingCode)).ToList();
}
if (umList == null)
{
umList = new List<underlying_manager>();
}
var exchangeOptionCodes = onSitePositionDatas.Select(p => p.ExchangeOptionCode).Distinct().ToList();
List<ExchangeListOption> exchangeListOptionList = null;
if (exchangeOptionCodes != null && exchangeOptionCodes.Count > 0)
{
exchangeListOptionList = DbContext.exchange_list_option.AsNoTracking().Where(p => exchangeOptionCodes.Contains(p.ContractCode)).ToList();
}
if (exchangeListOptionList == null)
{
exchangeListOptionList = new List<ExchangeListOption>();
}
var query = from risk in onSiteRiskDatas
join pos in onSitePositionDatas on risk.HedgeUniqueCode equals pos.HedgeUniqueCode
join un in umList on pos.UnderlyingCode equals un.UnderlyingCode
join ex in exchangeListOptionList on pos.ExchangeOptionCode equals ex.ContractCode
where (!underlyingIds.Any() || underlyingIds.Contains(un.id))
&& (!varietyIds.Any() || varietyIds.Contains(un.UnderlyingTypeId))
select new EodPositionRisksDTO
{
id = -pos.id,
PV = pos.Pv,
RoundedPV = pos.RoundedPv,
PositionPnl = pos.PositionPnL,
RoundedPositionPnl = pos.RoundedPositionPnL,
Vega = risk.Vega,
Theta = risk.Theta,
Rho = risk.Rho,
Delta = risk.Delta,
Gamma = risk.Gamma,
DeltaCash = risk.DeltaCash,
GammaCash = risk.GammaCash,
VegaCash = risk.VegaCash,
Exposure = risk.CreditExposure,
CurrentVolatility = risk.Vol,
Notional = pos.Amount,
OriginalNotional = pos.Amount,
TradePrice = pos.Cost,
TradeSinglePrice = pos.Amount > 0 ? pos.Cost / pos.Amount : 0,
TradeType = pos.TradeType,
UnderlyingCode = pos.UnderlyingCode,
UnderlyingPrice = un.Price ?? 0,
UnderlyingId = un.id,
VarietyId = un.UnderlyingTypeId,
UnderlyingAssetName = un.UnderlyingName,
Margin = pos.Margin,
RealizedPnl = pos.TotalPnL - (double)pos.PositionPnL,
ExchangeOptionCode = pos.ExchangeOptionCode,
Strike = ex.Strike,
ExerciseDate = ex.MaturityDate,
OptionType = ex.OptionType,
TradeDate = ex.OpenDate,
GammaLots = NumberHelper.Normalize(risk.Gamma / un.ContractSize),
DeltaLots = NumberHelper.Normalize(risk.Delta / un.ContractSize),
TradeOriginalAmount = un != null ? pos.Amount / un.CountRatio : pos.Amount
};
var datas = query.ToArray();
foreach (var data in datas)
{
data.RiskFreeRate = valuedateBLL.RiskFreeRate / 100;
//var um = DataCacheProvider.GetUnderlyingDataSource().GetData(data.UnderlyingCode);
//if (um != null)
//{
// data.GammaLots = NumberHelper.Normalize(data.Gamma / um.ContractSize);
// data.DeltaLots = NumberHelper.Normalize(data.Delta / um.ContractSize);
//}
data.Rho *= 100;
//data.TradeOriginalAmount = um != null ? data.OriginalNotional / um.CountRatio : data.OriginalNotional;
}
return datas;
}
private List<EodTradeJsonDto> GetEodTradeJsonList(List<T2PositionDataDto> t2PositionDatas, List<T1ToT2DataDto> t1ToT2Datas)
{
var result = new List<EodTradeJsonDto>();
List<EodTradeJsonQueryDto> queryList = new List<EodTradeJsonQueryDto>();
if (t2PositionDatas != null && t2PositionDatas.Count > 0)
{
var queryDtos1 = t2PositionDatas.Where(p => p.TradeId > 0).Select(p => new EodTradeJsonQueryDto
{
ValueDate = p.ValueDate,
TradeId = p.ParentTradeId > 0 ? p.ParentTradeId : p.TradeId
}).ToList();
if (queryDtos1 != null && queryDtos1.Count > 0)
{
queryList.AddRange(queryDtos1);
}
}
if (t1ToT2Datas != null && t1ToT2Datas.Count > 0)
{
var queryDtos2 = t1ToT2Datas.Where(p => p.TradeId > 0).Select(p => new EodTradeJsonQueryDto
{
ValueDate = p.ValueDate,
TradeId = p.ParentTradeId > 0 ? p.ParentTradeId : p.TradeId
}).ToList();
if (queryDtos2 != null && queryDtos2.Count > 0)
{
queryList.AddRange(queryDtos2);
}
}
if (queryList.Count > 0)
{
var comparer = new EodTradeJsonQueryDtoComparer();
queryList = queryList.Distinct(comparer).ToList();
}
DbContext.Database.SetCommandTimeout(1800);
result = GetEodTradeList(queryList);
return result;
}
private List<EodTradeJsonDto> GetEodTradeList(List<EodTradeJsonQueryDto> queryList)
{
if(queryList== null||queryList.Count==0)
{
return new List<EodTradeJsonDto>();
}
if (queryList.Count < 10000)
{
return GetEodTradeListByQuery(queryList);
}
List<Task<List<EodTradeJsonDto>>> tasks = new List<Task<List<EodTradeJsonDto>>>();
int pageIndex = 1;
int pageSize = 15000;
var itemList = queryList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
while (itemList != null && itemList.Count > 0)
{
tasks.Add(CreateGetEodTradeListTask(itemList));
pageIndex++;
itemList = queryList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
tasks.ForEach(p => p.Start());
System.Threading.Tasks.Task.WaitAll(tasks.ToArray());
List<EodTradeJsonDto> result = new List<EodTradeJsonDto>();
tasks.ForEach(p =>
{
if (p.Result != null && p.Result.Count > 0)
{
result.AddRange(p.Result);
}
});
return result;
}
private List<EodTradeJsonDto> GetEodTradeListByQuery(List<EodTradeJsonQueryDto> queryList)
{
var result = new List<EodTradeJsonDto>();
if (queryList.Count > 0)
{
var sql = "select ValueDate,TradeId,TradeJson from eod_trade where (ValueDate,TradeId) in ({0})";
int pageIndex = 1;
int pageSize = 1000;
var itemList = queryList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
using (var db = DbContextFactory.GetYLDbContext())
{
var conn = db.Database.GetDbConnection();
db.Database.SetCommandTimeout(1800);
while (itemList != null && itemList.Count > 0)
{
var sb = new StringBuilder();
for (int i = 0; i < itemList.Count; i++)
{
sb.AppendFormat("('{0}',{1})", ((DateTime)(itemList[i].ValueDate)).ToString("yyyy-MM-dd"), itemList[i].TradeId);
if (i < (itemList.Count - 1))
{
sb.Append(",");
}
}
var datas = conn.Query<EodTradeJsonDto>(String.Format(sql, sb.ToString()),commandTimeout:1800).ToList();
//var datas = GetEodTradeListForDataReader(conn, String.Format(sql, sb.ToString()));
if (datas != null && datas.Count > 0)
{
result.AddRange(datas);
}
pageIndex++;
itemList = queryList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
}
}
return result;
}
//private List<EodTradeJsonDto> GetEodTradeListForDataReader(DbConnection conn,string sql)
//{
// List<EodTradeJsonDto> result = new List<EodTradeJsonDto>();
// MySqlCommand command = new MySqlCommand(sql, (MySqlConnection)conn);
// var dr = command.ExecuteReader();
// while (dr.Read())
// {
// result.Add(new EodTradeJsonDto {
// ValueDate = DateTime.Parse(dr["ValueDate"].ToString()),
// TradeId = int.Parse(dr["TradeId"].ToString()),
// TradeJson = dr["TradeJson"].ToString()
// });
// }
// dr.Close();
// dr.Dispose();
// return result;
//}
private Task<List<EodTradeJsonDto>> CreateGetEodTradeListTask(List<EodTradeJsonQueryDto> queryList)
{
return new Task<List<EodTradeJsonDto>>(() =>
{
return GetEodTradeListByQuery(queryList);
});
}
private List<T1ToT2DataDto> GetOnSitePositionDatas(DbConnection conn,List<ExchangeTradeQueryDto> onSiteTradeList)
{
var onSiteT1ToT2DataSql = "SELECT ValueDate,TradeId,ClientId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,TotalPnL,Commission FROM {0} WHERE (ValueDate,TradeId,HedgeUniqueCode) in ({1})";
var result = new List<T1ToT2DataDto>();
int pageIndex = 1;
int pageSize = 1000;
var itemList = onSiteTradeList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
while (itemList != null && itemList.Count > 0)
{
var onSiteSb = new StringBuilder();
for (int i = 0; i < itemList.Count; i++)
{
onSiteSb.AppendFormat("('{0}',0,'{1}')", ((DateTime)(itemList[i].MaturityDate)).ToString("yyyy-MM-dd"), HedgePnlCalc.GetHedgeUniqueCode(itemList[i].AssetBookId, itemList[i].TradeType, HedgePnlCalc.GetHedgeLongShort(itemList[i].TradeType, itemList[i].TradeSide), itemList[i].UnderlyingCode, itemList[i].OptionCode));
if (i < (itemList.Count - 1))
{
onSiteSb.Append(",");
}
}
var t1ToT2Datas = conn.Query<T1ToT2DataDto>(String.Format(onSiteT1ToT2DataSql, DbContext.GetTableName<eodPosition>(), onSiteSb.ToString())).ToList();
if(t1ToT2Datas != null&& t1ToT2Datas.Count > 0)
{
result.AddRange(t1ToT2Datas);
}
pageIndex++;
itemList = onSiteTradeList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
return result;
}
/// <summary>
/// 获取时间点 T1 T2 相关数据
/// </summary>
/// <typeparam name="eodRisk"></typeparam>
/// <typeparam name="eodPnl"></typeparam>
/// <param name="reqModel"></param>
/// <param name="dateT1"></param>
/// <param name="dateT2"></param>
/// <param name="t1Datas"></param>
/// <param name="t2PositionDatas"></param>
/// <param name="t2RiskDatas"></param>
/// <param name="t2PnlDatas"></param>
/// <param name="t1ToT2Datas"></param>
/// <param name="eodDatas"></param>
/// <returns></returns>
private bool GetT1AndT2SourceData<eodRisk, eodPnl>(RiskRequestModel reqModel,DateTime dateT1, DateTime dateT2, DateTime preDateT2, out List<T1DataDto> t1Datas,out List<T2PositionDataDto> t2PositionDatas, out List<T2RiskDataDto> t2RiskDatas, out List<T2PnlDataDto> t2PnlDatas,out List<T1ToT2DataDto> t1ToT2Datas, out List<EodTradeJsonDto> eodDatas,out List<PreDateT2DataDto> preDateT2Datas) where eodRisk : EodTradeRisk where eodPnl : EodPnl
{
var task1 = CreateGetT1DatasTask(dateT1);
string tradeWhere, onSiteTradeWhere, predicateWhere,inSiteWhere;
MakeCondition(reqModel, out tradeWhere, out onSiteTradeWhere, out predicateWhere,out inSiteWhere);
var task2 = CreateGetT2DatasTask<eodRisk, eodPnl>(reqModel, dateT2, predicateWhere);
tradeWhere = " UnWindDate>@StartTime and UnWindDate<@EndTime and TradeStatus in @TradeCompletedStatus and " + tradeWhere;
var task3 = CreateGetT1ToT2DatasTask(reqModel, dateT1, dateT2, onSiteTradeWhere, tradeWhere,inSiteWhere);
var task4 = CreateGetPreT2DatasTask(preDateT2);
task1.Start();
task2.Start();
task3.Start();
task4.Start();
System.Threading.Tasks.Task.WaitAll(task1, task2, task3,task4);
t1Datas = task1.Result;
t2PositionDatas = task2.Result.T2PositionDatas;
t2RiskDatas = task2.Result.T2RiskDatas;
t2PnlDatas = task2.Result.T2PnlDatas;
t1ToT2Datas = task3.Result;
preDateT2Datas = task4.Result;
//eodDatas = GetEodTradeJsonList(t2PositionDatas, t1ToT2Datas);
if (t1Datas == null)
{
t1Datas = new List<T1DataDto>();
}
if (t2PositionDatas == null)
{
t2PositionDatas = new List<T2PositionDataDto>();
}
if (t2RiskDatas == null)
{
t2RiskDatas = new List<T2RiskDataDto>();
}
if (t2PnlDatas == null)
{
t2PnlDatas = new List<T2PnlDataDto>();
}
if (t1ToT2Datas == null)
{
t1ToT2Datas = new List<T1ToT2DataDto>();
}
eodDatas = null;
//if (eodDatas == null)
//{
// eodDatas = new List<EodTradeJsonDto>();
//}
if (preDateT2Datas == null)
{
preDateT2Datas = new List<PreDateT2DataDto>();
}
return true;
}
/// <summary>
/// 获取T1 时间点数据
/// </summary>
/// <param name="dateT1"></param>
/// <returns></returns>
public Task<List<T1DataDto>> CreateGetT1DatasTask(DateTime dateT1)
{
return new Task<List<T1DataDto>>(() =>
{
using (var db = DbContextFactory.GetYLDbContext())
{
db.Database.SetCommandTimeout(1800);
return db.Set<eodPosition>().Where(p => p.ValueDate == dateT1).Select(p => new T1DataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
UnderlyingCode = p.UnderlyingCode,
ExchangeOptionCode = p.ExchangeOptionCode,
TotalPnL = p.TotalPnL,
Cost = p.Cost,
Pv = p.Pv,
TradeType = p.TradeType,
ClientId = p.ClientId,
BookId= p.BookId,
Commission=p.Commission
}).ToList();
}
});
}
/// <summary>
/// 获取T2-1 时间点数据
/// </summary>
/// <param name="dateT1"></param>
/// <returns></returns>
private Task<List<PreDateT2DataDto>> CreateGetPreT2DatasTask(DateTime date)
{
return new Task<List<PreDateT2DataDto>>(() =>
{
List<string> tradeTypes = new List<string>()
{
"场内期权",
"商品期货",
"股票"
};
using (var db = DbContextFactory.GetYLDbContext())
{
db.Database.SetCommandTimeout(1800);
return db.Set<eodPosition>().Where(p => p.ValueDate == date&& tradeTypes.Contains(p.TradeType)).Select(p => new PreDateT2DataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
Commission = p.Commission
}).ToList();
}
});
}
/// <summary>
/// 获取 T2 时间点 数据
/// </summary>
/// <typeparam name="eodRisk"></typeparam>
/// <typeparam name="eodPnl"></typeparam>
/// <param name="reqModel"></param>
/// <param name="dateT2"></param>
/// <param name="predicateWhere"></param>
/// <returns></returns>
private Task<T2DataResult> CreateGetT2DatasTask<eodRisk, eodPnl>(RiskRequestModel reqModel, DateTime dateT2,string predicateWhere) where eodRisk : EodTradeRisk where eodPnl : EodPnl
{
return new Task<T2DataResult>(() =>
{
T2DataResult result= new T2DataResult();
using (var db = DbContextFactory.GetYLDbContext())
{
var t2PositionDateSql = string.Format("select id,ValueDate,TradeId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,Amount,TotalPnL,Pv,Cost,Commission,DailyPnL,RoundedPv,PositionPnL,RoundedPositionPnL,Margin from {0} where {1}", db.GetTableName<eodPosition>(), predicateWhere);
db.Database.SetCommandTimeout(1800);
var conn = db.Database.GetDbConnection();
var t2PositionDatas = conn.Query<T2PositionDataDto>(t2PositionDateSql, new
{
EndTime = dateT2,
UserAssets = reqModel.UserAssets,
UserClients = reqModel.UserClients,
ClientIds = reqModel.ClientIds,
BookIds = reqModel.BookIds,
TradeTypes = reqModel.TradeTypes,
TraderIds = reqModel.TraderIds,
TagIds = reqModel.TagIds,
UnderlyingIds = reqModel.UnderlyingIds,
VarietyIds = reqModel.VarietyIds
},commandTimeout:1800).ToList();
var t2RiskDatas = new List<T2RiskDataDto>();
var t2PnlDatas = new List<T2PnlDataDto>();
if (t2PositionDatas != null && t2PositionDatas.Count > 0)
{
var t2TradeIds = t2PositionDatas.Where(p => p.TradeId > 0).Select(p => p.TradeId).Distinct().ToList();
if (t2TradeIds != null && t2TradeIds.Count > 0)
{
var riskDatas = db.Set<eodRisk>().AsNoTracking().Where(p => p.ValueDate == dateT2 && t2TradeIds.Contains(p.TradeId)).Select(p => new T2RiskDataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
Delta = p.Delta,
DeltaCash = p.DeltaCash,
Gamma = p.Gamma,
GammaCash = p.GammaCash,
Vega = p.Vega,
Rho = p.Rho,
Theta = p.Theta,
VegaCash = p.VegaCash,
CreditExposure = p.CreditExposure,
Vol = p.Vol
}).ToList();
if (riskDatas != null && riskDatas.Count > 0)
{
t2RiskDatas.AddRange(riskDatas);
}
var pnlDatas = db.Set<eodPnl>().AsNoTracking().Where(p => p.ValueDate == dateT2 && t2TradeIds.Contains(p.TradeId)).Select(p => new T2PnlDataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
PnLDelta = p.PnLDelta,
PnLGamma = p.PnLGamma,
PnLPsi = p.PnLPsi,
PnLTheta = p.PnLTheta,
PnLVega = p.PnLVega
}).ToList();
if (pnlDatas != null && pnlDatas.Count > 0)
{
t2PnlDatas.AddRange(pnlDatas);
}
}
var t2HedgeCodes = t2PositionDatas.Where(p => p.TradeId == 0).Select(p => p.HedgeUniqueCode).Distinct().ToList();
if (t2HedgeCodes != null && t2HedgeCodes.Count > 0)
{
var riskHegeDatas = db.Set<eodRisk>().AsNoTracking().Where(p => p.ValueDate == dateT2 && p.TradeId == 0 && t2HedgeCodes.Contains(p.HedgeUniqueCode)).Select(p => new T2RiskDataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
Delta = p.Delta,
DeltaCash = p.DeltaCash,
Gamma = p.Gamma,
GammaCash = p.GammaCash,
Vega = p.Vega,
Rho = p.Rho,
Theta = p.Theta
}).ToList();
if (riskHegeDatas != null && riskHegeDatas.Count > 0)
{
t2RiskDatas.AddRange(riskHegeDatas);
}
var pnlHegeDatas = db.Set<eodPnl>().AsNoTracking().Where(p => p.ValueDate == dateT2 && p.TradeId == 0 && t2HedgeCodes.Contains(p.HedgeUniqueCode)).Select(p => new T2PnlDataDto
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
HedgeUniqueCode = p.HedgeUniqueCode,
PnLDelta = p.PnLDelta,
PnLGamma = p.PnLGamma,
PnLPsi = p.PnLPsi,
PnLTheta = p.PnLTheta,
PnLVega = p.PnLVega
}).ToList();
if (pnlHegeDatas != null && pnlHegeDatas.Count > 0)
{
t2PnlDatas.AddRange(pnlHegeDatas);
}
}
}
result.T2PositionDatas = t2PositionDatas;
result.T2RiskDatas = t2RiskDatas;
result.T2PnlDatas = t2PnlDatas;
return result;
}
});
}
/// <summary>
/// 获取 T1 - T2 之间的数据
/// </summary>
/// <param name="reqModel"></param>
/// <param name="dateT1"></param>
/// <param name="dateT2"></param>
/// <param name="onSiteTradeWhere"></param>
/// <param name="tradeWhere"></param>
/// <returns></returns>
public Task<List<T1ToT2DataDto>> CreateGetT1ToT2DatasTask(RiskRequestModel reqModel, DateTime dateT1, DateTime dateT2,string onSiteTradeWhere,string tradeWhere,string inSiteWhere)
{
return new Task<List<T1ToT2DataDto>>(() =>
{
var t1ToT2Datas = new List<T1ToT2DataDto>();
var onSiteT1ToT2Datas = new List<T1ToT2DataDto>();
using (var db=DbContextFactory.GetYLDbContext())
{
db.Database.SetCommandTimeout(1800);
var t1ToT2Sql = string.Format("SELECT ValueDate,TradeId,ClientId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,TotalPnL,Commission FROM {0} WHERE (ValueDate,TradeId,HedgeUniqueCode) IN (SELECT UnWindDate AS ValueDate,id AS TradeId,'' AS HedgeUniqueCode FROM trade WHERE {1})", db.GetTableName<eodPosition>(), tradeWhere);
var conn = db.Database.GetDbConnection();
// 1 获取场外数据
var outSiteT1ToT2Datas = conn.Query<T1ToT2DataDto>(t1ToT2Sql, new
{
StartTime = dateT1,
EndTime = dateT2,
UserAssets = reqModel.UserAssets,
UserClients = reqModel.UserClients,
ClientIds = reqModel.ClientIds,
BookIds = reqModel.BookIds,
TradeTypes = reqModel.TradeTypes,
TraderIds = reqModel.TraderIds,
TagIds = reqModel.TagIds,
UnderlyingIds = reqModel.UnderlyingIds,
VarietyIds = reqModel.VarietyIds,
TradeCompletedStatus = ConsTrade.TradeCompleteStatus
},commandTimeout:1800).ToList();
if (outSiteT1ToT2Datas != null && outSiteT1ToT2Datas.Count > 0)
{
t1ToT2Datas.AddRange(outSiteT1ToT2Datas);
}
//onSiteTradeWhere = " MaturityDate>@StartTime and MaturityDate<@EndTime and" + onSiteTradeWhere;
//var onSiteTradeList = conn.Query<ExchangeTradeQueryDto>(String.Format("select MaturityDate,AssetBookId,TradeType,TradeSide,UnderlyingCode,OptionCode from exchange_trade where {0}", onSiteTradeWhere), new
//{
// StartTime = dateT1,
// EndTime = dateT2,
// UserAssets = reqModel.UserAssets,
// UserClients = reqModel.UserClients,
// ClientIds = reqModel.ClientIds,
// BookIds = reqModel.BookIds,
// TradeTypes = reqModel.TradeTypes,
// TraderIds = reqModel.TraderIds,
// TagIds = reqModel.TagIds,
// UnderlyingIds = reqModel.UnderlyingIds,
// VarietyIds = reqModel.VarietyIds,
//},commandTimeout:1800).ToList();
//if (onSiteTradeList != null && onSiteTradeList.Count > 0)
//{
// var onSitePostionDatas = GetOnSitePositionDatas(conn, onSiteTradeList);
// if (onSitePostionDatas != null && onSitePostionDatas.Count > 0)
// {
// t1ToT2Datas.AddRange(onSitePostionDatas);
// }
//}
//2、获取场内数据 场内交易对应 eod_trade_position数据获取 从 underlying_manager 取期货数据 exchange_list_option 全部
var instrumentTypes = new List<string> {
ConsGlobal.InstrumentType.GetFromDesc("股指期货"),
ConsGlobal.InstrumentType.GetFromDesc("商品期货"),
ConsGlobal.InstrumentType.GetFromDesc("黄金期货"),
ConsGlobal.InstrumentType.GetFromDesc("国债期货"),
ConsGlobal.InstrumentType.GetFromDesc("其他期货"),
ConsGlobal.InstrumentType.GetFromDesc("境外期货")
};
var managerSql = "select MaturityDate,UnderlyingCode from underlying_manager where MaturityDate>@StartTime and MaturityDate<@EndTime and UnderlyingInstrumentType in @UnderlyingInstrumentTypes";
var exchangeSql = "select MaturityDate,ContractCode from exchange_list_option where MaturityDate>@StartTime and MaturityDate<@EndTime";
var managerList = conn.Query<UnderlyingRiskQueryDto>(managerSql, new
{
StartTime = dateT1,
EndTime = dateT2,
UnderlyingInstrumentTypes= instrumentTypes
},commandTimeout:600).ToList();
var onSiteDatas1 = GetOnSiteDataByUnderlyManagerList(reqModel, conn, managerList, inSiteWhere);
if (onSiteDatas1 != null && onSiteDatas1.Count > 0)
{
onSiteT1ToT2Datas.AddRange(onSiteDatas1);
}
var exchangeList = conn.Query<ExchangeRiskQueryDto>(exchangeSql, new {
StartTime = dateT1,
EndTime = dateT2,
}, commandTimeout: 600).ToList();
var onSiteDatas2 = GetOnSiteDataByUnderlyExchangeList(reqModel,conn, exchangeList, inSiteWhere);
if (onSiteDatas2 != null && onSiteDatas2.Count > 0)
{
onSiteT1ToT2Datas.AddRange(onSiteDatas2);
}
}
if (onSiteT1ToT2Datas != null && onSiteT1ToT2Datas.Count > 0)
{
if (reqModel.UserAssets != null && reqModel.UserAssets.Count > 0)
{
onSiteT1ToT2Datas = onSiteT1ToT2Datas.Where(p => reqModel.UserAssets.Contains(p.BookId)).ToList();
}
if (reqModel.BookIds != null && reqModel.BookIds.Count > 0)
{
onSiteT1ToT2Datas = onSiteT1ToT2Datas.Where(p => reqModel.UserAssets.Contains(p.BookId)).ToList();
}
//if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any() && reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
//{
// predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
// tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
//}
//else
//{
// if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any())
// {
// predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
// tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
// }
// if (reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
// {
// predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
// tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
// }
//}
t1ToT2Datas.AddRange(onSiteT1ToT2Datas);
}
return t1ToT2Datas;
});
}
private List<T1ToT2DataDto> GetOnSiteDataByUnderlyExchangeList(RiskRequestModel reqModel,DbConnection conn, List<ExchangeRiskQueryDto> managerList, string inSiteWhere)
{
if (managerList == null || managerList.Count == 0)
{
return new List<T1ToT2DataDto>();
}
var onSiteT1ToT2DataSql = "SELECT ValueDate,TradeId,ClientId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,TotalPnL,Commission FROM {0} WHERE (ValueDate,TradeId,ExchangeOptionCode) in ({1}) and " + inSiteWhere;
var result = new List<T1ToT2DataDto>();
int pageIndex = 1;
int pageSize = 1000;
var itemList = managerList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
while (itemList != null && itemList.Count > 0)
{
var onSiteSb = new StringBuilder();
for (int i = 0; i < itemList.Count; i++)
{
onSiteSb.AppendFormat("('{0}',0,'{1}')", ((DateTime)(itemList[i].MaturityDate)).ToString("yyyy-MM-dd"), itemList[i].ContractCode);
if (i < (itemList.Count - 1))
{
onSiteSb.Append(",");
}
}
var t1ToT2Datas = conn.Query<T1ToT2DataDto>(String.Format(onSiteT1ToT2DataSql, DbContext.GetTableName<eodPosition>(), onSiteSb.ToString()), new
{
UserAssets = reqModel.UserAssets,
UserClients = reqModel.UserClients,
ClientIds = reqModel.ClientIds,
BookIds = reqModel.BookIds,
TradeTypes = reqModel.TradeTypes,
TraderIds = reqModel.TraderIds,
TagIds = reqModel.TagIds,
UnderlyingIds = reqModel.UnderlyingIds,
VarietyIds = reqModel.VarietyIds
}, commandTimeout: 600).ToList();
if (t1ToT2Datas != null && t1ToT2Datas.Count > 0)
{
result.AddRange(t1ToT2Datas);
}
pageIndex++;
itemList = managerList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
return result;
}
private List<T1ToT2DataDto> GetOnSiteDataByUnderlyManagerList(RiskRequestModel reqModel,DbConnection conn,List<UnderlyingRiskQueryDto> managerList,string inSiteWhere)
{
if (managerList == null || managerList.Count == 0)
{
return new List<T1ToT2DataDto>();
}
var onSiteT1ToT2DataSql = "SELECT ValueDate,TradeId,ClientId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,TotalPnL,Commission FROM {0} WHERE (ValueDate,TradeId,UnderlyingCode) in ({1}) and " + inSiteWhere;
var result = new List<T1ToT2DataDto>();
int pageIndex = 1;
int pageSize = 1000;
var itemList = managerList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
while (itemList != null && itemList.Count > 0)
{
var onSiteSb = new StringBuilder();
for (int i = 0; i < itemList.Count; i++)
{
onSiteSb.AppendFormat("('{0}',0,'{1}')", ((DateTime)(itemList[i].MaturityDate)).ToString("yyyy-MM-dd"), itemList[i].UnderlyingCode);
if (i < (itemList.Count - 1))
{
onSiteSb.Append(",");
}
}
var t1ToT2Datas = conn.Query<T1ToT2DataDto>(String.Format(onSiteT1ToT2DataSql, DbContext.GetTableName<eodPosition>(), onSiteSb.ToString()), new
{
UserAssets = reqModel.UserAssets,
UserClients = reqModel.UserClients,
ClientIds = reqModel.ClientIds,
BookIds = reqModel.BookIds,
TradeTypes = reqModel.TradeTypes,
TraderIds = reqModel.TraderIds,
TagIds = reqModel.TagIds,
UnderlyingIds = reqModel.UnderlyingIds,
VarietyIds = reqModel.VarietyIds
},commandTimeout:600).ToList();
if (t1ToT2Datas != null && t1ToT2Datas.Count > 0)
{
result.AddRange(t1ToT2Datas);
}
pageIndex++;
itemList = managerList.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
return result;
}
private List<RiskExposureItemModel> GetRisExposureItemList(List<T1DataDto> t1Datas, List<T2PositionDataDto> t2PositionDatas, List<T2RiskDataDto> t2RiskDatas, List<T2PnlDataDto> t2PnlDatas, List<T1ToT2DataDto> t1ToT2Datas, List<EodTradeJsonDto> eodDatas, List<PreDateT2DataDto> preDateT2Datas)
{
var t1DatasDic = t1Datas.ToDictionary(p => p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode), p => p);
//数据整合
if (t1DatasDic == null)
{
t1DatasDic = new Dictionary<string, T1DataDto>();
}
var t2RiskDataDic = t2RiskDatas.ToDictionary(p => p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode), p => p);
var t2PnlDataDic = t2PnlDatas.ToDictionary(p => p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode), p => p);
var preDateT2DatasDic= preDateT2Datas.ToDictionary(p => p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode), p => p);
if (preDateT2DatasDic == null)
{
preDateT2DatasDic = new Dictionary<string, PreDateT2DataDto>();
}
List<RiskExposureItemModel> riskExposureItemModels = new List<RiskExposureItemModel>();
List<int?> tradeIds = new List<int?>();
if (t2PositionDatas != null && t2PositionDatas.Count > 0)
{
var t2TradeIds = t2PositionDatas.Where(p => p.TradeId > 0).Select(p => p.TradeId).Distinct().ToList();
if (t2TradeIds != null && t2TradeIds.Count > 0)
{
tradeIds.AddRange(t2TradeIds);
}
}
if (t1ToT2Datas != null && t1ToT2Datas.Count > 0)
{
var t1Tot2TradeIds = t1ToT2Datas.Where(p => p.TradeId > 0).Select(p => p.TradeId).Distinct().ToList();
if (t1Tot2TradeIds != null && t1Tot2TradeIds.Count > 0)
{
tradeIds.AddRange(t1Tot2TradeIds);
}
}
Dictionary<int,TradeRiskQueryDto> tradeDic = null;
if (tradeIds != null && tradeIds.Count > 0)
{
DbContext.Database.SetCommandTimeout(1800);
tradeDic = DbContext.trade.AsNoTracking().Where(p => tradeIds.Contains(p.id)).Select(p => new TradeRiskQueryDto
{
TradeId = p.id,
SpotPrice = p.SpotPrice,
OriginalNotional = p.OriginalNotional,
OriginalStockEqvNotional = p.OriginalStockEqvNotional
}).ToDictionary(p => p.TradeId, p => p);
}
if (tradeDic == null)
{
tradeDic = new Dictionary<int, TradeRiskQueryDto>();
}
List<int> parentTradeList = new List<int>();
//var eodDataDic = eodDatas.ToDictionary(p => p.TradeId + "_" + p.ValueDate.ToString("yyyy-MM-dd"), p => p);
if (t2PositionDatas != null && t2PositionDatas.Count > 0)
{
t2PositionDatas.ForEach(p =>
{
var model = new RiskExposureItemModel
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
ParentTradeId = p.ParentTradeId ?? 0,
UnderlyingCode = p.UnderlyingCode,
OptionCode = p.ExchangeOptionCode,
UnderlyingId = p.UnderlyingId ?? 0,
BookId = p.BookId ?? 0,
TradeType = p.StructureType == null || p.StructureType == "" ? p.TradeType : p.StructureType,
Amount = p.Amount ?? 0,
AccruedTotalPnL = p.TotalPnL,
CumulativeFloatProfitLoss = (p.Pv ?? 0) - (p.Cost ?? 0),
Commission = p.Commission ?? 0,//总计手续费
DailyCommission= p.Commission ?? 0,//总计手续费
DailyPnl = p.DailyPnL,
SpotPrice = 0,
};
var key = p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode);
var t1Data = t1DatasDic.ContainsKey(key) ? t1DatasDic[key] : null;
if (t1Data != null)
{
if (PS.Config.Company != Configuration.CompanyEnum.中基石化) //中基 在T2点持仓的交易 累积总盈亏 取 交易开始日到T2时间的的盈亏 即T2时间点的TotalPnl
{
model.AccruedTotalPnL = model.AccruedTotalPnL - (t1Data.TotalPnL ?? 0);
}
model.CumulativeFloatProfitLoss = model.CumulativeFloatProfitLoss - (t1Data.Pv ?? 0) - (t1Data.Cost ?? 0);
model.Commission = model.Commission - t1Data.Commission;
}
var preDateT2Data = preDateT2DatasDic.ContainsKey(key) ? preDateT2DatasDic[key] : null;
if(preDateT2Data != null)
{
model.DailyCommission = model.DailyCommission - (preDateT2Data.Commission??0);
}
var riskData = t2RiskDataDic.ContainsKey(key) ? t2RiskDataDic[key] : null;
if (riskData != null)
{
model.Delta = riskData.Delta;
model.DeltaCash = riskData.DeltaCash;
model.Gamma = riskData.Gamma;
model.GammaCash = riskData.GammaCash;
model.Vega = riskData.Vega;
model.Rho = riskData.Rho ?? 0 * 100;
model.Theta = riskData.Theta;
}
var pnlData = t2PnlDataDic.ContainsKey(key) ? t2PnlDataDic[key] : null;
if (pnlData != null)
{
model.dPnlDelta = pnlData.PnLDelta ?? 0;
model.dPnlGamma = pnlData.PnLGamma ?? 0;
model.dPnlTheta = pnlData.PnLTheta ?? 0;
model.dPnlVega = pnlData.PnLVega ?? 0;
model.dPnlPsi = pnlData.PnLPsi ?? 0;
}
if (p.TradeId > 0 && tradeDic.ContainsKey((int)p.TradeId))
{
var tradeInfo = tradeDic[(int)p.TradeId];
model.SpotPrice = tradeInfo.SpotPrice;
model.StockEqvNotional = model.Amount > 0 && tradeInfo.OriginalNotional > 0 ? ((double)tradeInfo.OriginalStockEqvNotional * model.Amount / ((double)tradeInfo.OriginalNotional)) : 0;
}
//if (p.TradeId > 0)
//{
// var eodKey = (p.ParentTradeId > 0 ? p.ParentTradeId : p.TradeId) + "_" + p.ValueDate.ToString("yyyy-MM-dd");
// var eodData = eodDataDic.ContainsKey(eodKey) ? eodDataDic[eodKey] : null;
// if (eodData != null)
// {
// model.eodTrade = new xodTradeBase { TradeJson = eodData.TradeJson };
// }
// if (model.eodTrade != null)
// {
// if (p.ParentTradeId > 0)
// {
// if (!parentTradeList.Contains((int)p.ParentTradeId))
// {
// model.StockEqvNotional = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotional : 0;
// model.StockEqvNotionalReal = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotionalReal : 0;
// parentTradeList.Add((int)p.ParentTradeId);
// }
// }
// else
// {
// model.StockEqvNotional = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotional : 0;
// model.StockEqvNotionalReal = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotionalReal : 0;
// }
// }
//}
riskExposureItemModels.Add(model);
});
}
if (t1ToT2Datas != null && t1ToT2Datas.Count > 0)
{
t1ToT2Datas.ForEach(p =>
{
var model = new RiskExposureItemModel
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
ParentTradeId = p.ParentTradeId ?? 0,
UnderlyingCode = p.UnderlyingCode,
OptionCode = p.ExchangeOptionCode,
UnderlyingId = p.UnderlyingId ?? 0,
BookId = p.BookId,
TradeType = p.StructureType == null || p.StructureType == "" ? p.TradeType : p.StructureType,
Commission = p.Commission,//总计手续费
Amount = 0,
CumulativeFloatProfitLoss = 0,
DailyPnl = 0,
Delta = 0,
Gamma = 0,
Vega = 0,
Rho = 0,
Theta = 0,
DeltaCash = 0,
GammaCash = 0,
dPnlDelta = 0,
dPnlGamma = 0,
dPnlTheta = 0,
dPnlVega = 0,
dPnlPsi = 0,
AccruedTotalPnL = p.TotalPnL,
SpotPrice = 0,
};
var key = p.TradeId + "_" + (String.IsNullOrEmpty(p.HedgeUniqueCode) ? "" : p.HedgeUniqueCode);
var t1Data = t1DatasDic.ContainsKey(key) ? t1DatasDic[key] : null;
if (t1Data != null)
{
model.AccruedTotalPnL = model.AccruedTotalPnL - (t1Data.TotalPnL ?? 0);
model.Commission = model.Commission - t1Data.Commission;
}
if (p.TradeId > 0 && tradeDic.ContainsKey((int)p.TradeId))
{
var tradeInfo = tradeDic[(int)p.TradeId];
model.SpotPrice = tradeInfo.SpotPrice;
model.StockEqvNotional = 0;
}
if (p.TradeId > 0)
{
//var eodKey = (p.ParentTradeId > 0 ? p.ParentTradeId : p.TradeId) + "_" + p.ValueDate.ToString("yyyy-MM-dd");
//var eodData = eodDataDic.ContainsKey(eodKey) ? eodDataDic[eodKey] : null;
//if (eodData != null)
//{
// model.eodTrade = new xodTradeBase { TradeJson = eodData.TradeJson };
//}
//if (model.eodTrade != null)
//{
// if (p.ParentTradeId > 0)
// {
// if (!parentTradeList.Contains((int)p.ParentTradeId))
// {
// model.StockEqvNotional = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotional : 0;
// model.StockEqvNotionalReal = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotionalReal : 0;
// parentTradeList.Add((int)p.ParentTradeId);
// }
// }
// else
// {
// model.StockEqvNotional = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotional : 0;
// model.StockEqvNotionalReal = model.eodTrade.trade != null ? model.eodTrade.trade.StockEqvNotionalReal : 0;
// }
//}
}
riskExposureItemModels.Add(model);
});
}
return riskExposureItemModels;
}
/// <summary>
/// 获取市场风险图表数据
/// </summary>
/// <typeparam name="eodRisk"></typeparam>
/// <typeparam name="eodPnl"></typeparam>
/// <param name="reqModel"></param>
/// <param name="days"></param>
/// <returns></returns>
public Dictionary<DateTime, RiskExposureReportModel> SearchRiskExposureReportsEchart<eodRisk, eodPnl>(RiskRequestModel reqModel, List<DateTime> days) where eodRisk : EodTradeRisk where eodPnl : EodPnl
{
Dictionary<DateTime, RiskExposureReportModel> dicResult = new Dictionary<DateTime, RiskExposureReportModel>();
if (days == null || days.Count == 0)
{
return dicResult;
}
reqModel = CheckModelForEchart(reqModel, days);
string predicateWhere = "";
MakeConditionForEchart(reqModel,out predicateWhere);
List<T2PositionDataDto> t2PositionDatas = GetPositionData(reqModel, days, predicateWhere);
if(t2PositionDatas==null|| t2PositionDatas.Count == 0)
{
return dicResult;
}
Dictionary<DateTime, List<RiskExposureItemModel>> dicExposureItemModels = new Dictionary<DateTime, List<RiskExposureItemModel>>();
foreach(var p in t2PositionDatas)
{
if (!dicExposureItemModels.ContainsKey(p.ValueDate))
{
dicExposureItemModels.Add(p.ValueDate, new List<RiskExposureItemModel>());
}
var model = new RiskExposureItemModel
{
ValueDate = p.ValueDate,
TradeId = p.TradeId,
ParentTradeId = p.ParentTradeId ?? 0,
UnderlyingCode = p.UnderlyingCode,
OptionCode = p.ExchangeOptionCode,
UnderlyingId = p.UnderlyingId ?? 0,
BookId = p.BookId ?? 0,
TradeType = p.StructureType == null || p.StructureType == "" ? p.TradeType : p.StructureType,
Amount = p.Amount ?? 0,
AccruedTotalPnL = p.DailyPnL,
CumulativeFloatProfitLoss = (p.Pv ?? 0) - (p.Cost ?? 0),
Commission = p.Commission ?? 0,//总计手续费
DailyCommission = p.Commission ?? 0,//总计手续费
DailyPnl = p.DailyPnL,
SpotPrice = 0,
};
dicExposureItemModels[p.ValueDate].Add(model);
}
var structList = DbContext.Structure_Info.Select(o => o.StructureName).ToList();
days.ForEach(p =>
{
if (dicExposureItemModels.ContainsKey(p))
{
dicResult.Add(p, MakeRiskExposureReportsEchartResultData(dicExposureItemModels[p], structList));
}
});
return dicResult;
}
/// <summary>
/// 获取position数据
/// </summary>
/// <param name="reqModel"></param>
/// <param name="days"></param>
/// <param name="predicateWhere"></param>
/// <returns></returns>
private List<T2PositionDataDto> GetPositionData(RiskRequestModel reqModel, List<DateTime> days, string predicateWhere)
{
var result = new List<T2PositionDataDto>();
List<Task<List<T2PositionDataDto>>> taskList = new List<Task<List<T2PositionDataDto>>>();
int pageIndex = 1;
int pageSize = 20;
var itemDays = days.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
while (itemDays != null && itemDays.Count > 0)
{
taskList.Add(CreateGetPositionDatasTask(reqModel, itemDays, predicateWhere));
pageIndex++;
itemDays = days.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}
taskList.ForEach(p => { p.Start(); });
System.Threading.Tasks.Task.WaitAll(taskList.ToArray());
taskList.ForEach(p =>
{
if (p.Result != null && p.Result.Count > 0)
{
result.AddRange(p.Result);
}
});
return result;
}
/// <summary>
/// 获取一系列时间的position数据
/// </summary>
/// <param name="reqModel"></param>
/// <param name="days"></param>
/// <param name="predicateWhere"></param>
/// <returns></returns>
private Task<List<T2PositionDataDto>> CreateGetPositionDatasTask(RiskRequestModel reqModel, List<DateTime> days, string predicateWhere)
{
return new Task<List<T2PositionDataDto>>(() =>
{
using (var db = DbContextFactory.GetYLDbContext())
{
var t2PositionDateSql = string.Format("select id,ValueDate,TradeId,HedgeUniqueCode,ParentTradeId,UnderlyingCode,ExchangeOptionCode,UnderlyingId,BookId,StructureType,TradeType,Amount,TotalPnL,Pv,Cost,Commission,DailyPnL,RoundedPv,PositionPnL,RoundedPositionPnL,Margin from {0} where {1}", db.GetTableName<eodPosition>(), predicateWhere);
db.Database.SetCommandTimeout(1800);
var conn = db.Database.GetDbConnection();
return conn.Query<T2PositionDataDto>(t2PositionDateSql, new
{
Days = days,
UserAssets = reqModel.UserAssets,
UserClients = reqModel.UserClients,
ClientIds = reqModel.ClientIds,
BookIds = reqModel.BookIds,
TradeTypes = reqModel.TradeTypes,
TraderIds = reqModel.TraderIds,
TagIds = reqModel.TagIds,
UnderlyingIds = reqModel.UnderlyingIds,
VarietyIds = reqModel.VarietyIds
}, commandTimeout: 1800).ToList();
}
});
}
/// <summary>
/// 构造查询条件
/// </summary>
/// <param name="reqModel"></param>
/// <param name="predicateWhere"></param>
private void MakeConditionForEchart(RiskRequestModel reqModel, out string predicateWhere)
{
var tradeWhere = "IFNULL(ValidState,'')<>'InValid'";
predicateWhere = " ValueDate in @Days and TradeType<>'结构化交易' and TradeType<>'现金流交易'";
tradeWhere += " and TradeType<>'结构化交易' and TradeType<>'现金流交易'";
//if (reqModel.UserAssets != null && reqModel.UserAssets.Count > 0 && !(reqModel.UserClients != null && reqModel.UserClients.Count > 0))
//{
// tradeWhere += " and AssetId in @UserAssets";
// predicateWhere += " and BookId in @UserAssets";
//}
//if (!(reqModel.UserAssets != null && reqModel.UserAssets.Count > 0) && (reqModel.UserClients != null && reqModel.UserClients.Count > 0))
//{
// tradeWhere += " and ClientId in @UserClients";
// predicateWhere += " and ClientId in @UserClients";
//}
//if ((reqModel.UserAssets != null && reqModel.UserAssets.Count > 0) && (reqModel.UserClients != null && reqModel.UserClients.Count > 0))
//{
// tradeWhere += " and (AssetId in @UserAssets or ClientId in @UserClients)";
// predicateWhere += " and (BookId in @UserAssets or ClientId in @UserClients)";
//}
//if (reqModel.ClientIds != null && reqModel.ClientIds.Count > 0)
//{
// predicateWhere += " and ClientId in @ClientIds";
// tradeWhere += " and ClientId in @ClientIds";
//}
if (reqModel.BookIds != null && reqModel.BookIds.Count > 0)
{
predicateWhere += " and BookId in @BookIds";
tradeWhere += " and AssetId in @BookIds";
}
if (reqModel.TradeTypes != null && reqModel.TradeTypes.Any())
{
predicateWhere += " and ((IFNULL(StructureType,'')='' and TradeType in @TradeTypes) or (IFNULL(StructureType,'')<>'' and StructureType in @TradeTypes))";
tradeWhere += " and ((IFNULL(StructureType,'')='' and TradeType in @TradeTypes) or (IFNULL(StructureType,'')<>'' and StructureType in @TradeTypes))";
}
//if (reqModel.TraderIds != null && reqModel.TraderIds.Any())
//{
// predicateWhere += " and TradeId>0";
// tradeWhere += " and TraderId in @TraderIds";
//}
//if (reqModel.TagIds != null && reqModel.TagIds.Count > 0)
//{
// tradeWhere += " and id in (select TradeId from trade_tag where TagId in @TagIds)";
//}
if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any() && reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds and UnderlyingTypeId in @VarietyIds)";
}
else
{
if (reqModel.VarietyIds != null && reqModel.VarietyIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where UnderlyingTypeId in @VarietyIds)";
}
if (reqModel.UnderlyingIds != null && reqModel.UnderlyingIds.Any())
{
predicateWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
tradeWhere += " and UnderlyingCode in (select UnderlyingCode from underlying_manager where id in @UnderlyingIds)";
}
}
predicateWhere += String.Format(" and (TradeId<1 or TradeId in (select id from trade where {0}))", tradeWhere);
}
private RiskRequestModel CheckModelForEchart(RiskRequestModel reqModel, List<DateTime> days)
{
if (reqModel == null)
{
throw new ServiceException("实体不能为空");
}
DateTime settleDate;
if (reqModel.EodSettlePriceMode == "结算价")
{
settleDate = EodOperationBase.GetLastSettlementDate_Settle(false);
}
else
{
settleDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
}
if (days.Max() > settleDate)
{
throw new ServiceException($"结束日期不能大于上一次收盘日期{settleDate:yyyy-MM-dd}");
}
return reqModel.Normalize();
}
/// <summary>
/// 组装图表数据
/// </summary>
/// <param name="list"></param>
/// <returns></returns>
private RiskExposureReportModel MakeRiskExposureReportsEchartResultData(List<RiskExposureItemModel> list,List<string> structList)
{
//合并处理
var underlyingGroup = list.GroupBy(e => e.UnderlyingCode.ToUpperInvariant());
var underlyingRiskList = new List<UnderlyingRiskModel>();
#region 1.对于最后一日有持仓数据的合约
foreach (var groupItem in underlyingGroup)
{
var underlyingRisk = new UnderlyingRiskModel();
var otcOptionsTradeType = ConsTrade.OptionTradeTypes.ToList();
otcOptionsTradeType.Add("结构化交易");
otcOptionsTradeType.AddRange(structList);
otcOptionsTradeType.Remove("收益互换");
//场外期权
var otcRiskList = groupItem.Where(g => otcOptionsTradeType.Contains(g.TradeType));
underlyingRisk.OtcRisk = new EodRiskModel
{
Pnl = otcRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0)
};
//场内期权
var exchangeRiskList = groupItem.Where(g => g.TradeType == "场内期权");
underlyingRisk.ExOptionRisk = new EodRiskModel
{
Pnl = exchangeRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0)
};
//标的交易
var hedgeRiskList = groupItem.Where(g => g.TradeType == "商品期货" || g.TradeType == "股票" || g.TradeType == "商品现货");
underlyingRisk.FuturesRisk = new EodRiskModel
{
Pnl = hedgeRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0)
};
//远期统计
var forwardRiskList = groupItem.Where(g => g.TradeType == "远期");
underlyingRisk.ForwardRisk = new EodRiskModel
{
Pnl = forwardRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0)
};
//收益互换统计
var swapRiskList = groupItem.Where(g => g.TradeType == "收益互换");
underlyingRisk.SwapRisk = new EodRiskModel
{
Pnl = swapRiskList.SumDouble(r => r.AccruedTotalPnL ?? 0)
};
//汇总合计
underlyingRisk.PortfolioRisk = new EodRiskModel
{
Pnl = underlyingRisk.OtcRisk.Pnl + underlyingRisk.ExOptionRisk.Pnl + underlyingRisk.FuturesRisk.Pnl + underlyingRisk.ForwardRisk.Pnl + underlyingRisk.SwapRisk.Pnl,
};
underlyingRiskList.Add(underlyingRisk);
}
#endregion
underlyingRiskList = underlyingRiskList.OrderBy(u => u, new UnderlyingRiskModelSortComparer()).ToList();
var varietyRiskExposureReports = underlyingRiskList.GroupBy(u => new { u.VarietyCode, u.VarietyOpenLimit, u.VarietyOpenLimitIcon }).Select(g =>
{
var list = g.ToList();
var portfolioSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.PortfolioRisk.Pnl)
};
var otcSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.OtcRisk.Pnl),
};
var exchangeListOptionSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.ExOptionRisk.Pnl)
};
var futuresSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.FuturesRisk.Pnl)
};
var forwardSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.ForwardRisk.Pnl)
};
var swapSum = new EodRiskModel
{
Pnl = list.SumDouble(l => l.SwapRisk.Pnl)
};
return new VarietyRiskExposureModel
{
VarietySum = new RiskExposureReportSumModel
{
PortfolioSum = portfolioSum,
OtcSum = otcSum,
ExOptionSum = exchangeListOptionSum,
FuturesSum = futuresSum,
ForwardSum = forwardSum,
SwapSum = swapSum
}
};
}).ToList();
var result = new RiskExposureReportModel
{
Sum = new RiskExposureReportSumModel
{
PortfolioSum = varietyRiskExposureReports.Select(r => r.VarietySum.PortfolioSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
OtcSum = varietyRiskExposureReports.Select(r => r.VarietySum.OtcSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
ExOptionSum = varietyRiskExposureReports.Select(r => r.VarietySum.ExOptionSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
FuturesSum = varietyRiskExposureReports.Select(r => r.VarietySum.FuturesSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
ForwardSum = varietyRiskExposureReports.Select(r => r.VarietySum.ForwardSum).Aggregate(new EodRiskModel(), (p, n) => p + n),
SwapSum = varietyRiskExposureReports.Select(r => r.VarietySum.SwapSum).Aggregate(new EodRiskModel(), (p, n) => p + n)
}
};
return result;
}
}
}