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

273 lines
13 KiB
C#

using BaseOUDAL;
using YLErp.BLL;
using YLErp.Commons;
using YLErp.Model;
using YLErp.Modules.EodModule;
using YLErp.Modules.RiskExposure;
using YLErp.Modules.RiskModule;
using YLErp.Modules.TradeModule;
using YLErp.QdpModule;
namespace YLErp.Modules.RiskHedgingModule
{
public class HedgeRiskMonitoringService : YLBaseService
{
private readonly ClientDBContext clientDB;
public HedgeRiskMonitoringService(OptUserInfo userInfo) : base(userInfo)
{
clientDB = DbContextFactory.GetClientDbContext(userInfo);
}
public HedgeRiskMonitoringService(YLBaseService baseService) : base(baseService)
{
}
public HedgeRiskMonitoringService(OptUserInfo optUser, YLContext dbContext) : base(optUser, dbContext)
{
}
/// <summary>
/// 读取配置
/// </summary>
/// <returns></returns>
public HedgeRiskMonitoringReq ReadHedgeRiskMonitoringReportConfig()
{
HedgeRiskMonitoringReq result = null;
try
{
var cfg = DbContext.AppConfig.Where(O => O.PName == "HedgeRiskMonitoringConfig").FirstOrDefault();
if (cfg == null)
{
result = new HedgeRiskMonitoringReq();
cfg = new AppConfig()
{
PGroup = "Custom",
PName = "HedgeRiskMonitoringConfig",
PType = "string",
Remark = "风险对冲检测表配置",
CreateTime = DateTime.Now,
};
DbContext.AppConfig.Add(cfg);
cfg.PValue = result.ToJson();
DbContext.SaveChanges();
}
else
{
result = JsonHelper.ToObject<HedgeRiskMonitoringReq>(cfg.PValue);
}
}
catch { }
return result ?? new HedgeRiskMonitoringReq();
}
/// <summary>
/// 保存配置
/// </summary>
/// <param name="req"></param>
public void SaveHedgeRiskMonitoringReportConfig(HedgeRiskMonitoringReq req)
{
try
{
var cfg = DbContext.AppConfig.Where(O => O.PName == "HedgeRiskMonitoringConfig").FirstOrDefault();
if (cfg == null)
{
cfg = new AppConfig()
{
PGroup = "System",
PName = "HedgeRiskMonitoringConfig",
PType = "string",
Remark = "风险对冲检测表配置",
CreateTime = DateTime.Now,
};
DbContext.AppConfig.Add(cfg);
}
cfg.PValue = req.ToJson();
cfg.OptDate = DateTime.Now;
DbContext.SaveChanges();
}
catch { }
}
public HedgeRiskMonitoringReportModel GetHedgeRiskMonitoringReportModel(DateTime endDate, HedgeRiskMonitoringReq req, RiskRequestModel reqRisk, EodPositionRisksReq eodPositionRisksReq, TradeMultiCloseQueryModel reqTradeMultiClose)
{
var hedgeRiskMonitoringReportModel = new HedgeRiskMonitoringReportModel();
//汇总
hedgeRiskMonitoringReportModel.QuotaTargetReport = new QuotaTargetReport()
{
QuotaStopLoss = req.quotaStopLoss,
QuotaCostRisk = req.quotaCostRisk,
QuotaPressureTest = req.quotaPressureTest,
QuotaCashDelta = req.quotaCashDelta,
QuotaContractTerm = req.quotaContractTerm,
QuotaUnderlyingConcentration = req.quotaUnderlyingConcentration,
QuotaStockEqvNotional = req.quotaStockEqvNotional,
QuotaMarginHold = req.quotaMarginHold,
};
if (PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (reqRisk?.EodSettlePriceMode == "结算价")
{
new Modules.RiskExposure.RiskExposureReportService<eod_trade_position_s>(UserInfo).GetPortfolioList<eod_trade_risk_s, eod_pnl_s>(reqRisk, out var riskCollectReport);
GetQuotaTargetReportByRiskCollect(endDate, hedgeRiskMonitoringReportModel.QuotaTargetReport, riskCollectReport, eodPositionRisksReq);
hedgeRiskMonitoringReportModel.RiskCollectReport = riskCollectReport;
}
else
{
new Modules.RiskExposure.RiskExposureReportService<eod_trade_position>(UserInfo).GetPortfolioList<eod_trade_risk, eod_pnl>(reqRisk, out var riskCollectReport);
GetQuotaTargetReportByRiskCollect(endDate, hedgeRiskMonitoringReportModel.QuotaTargetReport, riskCollectReport, eodPositionRisksReq);
hedgeRiskMonitoringReportModel.RiskCollectReport = riskCollectReport;
}
}
else
{
if (reqRisk?.EodSettlePriceMode == "结算价")
{
new Modules.RiskExposure.RiskExposureReportService<eod_trade_position_hedgevol_s>(UserInfo).GetPortfolioList<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(reqRisk, out var riskCollectReport);
GetQuotaTargetReportByRiskCollect(endDate, hedgeRiskMonitoringReportModel.QuotaTargetReport, riskCollectReport, eodPositionRisksReq);
hedgeRiskMonitoringReportModel.RiskCollectReport = riskCollectReport;
}
else
{
new Modules.RiskExposure.RiskExposureReportService<eod_trade_position_hedgevol>(UserInfo).GetPortfolioList<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(reqRisk, out var riskCollectReport);
GetQuotaTargetReportByRiskCollect(endDate, hedgeRiskMonitoringReportModel.QuotaTargetReport, riskCollectReport, eodPositionRisksReq);
hedgeRiskMonitoringReportModel.RiskCollectReport = riskCollectReport;
}
}
//预付金监控报表
hedgeRiskMonitoringReportModel.BondMonitorReport = GetClientLatestBalance(endDate);
if (hedgeRiskMonitoringReportModel.BondMonitorReport.BondMonitorDetails.Count == 0)
{
hedgeRiskMonitoringReportModel.BondMonitorReport.BondMonitorDetails.Add(new BondMonitorDetail() { IsRiskEventToDay = "", IsAppened = "" });
}
var PositionRisklist = new EodPositionRisksQueryService(UserInfo).GetEodPositionRisksDataHandle(eodPositionRisksReq);
var PositionRisklist2 = PositionRisklist.Select(n => new ExpandoDictionary<string, string>(n)).ToArray();
//日终报表
hedgeRiskMonitoringReportModel.PositionRiskReport = PositionRisklist2;
var OptionSettlelist = new Modules.TradeModule.QueryModule.OtcOptionMultiCloseService(UserInfo).HandleExportDataToList(reqTradeMultiClose);
var OptionSettlelist2 = OptionSettlelist.Select(n => new ExpandoDictionary<string, string>(n.MetaDic)).ToArray();
//了结报表
hedgeRiskMonitoringReportModel.OptionSettleReport = OptionSettlelist2;
//预付金占用
var currMargin = DbContext.exchange_account.Any() ? DbContext.exchange_account.Sum(O => O.CurrMargin) : 0;
hedgeRiskMonitoringReportModel.QuotaTargetReport.MarginHold = currMargin == 0 ? 0 : currMargin / 10000;//万元
return hedgeRiskMonitoringReportModel;
}
public BondMonitorReport GetClientLatestBalance(DateTime? ValueDateTo, bool IsClientBalanceGap = false, bool IsGetOuterMarginGap = false, bool ParentFlag = false)
{
var ValueDateFrom = ValueDateTo;
var context = new Modules.EodModule.QueryModule.EodSettleInfoQueryContext(UserInfo);
var clientIds = context.GetClientIds();
var cb = BLL.EodSettlement.ClientBalanceUtility.GetClientBanlances(clientIds, ValueDateFrom.Value, ValueDateTo.Value, IsClientBalanceGap, IsGetOuterMarginGap, ParentFlag).ToList();
var bondMonitorReport = new BondMonitorReport
{
BondMonitorDetails = new List<BondMonitorDetail>()
};
var MarginOccupationPositiveNumber = cb.Where(x => x.MarginOccupation > 0).ToList();
foreach (var item in MarginOccupationPositiveNumber)
{
var c = new YLContext();
var bondMonitorDetail = new BondMonitorDetail();
var name = clientDB.client.FirstOrDefault(l => l.id == item.ClientId).Name;
bondMonitorDetail.ClientName = name;
bondMonitorDetail.DepositReceivable = item.MarginOccupation;
bondMonitorDetail.CreditAndClosingBalance = item.AmountFund + item.TotalCredit;
bondMonitorReport.BondMonitorDetails.Add(bondMonitorDetail);
}
bondMonitorReport.SumBondMonitor = MarginOccupationPositiveNumber.Sum(x => x.MarginOccupation);
return bondMonitorReport;
}
public void ReqDefaultHandle(DateTime endDate, out RiskRequestModel reqRisk, out EodPositionRisksReq eodPositionRisksReq, out TradeMultiCloseQueryModel reqTradeMultiClose)
{
//方顿-风险监测表-汇总数据开始日期需要为每年的第一个交易日
var startDate = new DateTime(valuedateBLL.ValueDate.Year, 1, 1);
for (var i = 1; i < 30; i++)
{
if (!QdpCalendarHelper.IsHoliday(startDate))
{
break;
}
startDate = startDate.AddDays(1);
}
reqRisk = new RiskRequestModel
{
EodSettlePriceMode = "收盘价",
ValueDateStart = startDate,
ValueDateEnd = endDate
};
eodPositionRisksReq = new EodPositionRisksReq
{
EodSettlePriceMode = "收盘价",
IsOnlyExport = false,
IsParentTrade = false,
VolType = "持仓",
needSettleData = false,
page = 0,
rows = 0,
ValueDate = endDate
};
reqTradeMultiClose = new TradeMultiCloseQueryModel { GetTotal = true };
;
//reqTradeMultiClose.PageIndex = 1;
//reqTradeMultiClose.PageSize = 25;
//reqTradeMultiClose.TradeStatus = "确认成交,新增待确认,修改待确认,审批中,已拒绝,已执行,已平仓,已到期,平仓待复核,行权待复核,互换待复核,提前终止拒绝";
reqTradeMultiClose.UnWindType = "全部";
reqTradeMultiClose.UseForwardASwap = true;
reqTradeMultiClose.UnwindDateStart = startDate;
reqTradeMultiClose.UnwindDateEnd = endDate;
}
public void GetQuotaTargetReportByRiskCollect(DateTime endDate, QuotaTargetReport quotaTargetReport, RiskCollectReport riskCollectReport, EodPositionRisksReq eodPositionRisksReq)
{
quotaTargetReport.StopLoss = riskCollectReport.PortfolioSum.Pnl / 10000;//单位为万元
quotaTargetReport.CashDelta = riskCollectReport.PortfolioSum.DeltaCash / 10000;//单位为万元
quotaTargetReport.StockEqvNotional = riskCollectReport.PortfolioSum.OtcStockEqvNotionalReal / 10000;//单位为万元
var req = new Modules.EodModule.eod_varReq
{
ValueDate = endDate,
PvPercent = 0.95,
IsNeedExport = false
};
var results = new Modules.EodModule.EodVaRService(UserInfo).GetEodVaR(req);
//风险价值
quotaTargetReport.CostRisk = results.Any() ? ((double?)Math.Abs(results.First().WinLoss) / 10000) : null;//单位为万元
//压力测试
var req2 = new Modules.ScenarioModule.ScenarioRequest
{
//req2.ConfigId = 13;
UseTradeDivendRate = true,
ValueDate = endDate,
VolType = "对冲",
RiskFreeRate = valuedateBLL.SysRiskFreeRate(),
SearchModel = new Modules.ScenarioModule.TradeScenarioSearchModel
{
UserAssets = eodPositionRisksReq.UserAssets,
UserClients = eodPositionRisksReq.UserClients,
PositionDate = endDate,
IsSelAll = true,
page = 1,
rows = 20,
sord = "asc"
}
};
var config = DbContext.ScenarioConfig.Where(O => O.ConfigName == "对冲风险压力测试").FirstOrDefault();
if (config == null)
{
throw new ServiceException("没有找到名为\"对冲风险压力测试\"情景分析配置");
}
var result = new Modules.ScenarioModule.ScenarioCalcService(UserInfo).Calculate(req2, config);
quotaTargetReport.PressureTest = result.ResultItems.Any() ? ((double?)Math.Abs(result.ResultItems.GroupBy(o => $"{o.xIndex}_{o.yIndex}").ToList().Select(o => o.Sum(O => O.PnL)).Min()) / 10000)/*单位为万元*/ : null;
}
}
}