2178 lines
112 KiB
C#
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;
|
|
}
|
|
|
|
}
|
|
}
|