436 lines
15 KiB
C#
436 lines
15 KiB
C#
using BaseOUDAL;
|
|
|
|
namespace YLErp.Modules.EodModule
|
|
{
|
|
public class eod_trade_risk_manualReq : BaseSearchReq
|
|
{
|
|
public int? id { get; set; }
|
|
|
|
/// <summary>
|
|
/// 交易Id
|
|
/// </summary>
|
|
public int TradeId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 交易编号
|
|
/// </summary>
|
|
public string TradeNumber { get; set; }
|
|
|
|
/// <summary>
|
|
/// 估值日期
|
|
/// </summary>
|
|
public DateTime? ValueDate { get; set; }
|
|
|
|
/// <summary>
|
|
/// 是否分类型维护风险
|
|
/// </summary>
|
|
public bool IsByType { get; set; }
|
|
|
|
/// <summary>
|
|
/// 持仓市值
|
|
/// </summary>
|
|
public double Pv { get; set; }
|
|
|
|
/// <summary>
|
|
/// 预付金
|
|
/// </summary>
|
|
public double Margin { get; set; }
|
|
|
|
/// <summary>
|
|
/// Delta
|
|
/// </summary>
|
|
public double Delta { get; set; }
|
|
|
|
/// <summary>
|
|
/// Gamma
|
|
/// </summary>
|
|
public double Gamma { get; set; }
|
|
|
|
/// <summary>
|
|
/// Vega
|
|
/// </summary>
|
|
public double Vega { get; set; }
|
|
|
|
/// <summary>
|
|
/// Theta
|
|
/// </summary>
|
|
public double Theta { get; set; }
|
|
|
|
/// <summary>
|
|
/// Rho
|
|
/// </summary>
|
|
public double Rho { get; set; }
|
|
|
|
/// <summary>
|
|
/// 波动率类型
|
|
/// </summary>
|
|
public string VolType { get; set; }
|
|
|
|
/// <summary>
|
|
/// 计价类型
|
|
/// </summary>
|
|
public SettlementTypeEnum? SettlementType { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义交易风险维护服务
|
|
/// </summary>
|
|
public class EodTradeRiskManualService : YLBaseService
|
|
{
|
|
public EodTradeRiskManualService(OptUserInfo userInfo) : base(userInfo)
|
|
{
|
|
}
|
|
|
|
public SearchListResult<eod_trade_risk_manual> SearchEodTradeRiskManualList(eod_trade_risk_manualReq req)
|
|
{
|
|
if (string.IsNullOrEmpty(req.sidx))
|
|
{
|
|
req.sidx = "ValueDate";
|
|
req.sord = "desc";
|
|
}
|
|
else
|
|
{
|
|
req.sidx = req.sidx.Replace("SettlementTypeDesc", "SettlementType");
|
|
}
|
|
|
|
var query = from trm in DbContext.eod_trade_risk_manual
|
|
join td in DbContext.trade
|
|
on trm.TradeId equals td.id
|
|
where td.ValidState != "InValid"
|
|
select trm;
|
|
|
|
if (!string.IsNullOrEmpty(req.TradeNumber))
|
|
{
|
|
query = from trm in DbContext.eod_trade_risk_manual
|
|
join td in DbContext.trade
|
|
on trm.TradeId equals td.id
|
|
where td.ValidState != "InValid" && td.TradeNumber == req.TradeNumber
|
|
select trm;
|
|
}
|
|
|
|
if (req.TradeId > 0)
|
|
{
|
|
query = query.Where(x => x.TradeId == req.TradeId);
|
|
}
|
|
if (req.ValueDate != null)
|
|
{
|
|
query = query.Where(x => x.ValueDate == req.ValueDate);
|
|
}
|
|
if (req.IsByType)
|
|
{
|
|
if (!string.IsNullOrEmpty(req.VolType))
|
|
{
|
|
query = query.Where(x => x.VolType == req.VolType);
|
|
}
|
|
else
|
|
{
|
|
query = query.Where(x => x.VolType != null);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
query = query.Where(x => x.VolType == null);
|
|
}
|
|
if (req.SettlementType != null)
|
|
{
|
|
query = query.Where(x => x.SettlementType == req.SettlementType);
|
|
}
|
|
|
|
var result = query.ToSearchList(req);
|
|
foreach (var item in result.rows)
|
|
{
|
|
item.TradeNumber = DbContext.trade.Where(n => n.id == item.TradeId).Select(n => n.TradeNumber).FirstOrDefault();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新自定义交易风险
|
|
/// </summary>
|
|
public eod_trade_risk_manual SaveEodTradeRiskManual(eod_trade_risk_manualDto req)
|
|
{
|
|
return InnerSaveEodTradeRiskManual(req: req, onlyUpdatePositionMargin: false, fromApi: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新自定义交易风险
|
|
/// </summary>
|
|
public eod_trade_risk_manual SaveEodTradeRiskManualByType(eod_trade_risk_manualDto req)
|
|
{
|
|
return InnerSaveEodTradeRiskManualByType(req: req, fromApi: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新交易持仓预付金
|
|
/// </summary>
|
|
public eod_trade_risk_manual SaveEodTradePositionMargin(eod_trade_risk_manualDto req)
|
|
{
|
|
return InnerSaveEodTradeRiskManual(req: req, onlyUpdatePositionMargin: true, fromApi: false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// API更新自定义交易风险
|
|
/// </summary>
|
|
public eod_trade_risk_manual SaveEodTradeRiskManualAPI(eod_trade_risk_manualDto req)
|
|
{
|
|
return InnerSaveEodTradeRiskManual(req: req, onlyUpdatePositionMargin: false, fromApi: true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// API更新持仓预付金
|
|
/// </summary>
|
|
public eod_trade_risk_manual SaveEodTradePositionMarginAPI(eod_trade_risk_manualDto req)
|
|
{
|
|
return InnerSaveEodTradeRiskManual(req: req, onlyUpdatePositionMargin: true, fromApi: true);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新自定义交易风险
|
|
/// </summary>
|
|
private eod_trade_risk_manual InnerSaveEodTradeRiskManual(eod_trade_risk_manualDto req, bool onlyUpdatePositionMargin, bool fromApi)
|
|
{
|
|
if (req is null)
|
|
{
|
|
throw new ServiceException("未获取到传入参数");
|
|
}
|
|
|
|
if (req.ValueDate.Year < 2000)
|
|
{
|
|
throw new ServiceException("估值日期 请正确赋值:" + req.ValueDate.OtcFormatDate());
|
|
}
|
|
|
|
if (fromApi)
|
|
{
|
|
if (string.IsNullOrEmpty(req.TradeNumber))
|
|
{
|
|
throw new ServiceException("交易编号 必须填写");
|
|
}
|
|
|
|
var td = DbContext.trade.Where(n => n.TradeNumber == req.TradeNumber)
|
|
.Select(n => new { n.id, n.TradeType, n.TradeDate, n.ExerciseDate }).FirstOrDefault();
|
|
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("未找到交易数据,交易编号:" + req.TradeNumber);
|
|
}
|
|
|
|
if (req.ValueDate < td.TradeDate)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须大于等于交易开始日'{td.TradeDate:yyyy-MM-dd}'");
|
|
}
|
|
|
|
if (td.ExerciseDate.HasValue && req.ValueDate > td.ExerciseDate.Value)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须小于等于交易到期日'{td.ExerciseDate.Value:yyyy-MM-dd}'");
|
|
}
|
|
|
|
req.TradeId = td.id;
|
|
}
|
|
else
|
|
{
|
|
var td = DbContext.trade.Where(n => n.id == req.TradeId)
|
|
.Select(n => new { n.id, n.TradeDate, n.ExerciseDate }).FirstOrDefault();
|
|
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("未找到交易数据,交易id:" + req.TradeId);
|
|
}
|
|
|
|
if (req.ValueDate < td.TradeDate)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须大于等于交易开始日'{td.TradeDate:yyyy-MM-dd}'");
|
|
}
|
|
|
|
if (td.ExerciseDate.HasValue && req.ValueDate > td.ExerciseDate.Value)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须小于等于交易到期日'{td.ExerciseDate.Value:yyyy-MM-dd}'");
|
|
}
|
|
}
|
|
|
|
var dbModel = DbContext.eod_trade_risk_manual.FirstOrDefault(x => x.ValueDate == req.ValueDate && x.TradeId == req.TradeId && string.IsNullOrEmpty(x.VolType));
|
|
|
|
if (dbModel == null)
|
|
{
|
|
dbModel = new eod_trade_risk_manual
|
|
{
|
|
TradeId = req.TradeId,
|
|
ValueDate = req.ValueDate
|
|
};
|
|
DbContext.eod_trade_risk_manual.Add(dbModel);
|
|
}
|
|
else if (!fromApi && !onlyUpdatePositionMargin && req.id < 1)
|
|
{
|
|
throw new ServiceException("估值日期不能重复");
|
|
}
|
|
|
|
if (onlyUpdatePositionMargin)
|
|
{
|
|
dbModel.Margin = req.Margin;
|
|
|
|
var eodPosition = DbContext.eod_trade_position.Where(x => x.ValueDate == req.ValueDate && x.TradeId == req.TradeId).FirstOrDefault();
|
|
|
|
if (eodPosition != null)
|
|
{
|
|
eodPosition.Margin = req.Margin ?? 0;
|
|
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
AuditFlag = TradeAuditFlag.operation,
|
|
Changes = "更新持仓预付金为:" + eodPosition.Margin.OtcFormatFlex(2),
|
|
DataType = "text",
|
|
OptDate = DateTime.Now,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptType = "更新持仓预付金",
|
|
TradeId = req.TradeId
|
|
});
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dbModel.Pv = req.Pv;
|
|
dbModel.Delta = req.Delta;
|
|
dbModel.Gamma = req.Gamma;
|
|
dbModel.Vega = req.Vega;
|
|
dbModel.Theta = req.Theta;
|
|
dbModel.Rho = req.Rho;
|
|
dbModel.Margin = req.Margin;
|
|
dbModel.Spv1 = req.Spv1;
|
|
dbModel.Spv2 = req.Spv2;
|
|
dbModel.Spv3 = req.Spv3;
|
|
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
AuditFlag = TradeAuditFlag.operation,
|
|
Changes = JsonHelper.Serialize(dbModel),
|
|
DataType = "json",
|
|
OptDate = DateTime.Now,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptType = "风险维护",
|
|
TradeId = req.TradeId
|
|
});
|
|
}
|
|
|
|
//设置操作员
|
|
SetDBModelOpt(dbModel);
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
return dbModel;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新自定义交易风险
|
|
/// </summary>
|
|
private eod_trade_risk_manual InnerSaveEodTradeRiskManualByType(eod_trade_risk_manualDto req, bool fromApi)
|
|
{
|
|
if (req is null)
|
|
{
|
|
throw new ServiceException("未获取到传入参数");
|
|
}
|
|
|
|
if (req.ValueDate.Year < 2000)
|
|
{
|
|
throw new ServiceException("估值日期 请正确赋值:" + req.ValueDate.OtcFormatDate());
|
|
}
|
|
|
|
if (fromApi)
|
|
{
|
|
if (string.IsNullOrEmpty(req.TradeNumber))
|
|
{
|
|
throw new ServiceException("交易编号 必须填写");
|
|
}
|
|
|
|
var td = DbContext.trade.Where(n => n.TradeNumber == req.TradeNumber)
|
|
.Select(n => new { n.id, n.TradeType, n.TradeDate, n.ExerciseDate }).FirstOrDefault();
|
|
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("未找到交易数据,交易编号:" + req.TradeNumber);
|
|
}
|
|
|
|
if (req.ValueDate < td.TradeDate)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须大于等于交易开始日'{td.TradeDate:yyyy-MM-dd}'");
|
|
}
|
|
|
|
if (td.ExerciseDate.HasValue && req.ValueDate > td.ExerciseDate.Value)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须小于等于交易到期日'{td.ExerciseDate.Value:yyyy-MM-dd}'");
|
|
}
|
|
|
|
req.TradeId = td.id;
|
|
}
|
|
else
|
|
{
|
|
var td = DbContext.trade.Where(n => n.id == req.TradeId)
|
|
.Select(n => new { n.id, n.TradeDate, n.ExerciseDate }).FirstOrDefault();
|
|
|
|
if (td == null)
|
|
{
|
|
throw new ServiceException("未找到交易数据,交易id:" + req.TradeId);
|
|
}
|
|
|
|
if (req.ValueDate < td.TradeDate)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须大于等于交易开始日'{td.TradeDate:yyyy-MM-dd}'");
|
|
}
|
|
|
|
if (td.ExerciseDate.HasValue && req.ValueDate > td.ExerciseDate.Value)
|
|
{
|
|
throw new ServiceException($"估值日期'{req.ValueDate:yyyy-MM-dd}'必须小于等于交易到期日'{td.ExerciseDate.Value:yyyy-MM-dd}'");
|
|
}
|
|
}
|
|
|
|
|
|
var dbModel = DbContext.eod_trade_risk_manual.FirstOrDefault(x => x.ValueDate == req.ValueDate && x.TradeId == req.TradeId && x.VolType == req.VolType && x.SettlementType == req.SettlementType);
|
|
if (dbModel == null)
|
|
{
|
|
dbModel = new eod_trade_risk_manual
|
|
{
|
|
TradeId = req.TradeId,
|
|
ValueDate = req.ValueDate,
|
|
VolType = req.VolType,
|
|
SettlementType = req.SettlementType
|
|
};
|
|
DbContext.eod_trade_risk_manual.Add(dbModel);
|
|
}
|
|
else
|
|
{
|
|
if(req.id < 1)
|
|
{
|
|
throw new ServiceException("相同类型的交易风险维护数据在同一天不能重复");
|
|
}
|
|
}
|
|
|
|
dbModel.Pv = req.Pv;
|
|
dbModel.Delta = req.Delta;
|
|
dbModel.Gamma = req.Gamma;
|
|
dbModel.Vega = req.Vega;
|
|
dbModel.Theta = req.Theta;
|
|
dbModel.Rho = req.Rho;
|
|
|
|
DbContext.TradeAuditLog.Add(new TradeAuditLog
|
|
{
|
|
AuditFlag = TradeAuditFlag.operation,
|
|
Changes = JsonHelper.Serialize(dbModel),
|
|
DataType = "json",
|
|
OptDate = DateTime.Now,
|
|
OptId = UserId,
|
|
OptName = UserName,
|
|
OptType = "分类风险维护",
|
|
TradeId = req.TradeId
|
|
});
|
|
|
|
//设置操作员
|
|
SetDBModelOpt(dbModel);
|
|
|
|
DbContext.SaveChanges();
|
|
|
|
return dbModel;
|
|
}
|
|
}
|
|
}
|