285 lines
13 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|