Files
zszq-trs/YLErpWeb/Controllers/riskController.cs
T

1059 lines
51 KiB
C#

using Microsoft.AspNetCore.Authorization;
using YLErp.BLL.Eod;
using YLErp.Enums;
using YLErp.Model.HengTaiModel;
using YLErp.Modules.ApiModule;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.ClientModule;
using YLErp.Modules.ExchangeOptionTradeModule;
using YLErp.Modules.MarketRiskMoudule;
using YLErp.Modules.RiskExposure;
using YLErp.Modules.RiskListModule;
using YLErp.Modules.RiskModule;
using YLErp.Modules.ToolsModule;
using YLErp.Modules.TradeDalModule;
using YLErp.Modules.TradeModule;
namespace YLErp.Web.Controllers
{
public class riskController : BaseController
{
[MyAuthorize("风险控制-市场风险")]
public ActionResult RiskExposureReport()
{
ViewBag.lastDate_eod = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
ViewBag.lastDate_settle = EodOperationBase.GetLastSettlementDate_Settle();
var tradeTypes = ConsTrade.AllTradeTypes.Except(ConsTrade.TradeTypesForHedge).Select(O => O == "现金流交易" ? "结构化交易" : O).ToList();
//tradeTypes.AddRange(new TradeDalService(CurUser).GetTradeStructureType(DateTime.Today.AddYears(-1), tradeTypes));
ViewBag.tradeTypes = tradeTypes.Select(O => O == "结构化交易" ? "自由组合" : O);
return View();
}
[MyAuthorize("风险控制-市场风险")]
public JsonResult RiskExposureReportQuery(RiskRequestModel req, bool usePositionVol = false)
{
if (req.TradeTypes != null && req.TradeTypes.Any())
{
req.TradeTypes = req.TradeTypes.Select(O => O == "自由组合" ? "结构化交易" : O);
}
req.BookIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.BookIds).ToList();
req.UserAssets = CurUser.GetAssetUnitIds();
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
req.CurUserTradeIds = CurUser.GetTradeIdsByCurUser();
RiskExposureReportModel result;
var useOldMaskRiskService = Environment.GetEnvironmentVariable("AppSettings:UseOldMaskRiskService");
if (!string.IsNullOrEmpty(useOldMaskRiskService) && "true".Equals(useOldMaskRiskService))
{
if (usePositionVol || PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (req.EodSettlePriceMode == "结算价")
{
if (req.DividendRateType == "采集")
{
result = new RiskExposureReportService<eod_trade_position_extend_s>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk_extend_s, eod_pnl_extend_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position_s>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk_s, eod_pnl_s>(req);
}
}
else
{
if (req.DividendRateType == "采集")
{
result = new RiskExposureReportService<eod_trade_position_extend>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk_extend, eod_pnl_extend>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk, eod_pnl>(req);
}
}
}
else
{
if (req.EodSettlePriceMode == "结算价")
{
result = new RiskExposureReportService<eod_trade_position_hedgevol_s>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position_hedgevol>(CurUser).SearchRiskExposureReportsV2<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(req);
}
}
}
else
{
if (usePositionVol || PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (req.EodSettlePriceMode == "结算价")
{
if (req.DividendRateType == "采集")
{
result = new MarketRiskService<eod_trade_position_extend_s>(CurUser).SearchMarketRiskData<eod_trade_risk_extend_s, eod_pnl_extend_s>(req);
}
else
{
result = new MarketRiskService<eod_trade_position_s>(CurUser).SearchMarketRiskData<eod_trade_risk_s, eod_pnl_s>(req);
}
}
else
{
if (req.DividendRateType == "采集")
{
result = new MarketRiskService<eod_trade_position_extend>(CurUser).SearchMarketRiskData<eod_trade_risk_extend, eod_pnl_extend>(req);
}
else
{
result = new MarketRiskService<eod_trade_position>(CurUser).SearchMarketRiskData<eod_trade_risk, eod_pnl>(req);
}
}
}
else
{
if (req.EodSettlePriceMode == "结算价")
{
result = new MarketRiskService<eod_trade_position_hedgevol_s>(CurUser).SearchMarketRiskData<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(req);
}
else
{
result = new MarketRiskService<eod_trade_position_hedgevol>(CurUser).SearchMarketRiskData<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(req);
}
}
}
return JsonSuccess("", result);
}
[MyAuthorize("风险控制-市场风险")]
public ActionResult ExportRiskExposureReport(RiskRequestModel req)
{
if (req.TradeTypes != null && req.TradeTypes.Any())
{
req.TradeTypes = req.TradeTypes.Select(O => O == "自由组合" ? "结构化交易" : O);
}
req.BookIds = AssetUnitModel.IntersectAssetUnits(req.AssetIdGroupList, req.BookIds).ToList();
req.UserAssets = CurUser.GetAssetUnitIds();
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
byte[] result;
if (PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (req?.EodSettlePriceMode == "结算价")
{
result = new RiskExposureReportService<eod_trade_position_s>(CurUser).ExportReport<eod_trade_risk_s, eod_pnl_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position>(CurUser).ExportReport<eod_trade_risk, eod_pnl>(req);
}
}
else
{
if (req?.EodSettlePriceMode == "结算价")
{
result = new RiskExposureReportService<eod_trade_position_hedgevol_s>(CurUser).ExportReport<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position_hedgevol>(CurUser).ExportReport<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(req);
}
}
string fileDownloadName;
if (req.ValueDateStart == null || req.ValueDateStart == req.ValueDateEnd)
{
fileDownloadName = $"市场风险_{req.ValueDateEnd:yyyyMMdd}.xlsx";
}
else
{
fileDownloadName = $"市场风险_{req.ValueDateStart:yyyyMMdd}_{req.ValueDateEnd:yyyyMMdd}.xlsx";
}
return File(result, xlsxMimeType, fileDownloadName);
}
[MyAuthorize("风险控制-风控列表")]
public ActionResult RiskControlList()
{
var dailySummary = new RiskLimitDailySummary();
ViewBag.RiskLimitDailySummary = dailySummary;
ViewBag.ValueDate = new DateTime();
return View();
}
public ActionResult RiskDailyReport(DateTime? valueDate)
{
var dailySummary = new RiskLimitDailySummary();
var exchangeService = new EodExchangeOptionPriceService(CurUser);
var riskCalcService = new EodExchangeOptionRiskCalcService(CurUser);
var optionDeltaCash_Base = new Dictionary<string, double>();
var exchangeDeltaCash_Base = new Dictionary<string, double>();
var optionDeltaCash_Auxiliary = new Dictionary<string, double>();
var exchangeDeltaCash_Auxiliary = new Dictionary<string, double>();
var futureDeltaCash = new Dictionary<string, double>();
RiskDailyReportService service = null;
ViewBag.ErrorMessage = string.Empty;
try
{
if (!valueDate.HasValue)
{
//当前估值日期
valueDate = valuedateBLL.ValueDate;
}
//var logHelper = LogFactory.GetLogger("RiskController");
service = new RiskDailyReportService(CurUser, valueDate.Value);
var reportLimit = new RiskLimitBLL().GetRiskDailyReportLimit();
var currentExchangeList = service.GetExchangePositionList(service.CurrentEndDate);
var yestDayExchangeList = service.GetExchangePositionList(service.CurrentLastDate);
var lastExchangeList = service.GetExchangePositionList(service.LastYearEndDate);
var currentExchangeBase = currentExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.ClosePrice ?? 0) - O.Key.TradeSinglePrice));
var currentExchangeAuxiliary = currentExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.SettlePrice ?? 0) - O.Key.TradeSinglePrice));
var yestDayExchangeBase = yestDayExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.ClosePrice ?? 0) - O.Key.TradeSinglePrice));
var yestDayExchangeAuxiliary = yestDayExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.SettlePrice ?? 0) - O.Key.TradeSinglePrice));
var lastExchangeBase = lastExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.ClosePrice ?? 0) - O.Key.TradeSinglePrice));
var lastExchangeAuxiliary = lastExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.SettlePrice ?? 0) - O.Key.TradeSinglePrice));
futureDeltaCash = service.GetFutureDeltaCash<eod_trade_position>(service.CurrentEndDate);
var hedgePnl = riskCalcService.CalculateEodRisk<eod_trade_position_hedgevol>(service.CurrentEndDate, "对冲", TradeCalcHelper.UseClosePrice());
var underlyingId =
(from pnl in hedgePnl
join underlying in yldb.underlying_manager
on pnl.UnderlyingId equals underlying.id
select new { underlying.CommodityCode, pnl })
.GroupBy(O => O.CommodityCode)
.ToDictionary(K => K.Key, V => V.Select(O => O.pnl).ToList());
exchangeDeltaCash_Base = underlyingId.ToDictionary(K => K.Key, V => V.Value.Sum(O => O.DeltaCash));
var deltaCash_Exchange_Base = underlyingId.Values.Select(O => O.Sum(B => B.DeltaCash)).Sum(O => Math.Abs(O));
var gammaCash_Exchange_Base = underlyingId.Values.Select(O => O.Sum(B => B.GammaCash * 0.5 * 0.01)).Sum(O => O);
var extendpnl = riskCalcService.CalculateEodRisk<eod_trade_position_extend>(service.CurrentEndDate, "光证", TradeCalcHelper.UseClosePrice());
underlyingId =
(from pnl in extendpnl
join underlying in yldb.underlying_manager
on pnl.UnderlyingId equals underlying.id
select new { underlying.CommodityCode, pnl })
.GroupBy(O => O.CommodityCode)
.ToDictionary(K => K.Key, V => V.Select(O => O.pnl).ToList());
exchangeDeltaCash_Auxiliary = underlyingId.ToDictionary(K => K.Key, V => V.Value.Sum(O => O.DeltaCash));
var deltaCash_Exchange_VarietyVol = underlyingId.Values.Select(O => O.Sum(B => B.DeltaCash)).Sum(O => Math.Abs(O));
var gammaCash_Exchange_VarietyVol = underlyingId.Values.Select(O => O.Sum(B => B.GammaCash * 0.5 * 0.01)).Sum(O => O);
var currentAccruedTotalPnL = service.GetOptionPositionAccruedTotalPnL<eod_trade_position>(service.CurrentEndDate);
var currentAccruedTotalPnL_Variety = service.GetOptionPositionAccruedTotalPnL<eod_trade_position_extend>(service.CurrentEndDate);
#region 光子波动率
var dailyOptionEndPnl = service.GetOptionEndPnl(service.CurrentEndDate, service.CurrentEndDate);
optionDeltaCash_Base = service.GetOptionDeltaCash<eod_trade_risk_hedgevol, eod_trade_position_hedgevol>(service.CurrentEndDate);
var deltaCash = optionDeltaCash_Base.Values.Sum(O => Math.Abs(O));
var gammaCash = service.GetOptionGammaCash<eod_trade_risk_hedgevol, eod_trade_position_hedgevol>(service.CurrentEndDate);
var deltaCashPercentValue = reportLimit.DeltaCashPercent.LimitValueType == 1 ? (deltaCash * (double)reportLimit.DeltaCashPercent.LimitValue) : (double)reportLimit.DeltaCashPercent.LimitValue;
var gammaCashPercentValue = reportLimit.GammaCashPercent.LimitValueType == 1 ? (gammaCash * (double)reportLimit.GammaCashPercent.LimitValue) : (double)reportLimit.DeltaCashPercent.LimitValue;
var yearOptionEndPnl = service.GetOptionEndPnl(service.CurrentStartDate, service.CurrentEndDate);
var currentOptionPositionList = service.GetOptionPositionList<eod_trade_position>(service.CurrentEndDate);
#endregion
#region 光证波动率
var dailyFutureList_VarietyVol = service.GetFutureList<eod_trade_position_extend>(service.CurrentEndDate);
Dictionary<string, double> futurePriceList_VarietyVol = null;
if (dailyFutureList_VarietyVol.Count > 0)
{
var codeList = dailyFutureList_VarietyVol.Where(O => O.UnderlyingCode != null).Select(O => O.UnderlyingCode).ToList();
futurePriceList_VarietyVol = new EodCommodityFuturePriceService(CurUser).GetPriceDiff(codeList, service.CurrentEndDate, service.CurrentLastDate);
}
optionDeltaCash_Auxiliary = service.GetOptionDeltaCash<eod_trade_risk_extend, eod_trade_position_extend>(service.CurrentEndDate);
var deltaCash_VarietyVol = optionDeltaCash_Auxiliary.Values.Sum(O => Math.Abs(O));
var gammaCash_VarietyVol = service.GetOptionGammaCash<eod_trade_risk_extend, eod_trade_position_extend>(service.CurrentEndDate);
var yearFutureTotlePnl_VarietyVol = service.GetYearFutureTotlePnl<eod_trade_position_extend>(service.CurrentStartDate, service.CurrentEndDate, service.LastYearEndDate);
var yearFuturePositionPnl_VarietyVol = service.GetYearFuturePositionPnl<eod_trade_position_extend>(service.CurrentEndDate);
var currentOptionPositionList_VarietyVol = service.GetOptionPositionList<eod_trade_position_extend>(service.CurrentEndDate);
#endregion
dailySummary.YearPnl.LimitValue = (double)reportLimit.YearPnlLimit.LimitValue;
dailySummary.DailyPnl.LimitValue = (double)reportLimit.DailyPnlLimit.LimitValue;
dailySummary.DeltaCashLimit.LimitValue =
deltaCashPercentValue > (double)reportLimit.DeltaPnlLimit.LimitValue
? deltaCashPercentValue : (double)reportLimit.DeltaPnlLimit.LimitValue;
dailySummary.GammaCashLimit.LimitValue =
gammaCashPercentValue > (double)reportLimit.GammaPnlLimit.LimitValue
? gammaCashPercentValue : (double)reportLimit.GammaPnlLimit.LimitValue;
dailySummary.HoldingDeposit = service.CurrMargin;
dailySummary.Amount = service.CurrFund;
dailySummary.Risk = service.CurrMargin / service.CurrFund;
dailySummary.OptionStockEqvNotional = service.GetTradePrice(service.CurrentEndDate);
dailySummary.PositionValue.Option.BaseValue = (double)currentOptionPositionList.Sum(O => O.Pv);
dailySummary.PositionValue.Option.AuxiliaryValue = (double)currentOptionPositionList_VarietyVol.Sum(O => O.Pv);
dailySummary.PositionValue.Exchange.BaseValue = currentExchangeList.Sum(O => O.Key.TradeAmount * ((O.Value?.ClosePrice) ?? 0));
dailySummary.PositionValue.Exchange.AuxiliaryValue = currentExchangeList.Sum(O => O.Key.TradeAmount * (O.Value?.SettlePrice) ?? 0);
dailySummary.DailyPnl.Option.OptionEndPnl = dailyOptionEndPnl;
dailySummary.DailyPnl.Option.ExchangeEndPnl = exchangeService.GetEndPnl(service.CurrentEndDate);
dailySummary.DailyPnl.Option.Position.Option.BaseValue = currentAccruedTotalPnL - service.GetOptionPositionAccruedTotalPnL<eod_trade_position>(service.CurrentLastDate);
dailySummary.DailyPnl.Option.Position.Option.AuxiliaryValue = currentAccruedTotalPnL_Variety - service.GetOptionPositionAccruedTotalPnL<eod_trade_position_extend>(service.CurrentLastDate);
dailySummary.DailyPnl.Option.Position.Exchange.BaseValue = currentExchangeBase - yestDayExchangeBase;
dailySummary.DailyPnl.Option.Position.Exchange.AuxiliaryValue = currentExchangeAuxiliary - yestDayExchangeAuxiliary;
dailySummary.DailyPnl.Option.Total.Option.BaseValue = dailySummary.DailyPnl.Option.Position.Option.BaseValue + dailySummary.DailyPnl.Option.OptionEndPnl;
dailySummary.DailyPnl.Option.Total.Option.AuxiliaryValue = dailySummary.DailyPnl.Option.Position.Option.AuxiliaryValue + dailySummary.DailyPnl.Option.OptionEndPnl;
dailySummary.DailyPnl.Option.Total.Exchange.BaseValue = dailySummary.DailyPnl.Option.Position.Exchange.BaseValue + dailySummary.DailyPnl.Option.ExchangeEndPnl;
dailySummary.DailyPnl.Option.Total.Exchange.AuxiliaryValue = dailySummary.DailyPnl.Option.Position.Exchange.AuxiliaryValue + dailySummary.DailyPnl.Option.ExchangeEndPnl;
dailySummary.DailyPnl.Future.EndPnl = dailySummary.DailyPnl.Future.TotalPnl - dailySummary.DailyPnl.Future.Pnl;
dailySummary.DailyPnl.SetSummary();
dailySummary.YearPnl.Option.OptionEndPnl = yearOptionEndPnl;
dailySummary.YearPnl.Option.ExchangeEndPnl = exchangeService.GetEndPnl(service.CurrentEndDate, service.CurrentStartDate);
dailySummary.YearPnl.Option.Position.Option.BaseValue = currentAccruedTotalPnL - service.GetOptionPositionAccruedTotalPnL<eod_trade_position>(service.LastYearEndDate);
dailySummary.YearPnl.Option.Position.Option.AuxiliaryValue = currentAccruedTotalPnL_Variety - service.GetOptionPositionAccruedTotalPnL<eod_trade_position_extend>(service.LastYearEndDate);
dailySummary.YearPnl.Option.Position.Exchange.BaseValue = currentExchangeBase - lastExchangeBase;
dailySummary.YearPnl.Option.Position.Exchange.AuxiliaryValue = currentExchangeAuxiliary - lastExchangeAuxiliary;
dailySummary.YearPnl.Option.Total.Option.BaseValue = dailySummary.YearPnl.Option.Position.Option.BaseValue + dailySummary.YearPnl.Option.OptionEndPnl;
dailySummary.YearPnl.Option.Total.Option.AuxiliaryValue = dailySummary.YearPnl.Option.Position.Option.AuxiliaryValue + dailySummary.YearPnl.Option.OptionEndPnl;
dailySummary.YearPnl.Option.Total.Exchange.BaseValue = dailySummary.YearPnl.Option.Position.Exchange.BaseValue + dailySummary.YearPnl.Option.ExchangeEndPnl;
dailySummary.YearPnl.Option.Total.Exchange.AuxiliaryValue = dailySummary.YearPnl.Option.Position.Exchange.AuxiliaryValue + dailySummary.YearPnl.Option.ExchangeEndPnl;
dailySummary.YearPnl.Future.EndPnl = dailySummary.YearPnl.Future.TotalPnl - dailySummary.YearPnl.Future.Pnl;
dailySummary.YearPnl.SetSummary();
dailySummary.DeltaCashLimit.Option.Option.BaseValue = deltaCash;
dailySummary.DeltaCashLimit.Option.Exchange.BaseValue = deltaCash_Exchange_Base;
dailySummary.DeltaCashLimit.Option.Option.AuxiliaryValue = deltaCash_VarietyVol;
dailySummary.DeltaCashLimit.Option.Exchange.AuxiliaryValue = deltaCash_Exchange_VarietyVol;
dailySummary.DeltaCashLimit.FutureValue = futureDeltaCash.Sum(O => Math.Abs(O.Value));
dailySummary.GammaCashLimit.Option.Option.BaseValue = gammaCash;
dailySummary.GammaCashLimit.Option.Exchange.BaseValue = gammaCash_Exchange_Base;
dailySummary.GammaCashLimit.Option.Option.AuxiliaryValue = gammaCash_VarietyVol;
dailySummary.GammaCashLimit.Option.Exchange.AuxiliaryValue = gammaCash_Exchange_VarietyVol;
}
catch (Exception ex)
{
LogFactory.GetLogger("RiskDailyReport").Error(ex, ex.Message);
ViewBag.ErrorMessage = ex.Message;
}
ViewBag.RiskLimitDailySummary = dailySummary;
ViewBag.optionDeltaCash_Base = optionDeltaCash_Base;
ViewBag.exchangeDeltaCash_Base = exchangeDeltaCash_Base;
ViewBag.optionDeltaCash_Auxiliary = optionDeltaCash_Auxiliary;
ViewBag.exchangeDeltaCash_Auxiliary = exchangeDeltaCash_Auxiliary;
ViewBag.FutureDeltaCash = futureDeltaCash;
ViewBag.ValueDate = (service?.CurrentEndDate) ?? DateTime.MinValue;
ViewBag.MaxDate = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
return PartialView();
}
[MyAuthorize("风险控制-风险预警/禁止查询")]
public ActionResult SubstandardTrade()
{
return View();
}
[MyAuthorize("风险控制-风险预警/禁止查询")]
public ActionResult SubstandardTradeRule()
{
var obj = new SubstandardTradeRuleService(CurUser).QueryCurrentRule();
return View(obj);
}
public JsonResult CurrentSubstandardTradeRule()
{
var obj = new SubstandardTradeRuleService(CurUser).QueryCurrentRule();
return JsonSuccess("", obj);
}
[MyAuthorize("风险控制-风险预警/禁止查询")]
public ActionResult SubstandardTradeRuleList()
{
return View();
}
public JsonResult SubstandardTradeRuleQuery(BaseSearchReq req)
{
req.sidx = "OptDate";
req.sord = "desc";
var result = new SubstandardTradeRuleService(CurUser).QueryRuleList(req);
return Json(result);
}
public JsonResult SaveSubstandardTradeRule(SubstandardTradeRule rule)
{
if (rule == null)
{
throw new ServiceException("参数不应为null");
}
new SubstandardTradeRuleService(CurUser).SaveRule(rule);
return JsonSuccess();
}
public ActionResult SetRiskDailyReportLimit(List<RiskLimit> riskLimits)
{
if (riskLimits == null)
{
ViewBag.Data = new RiskLimitBLL().GetRiskDailyReportLimit();
return View();
}
var riskLimitNames = riskLimits.Select(O => O.LimitName).ToList();
using (var Db = new YLContext())
{
var dbRiskLimitDict = (from limitDb in Db.Risk_Limit where riskLimitNames.Contains(limitDb.LimitName) select limitDb).ToDictionary(K => K.LimitName, V => V);
for (var i = 0; i < riskLimits.Count; i++)
{
//if (riskLimits[i].LimitValue <= 0)
//{
// throw new Exception("限额不应小于零");
//}
switch (riskLimits[i].LimitName)
{
case "风控日报_年盈亏限额":
case "风控日报_日盈亏限额":
case "场外期权_Delta限额":
case "场外期权_Gamma限额":
riskLimits[i].LimitValueType = 0;
riskLimits[i].LimitBenchmark = "";
break;
case "场外期权_DeltaCash":
riskLimits[i].LimitValueType = 1;
riskLimits[i].LimitBenchmark = "DeltaCash";
break;
case "场外期权_GammaCash":
riskLimits[i].LimitValueType = 1;
riskLimits[i].LimitBenchmark = "GammaCash";
break;
}
riskLimits[i].OptTime = DateTime.Now;
riskLimits[i].OptName = UserName;
if (!dbRiskLimitDict.ContainsKey(riskLimits[i].LimitName))
{
Db.Risk_Limit.Add(riskLimits[i]);
}
else
{
dbRiskLimitDict[riskLimits[i].LimitName].LimitValueType = riskLimits[i].LimitValueType;
dbRiskLimitDict[riskLimits[i].LimitName].LimitValue = riskLimits[i].LimitValue;
dbRiskLimitDict[riskLimits[i].LimitName].LimitBenchmark = riskLimits[i].LimitBenchmark;
dbRiskLimitDict[riskLimits[i].LimitName].OptTime = riskLimits[i].OptTime;
dbRiskLimitDict[riskLimits[i].LimitName].OptName = riskLimits[i].OptName;
}
}
Db.SaveChanges();
}
return JsonSuccess();
}
[MyAuthorize("风险控制-对冲行为监控")]
public ActionResult HedgingMonitor()
{
ViewBag.ValueDate = valuedateBLL.ValueDate;
return View();
}
public JsonResult HedgingMonitorQuery(HedgingMonitorReq req)
{
req.page = 1;
req.rows = 10000;
req.sidx = "UnderlyingCode";
var result = new HedgingMonitorService(CurUser).Query(req);
return Json(result);
}
[MyAuthorize("风险控制-限额监控")]
public ActionResult QuotaMonitor()
{
ViewBag.SummaryType = "整体业务汇总";
var baseDb = DbContextFactory.GetErpBaseContext();
ViewBag.ActualSubject = (from type in baseDb.Dictionaries
join item in baseDb.DictionaryItems
on type.Id equals item.DictId
where type.Name == "同一主体"
orderby item.IndexNum
select item.Name).ToArray();
ViewBag.QuotaIndexList = QuotaMonitorService.QuotaIndexList;
return View();
}
[HttpPost]
public JsonResult QuotaMonitorMsgQuery()
{
var dic = WarningService.GetInstance();
return Json(dic);
}
[HttpPost]
public JsonResult QuotaMonitorMsgStates()
{
var Total = WarningService.GetModelSum();
return Json(Total);
}
public JsonResult QuotaMonitorMsgUpdateTime()
{
var updateTime = WarningService.GetUpdateTime();
var updateTimeStr = "";
if (updateTime.HasValue)
{
updateTimeStr = updateTime.Value.ToString("yyyy-MM-dd HH:mm");
}
return Json(updateTimeStr);
}
public JsonResult QuotaMonitorQuery(QuotaMonitorReq req)
{
var service = new QuotaMonitorService(CurUser);
object result;
switch (req.SummaryType)
{
case "整体业务汇总":
if (req.ValueDate > DateTime.MinValue && req.ValueDate != valuedateBLL.ValueDate)
{ result = service.QueryGlobalFromDb(req); }
else
{ result = service.QueryGlobalFromCalc(req); }
break;
case "标的汇总":
if (req.ValueDate > DateTime.MinValue && req.ValueDate != valuedateBLL.ValueDate)
{ result = service.QueryUnderlyingFromDb(req); }
else
{ result = service.QueryUnderlyingFromCalc(req); }
break;
case "逐笔汇总":
if (req.ValueDate > DateTime.MinValue && req.ValueDate != valuedateBLL.ValueDate)
{ result = service.QueryTradeFromDb(req); }
else
{ result = service.QueryTradeFromCalc(req); }
break;
case "客户汇总":
if (req.ValueDate > DateTime.MinValue && req.ValueDate != valuedateBLL.ValueDate)
{ result = service.QueryClientFromDb(req); }
else
{ result = service.QueryClientFromCalc(req); }
break;
case "限额指标记录":
result = service.QuerySetting(req);
break;
case "簿记汇总":
if (req.ValueDate > DateTime.MinValue && req.ValueDate != valuedateBLL.ValueDate)
{ result = service.QueryAssetUnitFromDb(req); }
else
{ result = service.QueryAssetUnitFromCalc(req); }
break;
default:
throw new ServiceException("参数错误");
}
return Json(result);
}
/// <summary>
/// 限额审批
/// </summary>
/// <param name="id"></param>
/// <param name="optType"></param>
/// <param name="optDate"></param>
/// <param name="remark"></param>
/// <returns></returns>
public JsonResult ApprovalQuotaSetting(List<ApprovalReqq> req)
{
try
{
new QuotaMonitorService(CurUser).ApprovalQuotaSetting(req);
return JsonSuccess("操作成功");
}
catch (ServiceException ex)
{
return JsonError(ex.Message);
}
}
[MyAuthorize("风险控制-限额监控")]
public ActionResult QuotaSetting()
{
return View();
}
public ActionResult UploadQuotaSetting(IFormFile file, bool checkStatus)
{
try
{
file = Request.Form.Files[0];
if (file == null || string.IsNullOrWhiteSpace(file.FileName))
{
return JsonError("未获取上传文件");
}
if (!file.FileName.Contains("导入限额指标"))
{
throw new ServiceException("导入限额指标模板不正确");
}
var fileExtension = Path.GetExtension(file.FileName);
using var openStream = file.OpenReadStream();
var result = new QuotaMonitorService(CurUser).ImportFromCsv(openStream);
return JsonSuccess("导入成功");
}
catch (ApiException ex)
{
LogFactory.GetLogger("导入限额指标").Error("导入限额指标出错", ex);
return JsonError(ex.Message);
}
}
public JsonResult QuotaSettingQuery()
{
var result = new QuotaMonitorService(CurUser).QueryCurrentQuotaSetting();
var rule = new QuotaRule
{
BusinessTotalScale = valuedateBLL.SystemDate.BusinessTotalScale,
BusinessAvailableFunds = valuedateBLL.SystemDate.BusinessAvailableFunds,
SingleUnderlyingRate = valuedateBLL.SystemDate.SingleUnderlyingRate,
QuotaSettings = result
};
return Json(rule);
}
public JsonResult SaveQuotaSetting(QuotaRule rule)
{
var logArr = new List<Processlog>();
try
{
var logTextArr = new List<string>();
if (rule.BusinessTotalScale != valuedateBLL.SystemDate.BusinessTotalScale)
{
logTextArr.Add($"业务合约总规模:{valuedateBLL.SystemDate.BusinessTotalScale?.ToString("N")}->{rule.BusinessTotalScale?.ToString("N")}");
var config = valuedateController.SetValueDate(m =>
{
m.BusinessTotalScale = rule.BusinessTotalScale;
});
}
if (rule.BusinessAvailableFunds != valuedateBLL.SystemDate.BusinessAvailableFunds)
{
logTextArr.Add($"业务投入资金:{valuedateBLL.SystemDate.BusinessAvailableFunds?.ToString("N")}->{rule.BusinessAvailableFunds?.ToString("N")}");
var config = valuedateController.SetValueDate(m =>
{
m.BusinessAvailableFunds = rule.BusinessAvailableFunds;
});
}
if (rule.SingleUnderlyingRate != valuedateBLL.SystemDate.SingleUnderlyingRate)
{
logTextArr.Add($"单标的品种合约总规模占业务合约总规模比例上限:{valuedateBLL.SystemDate.SingleUnderlyingRate?.ToString("N")}->{rule.SingleUnderlyingRate?.ToString("N")}");
var config = valuedateController.SetValueDate(m =>
{
m.SingleUnderlyingRate = rule.SingleUnderlyingRate;
});
}
if (logTextArr.Count > 0)
{
logArr.Add(new Processlog()
{
TypeId = 0,
ProcessType = "QuotaSetting",
ProcessStatus = "修改",
Log = string.Join("\r\n", logTextArr),
Remark = rule.Remark,
OptId = CurUser.UserId,
CreateTime = DateTime.Now
});
}
var service = new QuotaMonitorService(CurUser);
logArr.AddRange(service.SaveQuotaSettings(rule.QuotaSettings));
var log = new ClientProcessLogService(CurUser);
logArr.ForEach(O =>
{
O.Remark = rule.Remark;
log.SetLog(O);
});
}
catch (Exception ex)
{
LogFactory.GetLogger("SaveQuotaSetting").Error(ex);
return JsonSuccess("保存失败");
}
return JsonSuccess("保存成功");
}
public JsonResult DeleteQuotaSetting(QuotaTypeEnum quotaType, int quotaRange)
{
if (quotaRange <= 0)
{
return JsonError("不允许删除全局配置");
}
try
{
new QuotaMonitorService(CurUser).DeleteQuotaSettings(quotaType, quotaRange);
}
catch (Exception ex)
{
LogFactory.GetLogger("DeleteQuotaSetting").Error(ex);
return JsonSuccess("删除失败");
}
return JsonSuccess("删除成功");
}
public JsonResult QuotaSettingHistory(ProcesslogReq req)
{
var result = new QuotaMonitorService(CurUser).QueryQuotaSettingHistory(req);
return Json(result);
}
[MyAuthorize("风险控制-观察事件")]
public ActionResult KonckOutList(string settleDate = null)
{
ViewBag.AlertLineKonckInLimit = valuedateBLL.SystemDate.AlertLineKonckInLimit;
ViewBag.AlertLineKonckOutLimit = valuedateBLL.SystemDate.AlertLineKonckOutLimit;
ViewBag.settleDate = settleDate;
if (settleDate == null)
{
ViewBag.settleDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
[MyAuthorize("风险控制-观察事件")]
public ActionResult KonckInList(string settleDate = null)
{
ViewBag.AlertLineKonckInLimit = valuedateBLL.SystemDate.AlertLineKonckInLimit;
ViewBag.AlertLineKonckOutLimit = valuedateBLL.SystemDate.AlertLineKonckOutLimit;
ViewBag.settleDate = settleDate;
if (settleDate == null)
{
ViewBag.settleDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
[MyAuthorize("风险控制-观察事件")]
public ActionResult CouponList(string settleDate = null)
{
ViewBag.AlertLineKonckInLimit = valuedateBLL.SystemDate.AlertLineKonckInLimit;
ViewBag.AlertLineKonckOutLimit = valuedateBLL.SystemDate.AlertLineKonckOutLimit;
ViewBag.settleDate = settleDate;
if (settleDate == null)
{
ViewBag.settleDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
[MyAuthorize("风险控制-观察事件")]
public ActionResult CustomList(string settleDate = null)
{
ViewBag.settleDate = settleDate;
if (settleDate == null)
{
ViewBag.settleDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
public JsonResult ObservationEventTradeQuery(TdTradeQueryModel req)
{
req.UserAssets = CurUser.GetAssetUnitIds();
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
var sList = new TodayTradeQueryService(CurUser).GetObservationEventTradeList(req);
return Json(sList);
}
public ActionResult EventCalendar()
{
return View();
}
public JsonResult getDailyEvents(DateTime? date)
{
var userAssets = CurUser.GetAssetUnitIds();
var userClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
try
{
var ret = new TodayTradeQueryService(CurUser).getDailyEvents(date, userAssets, userClients);
return Json(ret);
}
catch (Exception e)
{
return JsonError(date.OtcFormatDate() + e.Message, date);
}
}
public ActionResult TrendChart()
{
return View();
}
public JsonResult GetDateSection(string DateSection)
{
var valueDatetime = EodOperationBase.GetLastSettlementDate(valuedateBLL.ValueDate);
List<DateTime> datetimes = new List<DateTime>();
switch (DateSection)
{
case "最近7日":
datetimes.Add(valuedateBLL.GetNonHoliday(valueDatetime.AddDays(-7)));
break;
case "最近30日":
datetimes.Add(valuedateBLL.GetNonHoliday(valueDatetime.AddDays(-30)));
break;
case "最近60日":
datetimes.Add(valuedateBLL.GetNonHoliday(valueDatetime.AddDays(-60)));
break;
case "最近100日":
datetimes.Add(valuedateBLL.GetNonHoliday(valueDatetime.AddDays(-100)));
break;
}
datetimes.Add(valueDatetime);
return Json(datetimes);
}
public JsonResult CreateTrendChart(RiskRequestModel req)
{
if (req.TradeTypes != null && req.TradeTypes.Any())
{
req.TradeTypes = req.TradeTypes.Select(O => O == "自由组合" ? "结构化交易" : O);
}
req.UserAssets = CurUser.GetAssetUnitIds();
req.UserClients = CurUser.GetClientIdsByCurUser(CurUser.交易管理_查看所有交易);
RiskExposureReportModel result;
TrendChartModel trendChartModel = new TrendChartModel();
var portfolioData = new List<string>();
var otcData = new List<string>();
var exOptionData = new List<string>();
var futuresData = new List<string>();
var forwardData = new List<string>();
var swapData = new List<string>();
var startDate = req.ValueDateStart.Value;
var endDate = req.ValueDateEnd;
var days = new List<DateTime>();
var taskList = new List<Task>();
for (var date = startDate; date <= endDate; date = date.AddDays(1))
{
if (!valuedateBLL.IsHoliday(date))
{
days.Add(date);
}
}
var useOldMaskRiskService = Environment.GetEnvironmentVariable("AppSettings:UseOldMaskRiskService");
if (!string.IsNullOrEmpty(useOldMaskRiskService) && "true".Equals(useOldMaskRiskService))
{
days.ForEach(a =>
{
trendChartModel.XAxisData.Add(a.ToString("yyyy-MM-dd"));
req.ValueDateStart = a;
req.ValueDateEnd = a;
//var temp = RiskExposureReportQuery(req);
if (PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (req.EodSettlePriceMode == "结算价")
{
result = new RiskExposureReportService<eod_trade_position_s>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_s, eod_pnl_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk, eod_pnl>(req);
}
}
else
{
if (req.EodSettlePriceMode == "结算价")
{
result = new RiskExposureReportService<eod_trade_position_hedgevol_s>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(req);
}
else
{
result = new RiskExposureReportService<eod_trade_position_hedgevol>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(req);
}
}
portfolioData.Add(result.Sum.PortfolioSum.Pnl.OtcFormatMoney());
otcData.Add(result.Sum.OtcSum.Pnl.OtcFormatMoney());
exOptionData.Add(result.Sum.ExOptionSum.Pnl.OtcFormatMoney());
futuresData.Add(result.Sum.FuturesSum.Pnl.OtcFormatMoney());
forwardData.Add(result.Sum.ForwardSum.Pnl.OtcFormatMoney());
swapData.Add(result.Sum.SwapSum.Pnl.OtcFormatMoney());
//result = (temp.Data as Result).obj as RiskExposureReportModel;
//portfolioData.Add(result.Sum.PortfolioSum.Pnl.OtcFormatMoney());
//otcData.Add(result.Sum.OtcSum.Pnl.OtcFormatMoney());
//exOptionData.Add(result.Sum.ExOptionSum.Pnl.OtcFormatMoney());
//futuresData.Add(result.Sum.FuturesSum.Pnl.OtcFormatMoney());
//forwardData.Add(result.Sum.ForwardSum.Pnl.OtcFormatMoney());
//swapData.Add(result.Sum.SwapSum.Pnl.OtcFormatMoney());
});
}
else
{
Dictionary<DateTime, RiskExposureReportModel> dicResult = null;
if (PS.Config.ErpElement.UseOldEodPnLExplainer)
{
if (req.EodSettlePriceMode == "结算价")
{
dicResult = new MarketRiskService<eod_trade_position_s>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_s, eod_pnl_s>(req, days);
}
else
{
dicResult = new MarketRiskService<eod_trade_position>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk, eod_pnl>(req, days);
}
}
else
{
if (req.EodSettlePriceMode == "结算价")
{
dicResult = new MarketRiskService<eod_trade_position_hedgevol_s>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_hedgevol_s, eod_pnl_hedgevol_s>(req, days);
}
else
{
dicResult = new MarketRiskService<eod_trade_position_hedgevol>(CurUser).SearchRiskExposureReportsEchart<eod_trade_risk_hedgevol, eod_pnl_hedgevol>(req, days);
}
}
days.ForEach(a =>
{
trendChartModel.XAxisData.Add(a.ToString("yyyy-MM-dd"));
if (dicResult.ContainsKey(a))
{
result = dicResult[a];
portfolioData.Add(result.Sum.PortfolioSum.Pnl.OtcFormatMoney());
otcData.Add(result.Sum.OtcSum.Pnl.OtcFormatMoney());
exOptionData.Add(result.Sum.ExOptionSum.Pnl.OtcFormatMoney());
futuresData.Add(result.Sum.FuturesSum.Pnl.OtcFormatMoney());
forwardData.Add(result.Sum.ForwardSum.Pnl.OtcFormatMoney());
swapData.Add(result.Sum.SwapSum.Pnl.OtcFormatMoney());
}
else
{
portfolioData.Add("0.00");
otcData.Add("0.00");
exOptionData.Add("0.00");
futuresData.Add("0.00");
forwardData.Add("0.00");
swapData.Add("0.00");
}
});
}
trendChartModel.YAxisData.Add(portfolioData);
trendChartModel.YAxisData.Add(otcData);
trendChartModel.YAxisData.Add(exOptionData);
trendChartModel.YAxisData.Add(futuresData);
trendChartModel.YAxisData.Add(forwardData);
trendChartModel.YAxisData.Add(swapData);
return Json(trendChartModel);
}
/// <summary>
/// 风险控制-观察事件-互换观察日tab
/// </summary>
/// <param name="settleDate"></param>
/// <returns></returns>
[MyAuthorize("风险控制-观察事件")]
public ActionResult ObservationList(string observationDate = null)
{
ViewBag.observationDate = observationDate;
if (observationDate == null)
{
ViewBag.observationDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
/// <summary>
/// 风险控制-观察事件-延期结算tab
/// </summary>
/// <param name="settleDate"></param>
/// <returns></returns>
[MyAuthorize("风险控制-观察事件")]
public ActionResult DelaySettlement(string settleDate = null)
{
ViewBag.settleDate = settleDate;
if (settleDate == null)
{
ViewBag.settleDate = valuedateBLL.ValueDate.ToString("yyyy-MM-dd");
}
return View();
}
public JsonResult DelaySettlementQuery(TdTradeQueryModel req)
{
var sList = new TodayTradeQueryService(CurUser).GetDelaySettlementTradeQuery(req);
return Json(sList);
}
/// <summary>
/// 风险控制-客户盈亏试算
/// </summary>
/// <param name="settleDate"></param>
/// <returns></returns>
[MyAuthorize("风险控制-客户盈亏试算")]
public ActionResult ClientWinLossCalc(int? clientId, string valueDate, bool? ParentFlag = false)
{
ViewBag.ClientId = clientId;
ViewBag.ValueDate = valueDate;
ViewBag.ParentFlag = ParentFlag;
return View();
}
/// <summary>
/// 风险控制-客户盈亏试算
/// </summary>
/// <param name="settleDate"></param>
/// <returns></returns>
[MyAuthorize("风险控制-客户盈亏试算")]
public ActionResult ClientWinLossCalcSwap(int? clientId, string valueDate, bool? ParentFlag = false)
{
ViewBag.ClientId = clientId;
ViewBag.ValueDate = valueDate;
ViewBag.ParentFlag = ParentFlag;
return View();
}
/// <summary>
/// TRS客户端交易端风控检查
/// </summary>
/// <param name="checkReq"></param>
/// <returns></returns>
[HttpPost]
[AllowAnonymous]
public JsonResult ClientRiskCheck([FromBody]ClientRiskCheckReq checkReq)
{
ClientRiskCheckResp clientRiskCheckResp = new ClientRiskCheckResp();
clientRiskCheckResp.requestId = checkReq.requestId;
try
{
foreach (ClientRiskCheckItemParam req in checkReq.clientRiskCheckItemList)
{
ClientRiskCheckData clientRiskCheckData = new ClientRiskCheckData();
clientRiskCheckData.orderNo = req.orderNo;
clientRiskCheckData.clientRiskCheckItemList = new QuotaMonitorService(new OptUserInfo(0, "客户风控校验", OptUserFrom.Service)).QuotaClientCheck(req);
clientRiskCheckData.checkResult = clientRiskCheckData.clientRiskCheckItemList.Count == 0;
clientRiskCheckResp.clientRiskCheckDataList.Add(clientRiskCheckData);
}
}
catch (Exception ex)
{
clientRiskCheckResp.clientRiskCheckDataList.Clear();
foreach (ClientRiskCheckItemParam req in checkReq.clientRiskCheckItemList)
{
ClientRiskCheckData clientRiskCheckData = new ClientRiskCheckData();
clientRiskCheckData.orderNo = req.orderNo;
clientRiskCheckResp.clientRiskCheckDataList.Add(clientRiskCheckData);
}
clientRiskCheckResp.code = 500;
clientRiskCheckResp.msg = ex.Message;
}
return Json(clientRiskCheckResp);
}
}
}