Files
zszq-trs/YLErpDAL/Modules/SuperviseReportModule/XingZhengReport/Service/SuperviseReportOptionService.cs
T
2024-05-09 14:06:26 +08:00

285 lines
13 KiB
C#

using BaseOUDAL;
using YLErp.BLL;
using YLErp.DBModels.Helpers;
using YLErp.Model;
using YLErp.QdpModule;
namespace YLErp.Modules.SuperviseReportModule.XingZhengReport.Service
{
public class SuperviseReportOptionService : SuperviseReportBaseService<SuperviseReportOptionModel>
{
public SuperviseReportOptionService(OptUserInfo userInfo, SuperviseReportReq req) : base(userInfo, req)
{
}
private SearchListResult<SuperviseReportOptionModel> ReportQuery(SuperviseReportReq req)
{
var query = from et in DbContext.eod_trade
join risk in DbContext.eod_trade_risk
on new { et.TradeId, et.ValueDate } equals new { risk.TradeId, risk.ValueDate }
//join cfm in DbContext.trade_contract_r.Where(O => O.IsValid && O.Type == "交易确认书")
//on et.TradeId equals cfm.TradeId into cfmTemp
//from cfm in cfmTemp.DefaultIfEmpty()
where et.ValueDate == req.ValueDate && et.TradeType != "收益互换" && et.TradeType != "现金流交易"
orderby et.TradeId descending
select new
{
et = new xodTradeBase() { TradeJson = et.TradeJson },
risk = risk,
//cfm.ContractCode,
};
var searchTradeInfo = query.ToSearchList(req, false);
List<SuperviseReportOptionModel> modelList = new List<SuperviseReportOptionModel>();
var hedgeGroup = searchTradeInfo.rows.Select(O => O.et.trade.UnderlyingCode).ToHashSet(); ;
//暂时不要下面的逻辑了,默认全部为已对冲
//var tradeList = searchTradeInfo.rows.Select(O => O.et.trade).ToList();
//var priceProvider = new EodPriceProvider(req.ValueDate).GetPriceProvider(SettlementTypeEnum.ClosePrice);
//var service = new QuotaMonitorService(OptUser);
//service.GetHedgeGroup(tradeList, priceProvider, out _, out _, out _, out var hedgeGroup, out _);
//service.GetRiskScale(tradeList,)
foreach (var item in searchTradeInfo.rows)
{
var trade = item.et.trade;
var risk = item.risk;
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
if (um != null)
{
var obj = new SuperviseReportOptionModel();
FormatModel(obj, trade, hedgeGroup, trade.TradeNumber, risk);
modelList.Add(obj);
}
else
{
searchTradeInfo.records--;
}
}
searchTradeInfo.total = Math.Max(1, (int)Math.Ceiling((double)searchTradeInfo.records / searchTradeInfo.rows.Count()));
return new SearchListResult<SuperviseReportOptionModel>(searchTradeInfo, modelList);
}
public override SearchListResult<SuperviseReportOptionModel> SearchReportList()
{
return ReportQuery(RequestInfo);
}
private void FormatModel(SuperviseReportOptionModel model, trade trade, IEnumerable<string> hedgeGroup, string contractCode, EodTradeRisk risk)
{
base.FormatModel(model, trade, hedgeGroup, contractCode);
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(trade.UnderlyingCode);
model.OptStructName = trade.StructureType ?? trade.TradeType;
model.OptPrftTypeCd = getOptPrftTypeCode(trade);
model.CallPutCd = trade.OptionType == "看涨" ? "01" : "02";
model.OtcDeriType = "01";//场外期权
model.RgtDutyCd = trade.BuySell == "买入" ? "01" : "02";
model.TgtCd = um.UnderlyingCode.Contains(".") ? um.UnderlyingCode : $"{um.UnderlyingCode}.{um.MarketCode}";
model.TgtName = um.UnderlyingName;
model.TgtExchCd = base.getTgtExchCd(um.MarketName);
model.TgtAstTypeCd = um.IsCommodity() ? "02" : (um.IsStock() || um.IsStockIndex()) ? "01" : "03";
model.CtrNomnVal = trade.StockEqvNotional;
model.RealNomnVal = TradeHelper.GetStockEqvNotionalReal(trade.StockEqvNotional, trade.ParticipationRate, trade.AnnualizeFactor);
//model.InsmScal = 0;//目前算法计算的业务规模是标的维度的,无法分解为交易维度;
model.PremFix = trade.TradePrice;
model.ExerMod = trade.ExerciseMode == "American" ? "20" : "10";
setObservationInfo(model, trade);
model.MaktVal = risk.Pv;
model.Delta = risk.Delta;
model.Vega = risk.Vega;
model.Gamma = risk.Gamma;
model.RiskFreeRate = trade.NoRiskRate ?? valuedateBLL.RiskFreeRate;
//model.DividRate = 0;
model.Volat = risk.Vol;
}
/// <summary>
/// 设置观察信息
/// </summary>
/// <param name="obj"></param>
/// <param name="trade"></param>
private void setObservationInfo(SuperviseReportOptionModel obj, trade trade)
{
var bpObsvDay = trade.StartDate.GetValueOrDefault().ToString("yyyy-MM-dd");
var epObsvDay = trade.ExerciseDate.GetValueOrDefault().ToString("yyyy-MM-dd");
switch (trade.TradeType)
{
case "亚式期权":
//获取fixings的时候,函数内部处理除权除息逻辑;
break;
case "障碍期权":
obj.BpObsvDay = bpObsvDay;
obj.EpObsvDay = epObsvDay;
obj.ObsvFreq = "每日观察";//1:到期观察;2:每日观察;
if (trade.IsMoneynessOptionData)
{
obj.BarriPricRati2 = trade.trade_barrier_option.BarrierPrice;
obj.BarriPricRati1 = trade.trade_barrier_option.UpperBarrierPrice;
}
else
{
obj.BarriPric2 = trade.trade_barrier_option.BarrierPrice;
obj.BarriPric1 = trade.trade_barrier_option.UpperBarrierPrice;
}
break;
case "凤凰期权":
var obsInfos = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_autocall.KOObservationDates);
obj.BpObsvDay = obsInfos.Item1.Length > 0 ? obsInfos.Item1.Min().DateTime.ToString("yyyy-MM-dd") : bpObsvDay;
obj.EpObsvDay = obsInfos.Item1.Length > 0 ? obsInfos.Item1.Max().DateTime.ToString("yyyy-MM-dd") : epObsvDay;
obj.ObsvFreq = obsInfos.Item1.Length > 0 ? "" : "每日观察";//1:到期观察;2:每日观察;
if (trade.IsMoneynessOptionData)
{
obj.ExecPricRati2 = trade.trade_autocall.SpreadStrike;
obj.ExecPricRati1 = trade.trade_autocall.SpreadStrike1;
}
else
{
obj.ExecPric2 = trade.trade_autocall.SpreadStrike;
obj.ExecPric1 = trade.trade_autocall.SpreadStrike1;
}
break;
case "双鲨期权":
obj.BpObsvDay = bpObsvDay;
obj.EpObsvDay = obj.ExprDt;
obj.ObsvFreq = "每日观察";//1:到期观察;2:每日观察;
if (trade.IsMoneynessOptionData)
{
obj.BarriPricRati2 = trade.trade_double_sharkfin_option.BarrierHigh;
obj.BarriPricRati1 = trade.trade_double_sharkfin_option.BarrierLow;
obj.ExecPricRati2 = trade.trade_double_sharkfin_option.StrikeHigh;
obj.ExecPricRati1 = trade.trade_double_sharkfin_option.StrikeLow;
}
else
{
obj.BarriPric2 = trade.trade_double_sharkfin_option.BarrierHigh;
obj.BarriPric1 = trade.trade_double_sharkfin_option.BarrierLow;
obj.ExecPric2 = trade.trade_double_sharkfin_option.StrikeHigh;
obj.ExecPric1 = trade.trade_double_sharkfin_option.StrikeLow;
}
break;
case "区间累积期权":
//t.trade_rangeaccrual.LowerRange = GetPrice(t.trade_rangeaccrual.LowerRange, dividendInfo, ratio);
//t.trade_rangeaccrual.UpperRange = GetPrice(t.trade_rangeaccrual.UpperRange, dividendInfo, ratio);
break;
case "雪球期权":
obsInfos = QdpHelper.ParseAutocallCustomizedInfo(trade.trade_snowball.KOObservationDates);
obj.BpObsvDay = obsInfos.Item1.Length > 0 ? obsInfos.Item1.Min().DateTime.ToString("yyyy-MM-dd") : bpObsvDay;
obj.EpObsvDay = obsInfos.Item1.Length > 0 ? obsInfos.Item1.Max().DateTime.ToString("yyyy-MM-dd") : epObsvDay;
obj.ObsvFreq = obsInfos.Item1.Length > 0 ? "" : "每日观察";//1:到期观察;2:每日观察;
if (trade.IsMoneynessOptionData)
{
obj.BarriPricRati2 = trade.trade_barrier_option.BarrierPrice;
obj.BarriPricRati1 = trade.trade_barrier_option.UpperBarrierPrice;
}
else
{
obj.BarriPric2 = trade.trade_barrier_option.BarrierPrice;
obj.BarriPric1 = trade.trade_barrier_option.UpperBarrierPrice;
}
break;
case "气囊结构":
obj.BpObsvDay = bpObsvDay;
obj.EpObsvDay = epObsvDay;
obj.ObsvFreq = "每日观察";//1:到期观察;2:每日观察;
if (trade.IsMoneynessOptionData)
{
obj.BarriPricRati2 = trade.trade_airbag.Barrier;
obj.ExecPricRati2 = trade.trade_airbag.HighStrike;
}
else
{
obj.BarriPric2 = trade.trade_airbag.Barrier;
obj.ExecPric2 = trade.trade_airbag.HighStrike;
}
break;
default:
break;
}
}
/// <summary>
/// 获取期权收益类型代码
/// </summary>
/// <param name="trade"></param>
/// <returns></returns>
private string getOptPrftTypeCode(trade trade)
{
string code = "99";
switch (trade.TradeType)
{
case "香草期权":
code = "01";
break;
case "结构化交易":
switch (trade.StructureType)
{
case "跨式组合":
code = "07";
break;
case "宽跨式":
case "宽跨式组合":
code = "08";
break;
case "牛市价差":
case "熊市价差":
code = "03";
break;
case "结构化交易":
//自由组合
default:
break;
}
break;
case "合成价差期权":
code = "03";
break;
case "凤凰期权":
code = "16";
break;
case "雪球期权":
if (trade.trade_snowball.KOPayoffType == KOPayoffTypeEnum.ToSpreadOption)
{
code = "14";
}
else
{
code = "15";
}
break;
case "障碍期权":
if (trade.trade_barrier_option.BarrierType == "双障碍敲出")
{
code = "06";
}
else if (trade.trade_barrier_option.BarrierType.Contains("双"))
{
//其他
}
else if (trade.trade_barrier_option.BarrierType.Contains("敲出"))
{
code = "04";
}
else if (trade.trade_barrier_option.BarrierType.Contains("敲入"))
{
code = "05";
}
break;
case "二元期权":
code = "02";
break;
case "亚式期权":
code = "13";
break;
case "双鲨期权":
code = "06";
break;
case "区间累计期权":
case "区间累积期权":
code = "18";
break;
default:
break;
}
return code;
}
}
}