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

1388 lines
74 KiB
C#

using BaseOUDAL;
using Qdp.Pricing.Base.Utilities;
using Qdp.Pricing.Library.Common.Interfaces;
using Qdp.Pricing.Library.Options.Products.Asian;
using YLErp.BLL;
using YLErp.Commons;
using YLErp.DBModels.Consts;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Modules.CalculationModule;
using YLErp.Modules.SuperviseReportModule.CFMMC2022.Model;
using static iTextSharp.text.pdf.AcroFields;
using static YLErp.ConsGlobal;
namespace YLErp.Modules.SuperviseReportModule.CFMMC2022.Service
{
public class SuperviseReportPositionService : SuperviseReportBaseService
{
private string _volType { get; set; }
public SuperviseReportPositionService(SuperviseReportReq req, OptUserInfo userInfo) : base(req, userInfo)
{
var arr = req.DataSource?.Split(',') ?? new string[2];
_volType = arr[0];
req.DataSource = arr[1];
}
/// <summary>
///
/// </summary>
/// <param name="model"></param>
/// <param name="varietyTypes">标的资产类型</param>
/// <param name="assetTypes">资产类型</param>
/// <param name="varietySuffixs">标的资产品种后缀和标的资产对应合约后缀</param>
/// <param name="syntheticPrice">组合标的价格</param>
/// <exception cref="ServiceException">EodTrade不存在时抛出</exception>
protected void FormatModel(NewSuperviseReportPositionModel model, List<DictionaryItem> assetTypes, List<DictionaryItem> varietySuffixs, List<DictionaryItem> varietyCodeList, Dictionary<int, EodTradeRisk> eRiskInfos, out SyntheticPriceModel syntheticPrice)
{
var obj = (NewSuperviseReportPositionModel)model;
obj.TradeDate = obj.trade.TradeDate;
obj.StartDate = obj.trade.TradeDate;
obj.EndDate = obj.trade.ExerciseDate;
base.FormatModel(obj, assetTypes, varietySuffixs, varietyCodeList, out syntheticPrice);
//持仓报告 设置特定字段
formatOptionlFields(obj);
double eqv = 0, endEqv = 0;
var annualizeFactor = obj.trade.IsAnnualized ? obj.trade.AnnualizeFactor : 1;
var trade = obj.trade;
var ignoreTradeTypes = new List<string>()
{
"远期",
"收益互换",
"掉期",
};
eRiskInfos.TryGetValue(obj.TradeId, out var eRisk);
if (obj.IsGroup == 1)
{
var childIds = DbContext.trade.Where(x => x.ParentTradeId == obj.TradeId).Select(x => x.id);
var riskChilds = DbContext.eod_trade_risk.Where(x => childIds.Contains(x.TradeId) && x.ValueDate == _req.ValueDate).ToList();
obj.ContractPrice = riskChilds.Sum(x => x.Pv);
obj.Delta = riskChilds.Sum(x => x.Delta).OtcFormat(OtcFormatFlag.greek);
obj.Vega = riskChilds.Sum(x => x.Vega).OtcFormat(OtcFormatFlag.greek);
obj.Theta = riskChilds.Sum(x => x.Theta).OtcFormat(OtcFormatFlag.greek);
obj.Rho = (riskChilds.Sum(x => x.Rho) * 100).OtcFormat(OtcFormatFlag.greek);
obj.Gamma = riskChilds.Sum(x => x.Gamma).OtcFormat(OtcFormatFlag.greek);
obj._delta = riskChilds.Sum(x => x.Delta);
obj._gamma = riskChilds.Sum(x => x.Gamma);
//估值波动率
obj.ValuationVolatility = eRisk == null ? null : eRisk.Vol > 0 ? eRisk.Vol.OtcFormat(OtcFormatFlag.greek) : null;
if (!string.IsNullOrEmpty(model.trade.ExtendInfo))
{
var tempVolat = 0D;
var isVolat = false;
foreach (var rItem in riskChilds)
{
if (rItem.Vol == 0)
{
continue;
}
if (tempVolat == 0)
{
tempVolat = rItem.Vol;
}
if (tempVolat == rItem.Vol)
{
isVolat = true;
}
else
{
isVolat = false;
}
tempVolat = rItem.Vol;
}
if (isVolat)
{
model.ValuationVolatility = tempVolat == 0 ? null : tempVolat.OtcFormat(OtcFormatFlag.greek);
}
}
}
else if (!ignoreTradeTypes.Contains(obj.TradeType))
{
obj.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek);
obj.Vega = (eRisk?.Vega ?? 0).OtcFormat(OtcFormatFlag.greek);
obj.Theta = (eRisk?.Theta ?? 0).OtcFormat(OtcFormatFlag.greek);
obj.Rho = ((eRisk?.Rho ?? 0) * 100).OtcFormat(OtcFormatFlag.greek);
var otherRisks = JsonHelper.Parse<OtherRisks>(eRisk?.OtherRisks);
if (otherRisks == null || string.IsNullOrWhiteSpace(otherRisks.CrossGamma))
{
obj.Gamma = (eRisk?.Gamma ?? 0).OtcFormat(OtcFormatFlag.greek);
}
else
{
obj.Gamma = otherRisks.CrossGamma.Replace(",", ";");
}
//估值波动率
obj.ValuationVolatility = eRisk == null ? null : eRisk.Vol > 0 ? eRisk.Vol.OtcFormat(OtcFormatFlag.greek) : null;
obj._delta = ((double)(eRisk?.Delta ?? 0));
obj._gamma = (eRisk?.Gamma ?? 0);
}
else
{
obj.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek);
obj._delta = (eRisk?.Delta ?? 0);
if (PS.Config.Company == Configuration.CompanyEnum.浙期 && !string.IsNullOrWhiteSpace(trade.BasisUnderlyingCode))
{
obj.Delta += ";" + obj.Delta;
obj.DeltaCash += ";" + obj.DeltaCash;
obj.GammaCash = "0";
}
}
//组合标的
if (syntheticPrice != null && syntheticPrice.SuList.Count() > 0)
{
var underlyingPrices = syntheticPrice.SuList.ToArray();
var arrSEN = new string[underlyingPrices.Length];
var arrSEN2 = new string[underlyingPrices.Length];
var arrAmount = new string[underlyingPrices.Length];
var arrEndAmount = new string[underlyingPrices.Length];
var arrUnderlyingInitialPrice = new string[underlyingPrices.Length];
var arrUnderlyingInitialPriceCurrency = new string[underlyingPrices.Length];
var arrContractValuationPrice = new string[underlyingPrices.Length];
var arrGammaCash = new string[underlyingPrices.Length];
var arrDeltaCash = new string[underlyingPrices.Length];
var notional = obj.trade.OriginalNotional;
if (PS.Config.Is广期资本 && "自定义交易".Equals(obj.trade.TradeType) && obj.trade.Propertys != null && obj.trade.Propertys.Any(d => "总数量".Equals(d.name)))
{
double totalCount = 0;
if (double.TryParse(obj.trade.Propertys.First(d => "总数量".Equals(d.name)).value, out totalCount))
{
notional = totalCount * obj.trade.CountRatio ?? 1;
}
}
for (var i = 0; i < underlyingPrices.Length; i++)
{
var originalStockEqvNotional = (underlyingPrices[i].Price * notional / annualizeFactor / obj.trade.ParticipationRate * underlyingPrices[i].Coefficient) ?? 0;
eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1);
endEqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, (1 - (obj.trade.Notional / obj.trade.OriginalNotional ?? 1)));
arrAmount[i] = formatTradeAmount(eqv / underlyingPrices[i].Price);
arrEndAmount[i] = formatTradeAmount(endEqv / underlyingPrices[i].Price);
arrSEN[i] = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate : eqv).ToString();
arrSEN2[i] = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate : endEqv).ToString();
var um1 = UnderlyingDataProvider.GetUnderlying(underlyingPrices[i].UnderlyingCode);
var variety = DataCacheProvider.GetVarietyDataSource().GetData(um1.UnderlyingTypeId);
if (variety.QuoteCurrency != null && (variety.QuoteCurrency.ToLower() == "usc" || variety.QuoteCurrency.ToLower() == "usd(cent)"))
{
arrSEN[i] = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate / 100 : eqv).ToString();
arrSEN2[i] = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate / 100 : endEqv).ToString();
}
arrUnderlyingInitialPrice[i] = underlyingPrices[i].Price.ToString();
arrUnderlyingInitialPriceCurrency[i] = string.IsNullOrEmpty(variety.QuoteCurrency) ? "CNY" : variety.QuoteCurrency;
arrContractValuationPrice[i] = _priceProvider.GetPrice(underlyingPrices[i].UnderlyingCode).ToString();
if (obj._delta != null)
{
arrDeltaCash[i] = OtcFormatHelper.FormatValue((obj._delta * underlyingPrices[i].Price), 4).ToString();
}
if (obj._gamma != null)
{
arrGammaCash[i] = OtcFormatHelper.FormatValue((obj._delta * underlyingPrices[i].Price), 4).ToString();
}
}
//初始名义金额
obj.InitialNominalAmount = string.Join(base._separator, arrSEN);
//已平仓总名义金额
obj.TotalClosedPositionsAmount = string.Join(base._separator, arrSEN2);
//初始名义数量
obj.InitialNominalNumber = string.Join(base._separator, arrAmount);
//已平仓总名义数量
obj.TotalClosedPositionsNumber = string.Join(base._separator, arrEndAmount);
//组合标的价格
obj.UnderlyingInitialPrice = string.Join(base._separator, arrUnderlyingInitialPrice);
obj.UnderlyingInitialPriceCurrency = string.Join(base._separator, arrUnderlyingInitialPriceCurrency);
obj.ContractValuationPrice = string.Join(base._separator, arrContractValuationPrice);
obj.DeltaCash = JoinArr(arrDeltaCash);
obj.GammaCash = JoinArr(arrGammaCash);
}
else
{
var notional = obj.trade.OriginalNotional;
if (PS.Config.Is广期资本 && "自定义交易".Equals(obj.trade.TradeType) && obj.trade.Propertys != null && obj.trade.Propertys.Any(d => "总数量".Equals(d.name)))
{
double totalCount = 0;
if (double.TryParse(obj.trade.Propertys.First(d => "总数量".Equals(d.name)).value, out totalCount))
{
notional = totalCount * obj.trade.CountRatio ?? 1;
obj.trade.OriginalStockEqvNotional = (obj.trade.SpotPrice * notional / obj.trade.AnnualizeFactor / obj.trade.ParticipationRate);
}
}
var originalStockEqvNotional = (obj.trade.OriginalStockEqvNotional == 0 ? (obj.trade.SpotPrice * notional / obj.trade.AnnualizeFactor / obj.trade.ParticipationRate) : obj.trade.OriginalStockEqvNotional) ?? 0;
eqv = formatEndStockEqvNotionalReal(originalStockEqvNotional, 1);
endEqv = formatEndStockEqvNotionalReal(eqv, (1 - (obj.trade.Notional / (obj.trade.OriginalNotional ?? 1))));
//初始名义金额
obj.InitialNominalAmount = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate : eqv).ToString();
//已平仓总名义金额
obj.TotalClosedPositionsAmount = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate : endEqv).ToString();
if (obj.QuoteCurrency != null && (obj.QuoteCurrency.ToLower() == "usc" || obj.QuoteCurrency.ToLower() == "usd(cent)"))
{
obj.InitialNominalAmount = (obj.ForeignCurrencyRate != null ? eqv * obj.ForeignCurrencyRate / 100 : eqv).ToString();
obj.TotalClosedPositionsAmount = (obj.ForeignCurrencyRate != null ? endEqv * obj.ForeignCurrencyRate / 100 : endEqv).ToString();
}
//初始名义数量
obj.InitialNominalNumber = formatTradeAmount(eqv / obj.trade.SpotPrice).ToString();
//已平仓总名义数量
obj.TotalClosedPositionsNumber = formatTradeAmount(endEqv / obj.trade.SpotPrice).ToString();
if (obj._delta != null)
{
obj.DeltaCash = OtcFormatHelper.FormatValue((model._delta * (model._price ?? model.trade.SpotPrice)), 4).ToString();
}
if (obj._gamma != null)
{
obj.GammaCash = OtcFormatHelper.FormatValue((model._gamma * (model._price ?? model.trade.SpotPrice)), 4).ToString();
}
}
obj.ExerciseDate = obj.trade.ExerciseDate;
}
#region 新持仓报送报表
private SearchListResult<NewSuperviseReportPositionModel> NewReportQuery(SuperviseReportReq req)
{
var commodityList = new List<string> { InstrumentType.CommodityFutures, InstrumentType.CommoditySpot };
var umQuery = DbContext.underlying_manager.AsQueryable();
switch (req.DataSource)
{
case "权益":
umQuery = umQuery.Where(O => !commodityList.Contains(O.UnderlyingInstrumentType));
break;
case "商品":
umQuery = umQuery.Where(O => commodityList.Contains(O.UnderlyingInstrumentType));
break;
case "全量":
default:
break;
}
var insidedClientIds = DataCacheProvider.GetClientDataSource().AsQueryable().Where(O => O.IsInsided == 1).Select(O => O.id).ToList();
var tId = DbContext.eod_trade_position.Where(O => !insidedClientIds.Contains(O.ClientId) && O.ValueDate == req.ValueDate && (ConsTrade.TradeTypesForOtcOptions.Contains(O.TradeType) || O.TradeType == "远期" || O.TradeType == "收益互换") && O.TradeType != "场内期权" && O.TradeId != 0).Select(O => O.TradeId);
var query = from eodTrade in DbContext.eod_trade
join trade in DbContext.trade on eodTrade.TradeId equals trade.id
join um in umQuery on trade.UnderlyingCode equals um.UnderlyingCode
join parentTrade in (from tr in DbContext.trade where tr.ValidState != "InValid" && tr.TradeType == "结构化交易" select tr) on trade.ParentTradeId equals parentTrade.id into parentTrades
from tempParentTrade in parentTrades.DefaultIfEmpty()
join cPrice in DbContext.eod_commodity_future_price.Where(O => O.ValueDate == req.ValueDate) on trade.UnderlyingCode equals cPrice.UnderlyingCode into tempCPrice
from cPrice in tempCPrice.DefaultIfEmpty()
join sPrice in DbContext.eod_stock_price.Where(O => O.ValueDate == req.ValueDate) on trade.UnderlyingCode equals sPrice.UnderlyingCode into tempSPrice
from sPrice in tempSPrice.DefaultIfEmpty()
where eodTrade.ValueDate == req.ValueDate && (tId.Contains(eodTrade.TradeId) || trade.IsGroup == 1) && trade.IsGroup != 2 && trade.TradeType != "现金流交易" && eodTrade.ClientId != 0 && ConsTrade.LiveTradeStatusList.Contains(eodTrade.TradeStatus)
select new NewSuperviseReportPositionModel
{
TradeId = eodTrade.TradeId,
ClientId = eodTrade.ClientId,
UnderlyingCode = eodTrade.UnderlyingCode,
ParentTradeId = eodTrade.ParentTradeId,
TradeStatus = eodTrade.TradeStatus,
OriginalTradeNumber = eodTrade.TradeNumber,
TradeJson = eodTrade.TradeJson,
ValuationMethod = "O",
UnwindPercentRate = 0,
ForeignCurrencyRate = null,
ParticipateRate = 1,
IsGroup = trade.IsGroup,
ProductType = trade.TradeType,
StructureType = trade.StructureType,
PositionCode = tempParentTrade != null ? tempParentTrade.TradeNumber : trade.TradeNumber,
OptionProductStructure = eodTrade.TradeType,
TradeType = tempParentTrade != null ? tempParentTrade.TradeType : trade.TradeType,
RiskFreeRate = trade.NoRiskRate ?? (valuedateBLL.RiskFreeRate * 0.01),
Dividend = trade.DividendRate,
SettlementMethod = "C",
LastUnWindDate = trade.SettlementDate == null ? trade.ExerciseDate : trade.SettlementDate,
ExtendInfo = trade.ExtendInfo,
ValueDate = req.ValueDate,
StartDate = trade.StartDate,
_price = cPrice != null ? cPrice.ClosePrice : sPrice.ClosePrice
};
var clientcontext = new ClientDBContext();
var clientids = query.Select(x => x.ClientId).Distinct().ToArray();
var clients = clientcontext.client.Where(x => clientids.Contains(x.id) && x.IsInsided != 1).Select(x => x.id).ToArray();
query = query.Where(x => clients.Contains(x.ClientId)).OrderBy(O => O.OriginalTradeNumber);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "StartDate";
req.sord = "desc";
}
req.sidx = req.sidx + ",TradeId";
var retListResult = query.ToSearchList(req, true);
return retListResult;
}
public SearchListResult<NewSuperviseReportPositionModel> NewSearchReportList()
{
SearchListResult<NewSuperviseReportPositionModel> retListResult = null;
using (var basedb = new ErpBaseContext())
{
IQueryable<EodTradeRisk> etr = null;
IQueryable<EodTradePosition> etp = null;
switch (_volType)
{
case "开仓":
etr = DbContext.eod_trade_risk_openvol.Where(O => O.ValueDate == _req.ValueDate);
etp = DbContext.eod_trade_position_openvol.Where(O => O.ValueDate == _req.ValueDate);
break;
case "持仓":
default:
etr = DbContext.eod_trade_risk.Where(O => O.ValueDate == _req.ValueDate);
etp = DbContext.eod_trade_position.Where(O => O.ValueDate == _req.ValueDate);
break;
}
retListResult = NewReportQuery(_req);
var clientIdArr = retListResult.rows.Select(O => O.ClientId).ToHashSet();
var assetTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "资产类型" select i).ToList();
var varietySuffixList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "标的资产后缀" select i).ToList();
var varietyCodeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == "标的资产分类" select i).ToList();
//var clientMetaQuery = DbContextFactory.GetClientDbContext(UserInfo).ClientMeta.Where(O => clientIdArr.Contains(O.ClientId));
//var clientEquityInfo = clientMetaQuery.Where(O => O.MetaKey == "RightProtocolSignVersion").ToDictionary(K => K.ClientId, V => V.MetaValue);
//var clientReportInfo = clientMetaQuery.Where(O => O.MetaKey == "ReportName").ToDictionary(K => K.ClientId, V => V.MetaValue);
var tIdArr = retListResult.rows.Select(O => O.TradeId);
var tpIdArr = retListResult.rows.Select(O => O.ParentTradeId);
var tradeContractRInfo = DbContext.trade_contract_r.Where(O => tIdArr.Contains(O.TradeId) || tpIdArr.Contains(O.TradeId)).ToList();
var tcRinfos = tradeContractRInfo.Where(O => O.Type == ContractTypeEnum.Trade).Select(O => new { TradeId = O.TradeId, O.ContractCode }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().ContractCode);
var tradeNumberInfo = tradeContractRInfo.Select(O => new { TradeCashId = (O.TradeCashId ?? 0), O.ContractCode }).GroupBy(O => O.TradeCashId).ToDictionary(K => K.Key, V => V.First().ContractCode);
var tradeMetaList = DbContext.TradeMeta.Where(O => tIdArr.Contains(O.TradeId)).ToList();
var iccInfo = tradeMetaList.Where(O => O.MetaKey == "中央对手方清算").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
var ccpInfo = tradeMetaList.Where(O => O.MetaKey == "中央清算平台").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
var tpInfo = tradeMetaList.Where(O => O.MetaKey == "交易平台").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
//敲入观察频率
var kiObservatonRate = tradeMetaList.Where(O => O.MetaKey == "敲入观察周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
//敲出观察频率
var koObservationRate = tradeMetaList.Where(O => O.MetaKey == "敲出观察周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
//远期 周期
var getObservatonRate = tradeMetaList.Where(O => O.MetaKey == "收取周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
var payObservatonRate = tradeMetaList.Where(O => O.MetaKey == "支付周期").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
//外币汇率
var exChangeRate = tradeMetaList.Where(O => O.MetaKey == "ExchangeRate").Select(O => new { TradeId = O.TradeId, O.MetaValue }).GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First().MetaValue);
var ptIdArr = retListResult.rows.Where(O => O.ParentTradeId != null).Select(O => O.ParentTradeId).ToHashSet();
var ptInfos = DbContext.trade.Where(O => ptIdArr.Contains(O.id)).Select(O => new { O.id, O.TradeType, O.StructureType, O.TradeNumber }).ToDictionary(K => K.id, V => V);
var tcRInfos = new Dictionary<int, string>();
var tmInfos = new Dictionary<int, string>();
switch (PS.Config.Company)
{
case Configuration.CompanyEnum.长江:
tcRInfos = DbContext.trade_contract_r.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.Type == ContractTypeEnum.Trade && O.IsValid).Select(O => new { O.TradeId, O.ContractCode }).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.FirstOrDefault().ContractCode);
tmInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey == ConsTradeMetaKey.ContractCode).ToDictionary(K => K.TradeId, V => V.MetaValue);
break;
case Configuration.CompanyEnum.浙期:
case Configuration.CompanyEnum.物产中大:
tmInfos = DbContext.TradeMeta.Where(O => (tIdArr.Contains(O.TradeId) || ptIdArr.Contains(O.TradeId)) && O.MetaKey == ConsTradeMetaKey.ContractCode).ToDictionary(K => K.TradeId, V => V.MetaValue);
break;
}
var clientMetaQuery = DbContextFactory.GetClientDbContext(UserInfo).ClientMeta.Where(O => clientIdArr.Contains(O.ClientId));
var clientReportInfo = clientMetaQuery.Where(O => O.MetaKey == "ReportName").ToDictionary(K => K.ClientId, V => V.MetaValue);
try
{
BLL.tradeBLL.SetFieldsByTradeType(retListResult.rows.Select(o => o.trade));
Dictionary<int, EodTradePosition> ePnlInfos = null;
Dictionary<int, EodTradeRisk> eRiskInfos = null;
var func = new Func<EodTradeRisk, EodTradeRisk>(O => new EodTradeRisk
{
TradeId = O.TradeId,
Delta = O.Delta,
DeltaCash = O.DeltaCash,
GammaCash = O.GammaCash,
Theta = O.Theta,
Gamma = O.Gamma,
Rho = O.Rho,
Vega = O.Vega,
Vol = O.Vol,
OtherRisks = O.OtherRisks
});
ePnlInfos = etp.Where(O => tIdArr.Contains(O.TradeId)).Select(O => new EodTradePosition { TradeId = O.TradeId, Pv = O.Pv, Margin = O.Margin }).ToDictionary(K => K.TradeId, V => V);
eRiskInfos = etr.Where(O => tIdArr.Contains(O.TradeId)).Select(func).AsEnumerable().GroupBy(O => O.TradeId).ToDictionary(K => K.Key, V => V.First());
foreach (var item in retListResult.rows)
{
if (item.TradeType == "远期" || item.TradeType == "收益互换")
{
item.ValuationMethod = "M";
}
//交易确认书
tcRinfos.TryGetValue(item.ParentTradeId > 0 ? item.ParentTradeId.Value : item.TradeId, out var tcValue);
if (string.IsNullOrEmpty(tcValue))
{
tcRinfos.TryGetValue(item.TradeId, out var tcValue2);
tcValue = tcValue2;
}
item.ContractCode = tcValue ?? null;
ptInfos.TryGetValue(item.ParentTradeId ?? 0, out var parentTrade);
switch (PS.Config.Company)
{
case Configuration.CompanyEnum.长江:
tcRInfos.TryGetValue(item.ParentTradeId ?? 0, out var pTcR);
tcRInfos.TryGetValue(item.TradeId, out var tcR);
tmInfos.TryGetValue(item.TradeId, out var tmValue);
tmInfos.TryGetValue(item.ParentTradeId ?? 0, out var ptmValue);
item.PositionCode = pTcR ?? tcR ?? ptmValue ?? tmValue ?? "";
break;
case Configuration.CompanyEnum.浙期:
tmInfos.TryGetValue(item.TradeId, out tmValue);
tmInfos.TryGetValue(item.ParentTradeId ?? 0, out ptmValue);
item.PositionCode = ptmValue ?? tmValue ?? parentTrade?.TradeNumber ?? item.OriginalTradeNumber;
item.OriginalTradeNumber = tmValue ?? item.OriginalTradeNumber;
var actualExerciseDate = DbContext.TradeMeta.Where(a => a.TradeId == item.TradeId && a.MetaKey == "ActualExerciseDate").FirstOrDefault()?.MetaValue;
if (!string.IsNullOrEmpty(actualExerciseDate) && DateTime.TryParse(actualExerciseDate, out DateTime newActualExerciseDate))
{
item.trade.ExerciseDate = newActualExerciseDate;
item.EndDate = item.trade.ExerciseDate;
}
break;
case Configuration.CompanyEnum.物产中大:
tmInfos.TryGetValue(item.TradeId, out tmValue);
tmInfos.TryGetValue(item.ParentTradeId ?? 0, out ptmValue);
item.PositionCode = ptmValue ?? tmValue;
item.TradeNumber = item.trade.TradeNumber;
item.ContractCode = DbContext.trade_contract_r_number.Where(n => n.TradeId == item.trade.id && n.TradeConfirmNumberType == "C").FirstOrDefault()?.ShowTradeConfirmNumber;
break;
case Configuration.CompanyEnum.上期资本:
trade_contract_r tCR = null;
//交易确认书编号
tCR = tradeContractRInfo.FirstOrDefault(n => n.TradeId == item.TradeId && n.Type == "交易确认书");
if (tCR != null)
{
item.ContractCode = tCR.ContractCode;
item.PositionCode = tCR.ContractCode;
}
else
{
item.ContractCode = null;
item.PositionCode = null;
}
break;
case Configuration.CompanyEnum.兴证:
item.PositionCode = item.trade.TradeNumber;
break;
default:
var defautPositionCode = parentTrade?.TradeNumber ?? item.OriginalTradeNumber;
if (defautPositionCode != null)
{
item.PositionCode = defautPositionCode;
}
break;
}
//一年有效天数
item.ValidDays = formartValidDays(item.trade);
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode);
var variety = DataCacheProvider.GetVarietyDataSource().GetData(um.UnderlyingTypeId);
ePnlInfos.TryGetValue(item.TradeId, out var positionInfo);
var price = positionInfo?.UnderlyingPrice ?? _priceProvider.GetPrice(item.UnderlyingCode);
//合约估值时的价格
item.ContractValuationPrice = price.ToString();
exChangeRate.TryGetValue(item.TradeId, out var ecRate);
if (!string.IsNullOrEmpty(variety.QuoteCurrency) && variety.QuoteCurrency != "CNY")
{
if (!string.IsNullOrEmpty(ecRate))
{
item.ForeignCurrencyRate = double.Parse(ecRate);
}
item.QuoteCurrency = variety.QuoteCurrency;
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
if (item.ForeignCurrencyRate != null)
item.ForeignCurrencyRate = item.ForeignCurrencyRate;
}
}
else
{
item.QuoteCurrency = "CNY";
}
FormatModel(item, assetTypeList, varietySuffixList, varietyCodeList, eRiskInfos, out _);
var protocalTyp = "协议签署版本";
var protocalTypeList = (from i in basedb.DictionaryItems join d in basedb.Dictionaries on i.DictId equals d.Id where d.Name == protocalTyp select i).ToDictionary(K => K.Name, V => V.ShortName);
var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId);
if (client != null)
{
//item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name;
while (client.IsDocShowParentName == 1 && client.ParentId > 0)
{
client = DataCacheProvider.GetClientDataSource().GetData(client.ParentId) ?? throw new ServiceException($"{client.Name} 的所属机构不存在,请维护后生成!");
}
item.ClientName = clientReportInfo.TryGetValue(client.id, out var reportName) && !string.IsNullOrWhiteSpace(reportName) ? reportName : client.Name;
item.ClientLicenseCode = client.LicenseCode;
item.ProtocalType = (!string.IsNullOrWhiteSpace(client.ProtocolSignVersion) && protocalTypeList.TryGetValue(client.ProtocolSignVersion, out var value) ? value : "9");
item.ProtocolSignDate = item.VarietyType == "EQ" ? client.RightProtocolSignDate : client.ProtocolSignDate;
//获取交易对手方LEI
item.ClientLEI = client.LEICode;
}
//中央对手方清算
iccInfo.TryGetValue(item.TradeId, out var icc);
item.IsCentralClearingPlatform = icc ?? "N";
//是否中央对方清算“字段不是”Y“时,中央清算平台才赋值
if (item.IsCentralClearingPlatform == "Y")
{
ccpInfo.TryGetValue(item.TradeId, out var ccp);
item.CentralClearingPlatform = ccp ?? null;
}
//交易平台
tpInfo.TryGetValue(item.TradeId, out var tp);
item.TradePlatform = tp ?? null;
if (item.trade.IsGroup != 1)
{
//合约价值
item.ContractPrice = (double)(positionInfo?.Pv ?? 0);
}
//累计期权并且 SettlementMode 是实物交割时赋值P
if (item.TradeType == "累计期权" && item.trade.trade_accumulator_option.SettlementMode == "实物交割")
{
if (PS.Config.Company != Configuration.CompanyEnum.浙期)
item.SettlementMethod = "P";
}
var IsUSC = false;
//非黑箱交易时处理
if (string.IsNullOrEmpty(item.trade.ExtendInfo) || item.trade.TradeType == "自定义交易")
{
if (item.trade.TradeType != "远期" && item.trade.TradeType != "掉期")
{
//雪球、凤凰
if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA" || item.OptionProductStructure == "PA")
{
if (item.ObserveType == "DISCRETE")
{
//雪球、凤凰 观察频率
koObservationRate.TryGetValue(item.TradeId, out var observationRate);
formatObservationRate(item, observationRate);
}
#region 雪球凤凰 敲入观察判断是否到期观察
var isTerminal = false;
var observeStartDates = "";
if (item.OptionProductStructure == "PA")
{
observeStartDates = item.trade.trade_autocall?.ObservationDates;
}
else
{
observeStartDates = item.trade.trade_snowball?.ObservationDates;
}
if (!string.IsNullOrEmpty(observeStartDates))
{
var odArrs = observeStartDates.Split(';');
if (odArrs.Length > 0)
{
DateTime.TryParse(odArrs[0], out DateTime koOD);
if (koOD == item.EndDate.Value)
{
isTerminal = true;
}
}
}
#endregion
if (!isTerminal)
{
//雪球、凤凰敲入观察频率
kiObservatonRate.TryGetValue(item.TradeId, out var kiOR);
formatKiObservationRate(item, kiOR);
}
}
//累计期权
else if (item.OptionProductStructure == "AC")
{
if (item.ObserveType == "DISCRETE")
{
koObservationRate.TryGetValue(item.TradeId, out var observationRate);
formatObservationRate(item, observationRate);
}
}
else
{
//其他产品观察频率观察频率
if (item.ObserveType == "DISCRETE")
{
kiObservatonRate.TryGetValue(item.TradeId, out var observationRate);
formatObservationRate(item, observationRate);
}
}
}
if (item.ToolType == "SW")
{
getObservatonRate.TryGetValue(item.TradeId, out var getOR);
payObservatonRate.TryGetValue(item.TradeId, out var payOR);
formatSWObservationRate(item, getOR, payOR);
item.OptionProductStructure = null;
if (item.trade.trade_swap != null)
{
item.ValidDays = item.trade.trade_swap.AnnualDays;
}
//当是互换、掉期时,计价单位是外币时,期初货币单位、执行价格货币单位需显示外币
if (item.QuoteCurrency != "CNY")
{
if (item.UnderlyingInitialPriceSymbol == "3")
{
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
IsUSC = true;
}
}
if (item.UnderlyingInitialPriceSymbol == "1")
{
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
IsUSC = true;
item.QuoteCurrency = "USD";
}
item.UnderlyingInitialPriceCurrency = item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency);
}
}
// 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100
if (IsUSC)
{
item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString();
item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString();
item.ContractValuationPrice = string.IsNullOrWhiteSpace(item.ContractValuationPrice) ? item.ContractValuationPrice : (Convert.ToDecimal(item.ContractValuationPrice) / 100).ToString();
}
item.StrikeSymbol = null;
item.StrikeCurrency = null;
item.Strike = null;
item.GuaranteedIncome = null;
item.GuaranteedIncomeCurrency = null;
item.GuaranteedIncomeSymbol = null;
}
else if (item.QuoteCurrency != "CNY")
{
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
IsUSC = true;
item.QuoteCurrency = "USD";
}
item.UnderlyingInitialPriceCurrency = string.IsNullOrEmpty(item.UnderlyingInitialPriceCurrency) ? null : item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency);
item.StrikeCurrency = string.IsNullOrEmpty(item.StrikeCurrency) ? null : item.StrikeCurrency.Replace("CNY", item.QuoteCurrency);
item.GuaranteedIncomeCurrency = string.IsNullOrEmpty(item.GuaranteedIncomeCurrency) ? null : item.GuaranteedIncomeCurrency.Replace("CNY", item.QuoteCurrency);
item.ExerciseBenefitsCurrency = string.IsNullOrEmpty(item.ExerciseBenefitsCurrency) ? null : item.ExerciseBenefitsCurrency.Replace("CNY", item.QuoteCurrency);
item.CompensationIncomeCurrency = string.IsNullOrEmpty(item.CompensationIncomeCurrency) ? null : item.CompensationIncomeCurrency.Replace("CNY", item.QuoteCurrency);
item.ForwardPriceCurrency = string.IsNullOrEmpty(item.ForwardPriceCurrency) ? null : item.ForwardPriceCurrency.Replace("CNY", item.QuoteCurrency);
}
if (item.ToolType == "FW" || item.ToolType == "SW")
{
item.OptionProductStructure = null;
}
if (item.UnderlyingInitialPriceSymbol == "3")
{
item.UnderlyingInitialPriceCurrency = null;
if (item.StrikeSymbol == "1")
{
item.StrikeSymbol = "3";
item.StrikeCurrency = null;
}
if (item.ForwardPriceSymbol == "1")
{
item.ForwardPriceSymbol = "3";
item.ForwardPriceCurrency = null;
}
}
// 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100 标的期初价格、平仓或终止时的标的价格、执行价格1、执行价格2、执行价格3、障碍价1、障碍价2、远期价格
if (IsUSC && (item.UnderlyingInitialPriceSymbol == "1" || item.UnderlyingInitialPriceSymbol == "3"))
{
item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString();
item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString();
item.ContractValuationPrice = string.IsNullOrWhiteSpace(item.ContractValuationPrice) ? item.ContractValuationPrice : (Convert.ToDecimal(item.ContractValuationPrice) / 100).ToString();
}
if (IsUSC && (item.StrikeSymbol == "1" || item.StrikeSymbol == "3"))
{
item.Strike /= 100;
item.Strike2 /= 100;
item.Strike3 /= 100;
item.BarriersPrice /= 100;
item.BarriersPrice2 /= 100;
}
if (IsUSC && (item.ForwardPriceSymbol == "1" || item.ForwardPriceSymbol == "3"))
{
item.ForwardPrice /= 100;
}
//雪球初始敲入时,”敲入障碍价“、”敲入观察期“字段为空
if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA")
{
if (item.trade.trade_snowball != null && item.trade.trade_snowball.IsInitialKnockedIn)
{
item.KnockInBarrierPrice = null;
item.KnockInObservationPeriod = null;
}
}
if (item.trade.TradeType == "自定义交易")
{
if (!string.IsNullOrEmpty(item.ValidDaysStr))
{
item.ValidDays = int.TryParse(item.ValidDaysStr, out int vDays) ? vDays : item.ValidDays;
}
}
}
else
{
//当是黑箱时,计价单位是外币时,期初货币单位、执行价格货币单位需显示外币
if (item.QuoteCurrency != "CNY")
{
if (item.UnderlyingInitialPriceSymbol == "3")
{
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
IsUSC = true;
}
}
if (item.UnderlyingInitialPriceSymbol == "1")
{
if (item.QuoteCurrency != null && (item.QuoteCurrency.ToLower() == "usc" || item.QuoteCurrency.ToLower() == "usd(cent)"))
{
IsUSC = true;
item.QuoteCurrency = "USD";
}
item.UnderlyingInitialPriceCurrency = item.UnderlyingInitialPriceCurrency.Replace("CNY", item.QuoteCurrency);
}
}
// 如遇货币单位为美分,如USD(cent)或USc,且价格符号为1或3时,以下涉及报送的字段需除以100 标的期初价格、平仓或终止时的标的价格、执行价格1、执行价格2、执行价格3、障碍价1、障碍价2、远期价格
if (IsUSC)
{
item.UnderlyingInitialPrice = (Convert.ToDecimal(item.UnderlyingInitialPrice) / 100).ToString();
item.ClosedUnderlyingPrice = string.IsNullOrWhiteSpace(item.ClosedUnderlyingPrice) ? item.ClosedUnderlyingPrice : (Convert.ToDecimal(item.ClosedUnderlyingPrice) / 100).ToString();
item.ContractValuationPrice = string.IsNullOrWhiteSpace(item.ContractValuationPrice) ? item.ContractValuationPrice : (Convert.ToDecimal(item.ContractValuationPrice) / 100).ToString();
}
if (!string.IsNullOrEmpty(item.ValidDaysStr))
{
item.ValidDays = int.TryParse(item.ValidDaysStr, out int vDays) ? vDays : item.ValidDays;
}
}
if (!item.IsStock)
{
item.Dividend = null;
}
//成交数量
var tradeNum = item.trade.OriginalNotional;
if (item.GuaranteedIncomeSymbol == "1")
{
if (item.GuaranteedIncome != null)
{
item.GuaranteedIncome /= tradeNum;
}
}
//行权收益
if (item.ExerciseBenefitsSymbol == "1")
{
if (item.ExerciseBenefits != null)
{
item.ExerciseBenefits /= tradeNum;
}
if (item.ExerciseBenefits2 != null)
{
item.ExerciseBenefits2 /= tradeNum;
}
if (item.ExerciseBenefits3 != null)
{
item.ExerciseBenefits3 /= tradeNum;
}
}
//补偿收益
if (item.CompensationIncomeSymbol == "1")
{
if (item.CompensationIncome != null)
{
item.CompensationIncome /= tradeNum;
}
if (item.CompensationIncome2 != null)
{
item.CompensationIncome2 /= tradeNum;
}
}
//固定收益
if (item.FixedIncomeSymbol == "1")
{
if (item.FixedIncome != null)
{
item.FixedIncome /= tradeNum;
}
}
if (PS.Config.Is招证)
{
if (item.GuaranteedIncome == 0)
{
item.GuaranteedIncome = null;
item.GuaranteedIncomeCurrency = null;
item.GuaranteedIncomeSymbol = null;
}
}
}
}
catch (ServiceException ex)
{
LogFactory.GetLogger("NewSuperviseReportPositionService").Error(ex, "已知错误");
throw;
}
catch (Exception ex)
{
LogFactory.GetLogger("NewSuperviseReportPositionService").Error(ex, "未知错误");
throw;
}
}
return retListResult;
}
/// <summary>
/// 一年有效天数,按系统参数中的定价参数(年交易天数合计)来获取
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
private int formartValidDays(trade t)
{
var vDays = 365;
//中粮
if (PS.Config.Company == Configuration.CompanyEnum.中粮)
{
bool isYear = false;
//雪球 凤凰 二元(美式)障碍(敲出类型的) 收益增强 累计期权(上端收益类型:固定)
switch (t.TradeType)
{
case "雪球期权":
if (t.trade_snowball != null && !t.trade_snowball.IsFixedCoupon)
{
isYear = true;
}
break;
case "凤凰期权":
if (t.trade_autocall != null && !t.trade_autocall.IsFixedCoupon)
{
isYear = true;
}
break;
case "二元期权":
if (t.ExerciseMode == "American" && t.trade_binary_option != null && t.trade_binary_option.RebateAnnualizedAtKO)
{
isYear = true;
}
break;
case "障碍期权":
if (t.trade_barrier_option != null && t.trade_barrier_option.RebateAnnualizedAtKO)
{
isYear = true;
}
break;
case "收益增强结构": isYear = true; break;
case "累计期权":
if (t.trade_accumulator_option != null && t.trade_accumulator_option.PayoffType == "固定" && !t.trade_accumulator_option.IsFixedCoupon)
{
isYear = true;
}
break;
}
if (isYear)
{
return vDays;
}
}
var positionReportTradeDayCountStr = valuedateBLL.SystemDate.PositionReportTradeDayCount;
switch (positionReportTradeDayCountStr)
{
case "Act365": vDays = 365; break;
case "Bus244": vDays = 244; break;
case "Bus245": vDays = 245; break;
case "ActAct":
if (DateTime.IsLeapYear(t.TradeDate.Value.Year))
{
vDays = 366;
}
else
{
vDays = 365;
}
break;
case "BusBus":
var year = t?.TradeDate?.Year;
var calendar = DbContext.calendar.FirstOrDefault(n => n.Year == year && n.ValidState != "InValid");
vDays = calendar.GetWorkingDays();
break;
case "Bus243": vDays = 243; break;
case "Bus252": vDays = 252; break;
}
return vDays;
}
/// <summary>
/// 持仓报告 设置risk表字段
/// </summary>
/// <param name="eRisk"></param>
/// <param name="model"></param>
private void formartERisk(Dictionary<int, EodTradeRisk> eRiskInfos, NewSuperviseReportPositionModel model)
{
var trade = model.trade;
var ignoreTradeTypes = new List<string>()
{
"远期",
"收益互换",
"掉期",
};
eRiskInfos.TryGetValue(model.TradeId, out var eRisk);
if (model.IsGroup == 1)
{
var childIds = DbContext.trade.Where(x => x.ParentTradeId == model.TradeId).Select(x => x.id);
var riskChilds = DbContext.eod_trade_risk.Where(x => childIds.Contains(x.TradeId) && x.ValueDate == _req.ValueDate).ToList();
model.ContractPrice = riskChilds.Sum(x => x.Pv);
model.Delta = riskChilds.Sum(x => x.Delta).OtcFormat(OtcFormatFlag.greek);
model.Vega = riskChilds.Sum(x => x.Vega).OtcFormat(OtcFormatFlag.greek);
model.Theta = riskChilds.Sum(x => x.Theta).OtcFormat(OtcFormatFlag.greek);
model.Rho = (riskChilds.Sum(x => x.Rho) * 100).OtcFormat(OtcFormatFlag.greek);
model.Gamma = riskChilds.Sum(x => x.Gamma).OtcFormat(OtcFormatFlag.greek);
model.DeltaCash = riskChilds.Sum(x => x.DeltaCash).OtcFormat(OtcFormatFlag.tradePrice);
//model.GammaCash = riskChilds.Sum(x => x.GammaCash).OtcFormat(OtcFormatFlag.tradePrice);
formatGammaCash(model);
//估值波动率
model.ValuationVolatility = eRisk == null ? null : eRisk.Vol > 0 ? eRisk.Vol.OtcFormat(OtcFormatFlag.greek) : null;
if (!string.IsNullOrEmpty(model.trade.ExtendInfo))
{
var tempVolat = 0D;
var isVolat = false;
foreach (var rItem in riskChilds)
{
if (rItem.Vol == 0)
{
continue;
}
if (tempVolat == 0)
{
tempVolat = rItem.Vol;
}
if (tempVolat == rItem.Vol)
{
isVolat = true;
}
else
{
isVolat = false;
}
tempVolat = rItem.Vol;
}
if (isVolat)
{
model.ValuationVolatility = tempVolat == 0 ? null : tempVolat.OtcFormat(OtcFormatFlag.greek);
}
//model.ValuationVolatility = riskChilds.Count > 0 && riskChilds[0].Vol > 0 ? riskChilds[0].Vol.OtcFormat(OtcFormatFlag.greek) : null;
}
}
else if (!ignoreTradeTypes.Contains(model.TradeType))
{
model.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek);
model.Vega = (eRisk?.Vega ?? 0).OtcFormat(OtcFormatFlag.greek);
model.Theta = (eRisk?.Theta ?? 0).OtcFormat(OtcFormatFlag.greek);
model.Rho = ((eRisk?.Rho ?? 0) * 100).OtcFormat(OtcFormatFlag.greek);
model.DeltaCash = (eRisk?.DeltaCash ?? 0).OtcFormat(OtcFormatFlag.tradePrice);
//model.GammaCash = (eRisk?.GammaCash ?? 0).OtcFormat(OtcFormatFlag.tradePrice);
var otherRisks = JsonHelper.Parse<OtherRisks>(eRisk?.OtherRisks);
if (otherRisks == null || string.IsNullOrWhiteSpace(otherRisks.CrossGamma))
{
model.Gamma = (eRisk?.Gamma ?? 0).OtcFormat(OtcFormatFlag.greek);
}
else
{
model.Gamma = otherRisks.CrossGamma.Replace(",", ";");
}
formatGammaCash(model);
//估值波动率
model.ValuationVolatility = eRisk == null ? null : eRisk.Vol > 0 ? eRisk.Vol.OtcFormat(OtcFormatFlag.greek) : null;
}
else
{
model.Delta = ((double)(eRisk?.Delta ?? 0)).OtcFormat(OtcFormatFlag.greek);
model.DeltaCash = (eRisk?.DeltaCash ?? 0).OtcFormat(OtcFormatFlag.tradePrice);
//model.GammaCash = (eRisk?.GammaCash ?? 0).OtcFormat(OtcFormatFlag.tradePrice);
formatGammaCash(model);
if (PS.Config.Company == Configuration.CompanyEnum.浙期 && !string.IsNullOrWhiteSpace(trade.BasisUnderlyingCode))
{
model.Delta += ";" + model.Delta;
model.DeltaCash += ";" + model.DeltaCash;
model.GammaCash = "0";
}
}
}
/// <summary>
/// 计算gammacash
/// </summary>
/// <param name="model"></param>
public void formatGammaCash(NewSuperviseReportPositionModel model)
{
double curRate = 1;
var cvPrices = model.ContractValuationPrice.Split(';');
double.TryParse(model.Gamma, out double gammaTemp);
var gammacashStr = "";
if (model.QuoteCurrency.ToUpper() != "CNY")
{
var eodCurrencyRate = DbContext.eod_currency_rate.FirstOrDefault(n => n.ValueDate == _req.ValueDate && n.LocalCurrency == "CNY" && (n.ForeignCurrency == model.QuoteCurrency.ToUpper() || n.ForeignCurrency == model.QuoteCurrency.ToLower()));
if (eodCurrencyRate != null)
{
curRate = eodCurrencyRate.Rate;
}
}
for (int i = 0; i < cvPrices.Length; i++)
{
double.TryParse(cvPrices[i], out double cvPrice);
if (i == (cvPrices.Length - 1))
{
gammacashStr += (gammaTemp * cvPrice * curRate).OtcFormat(OtcFormatFlag.tradePrice);
}
else
{
gammacashStr += (gammaTemp * cvPrice * curRate).OtcFormat(OtcFormatFlag.tradePrice) + ";";
}
}
model.GammaCash = gammacashStr;
}
/// <summary>
/// 持仓报告 设置特定字段
/// </summary>
/// <param name="model"></param>
private void formatOptionlFields(NewSuperviseReportPositionModel model)
{
var t = model.trade;
switch (model.OptionProductStructure)
{
case "SKI":
if (t.trade_barrier_option != null)
{
if (t.trade_barrier_option != null && !string.IsNullOrEmpty(t.trade_barrier_option.BarrierType)
&& model.trade.trade_barrier_option.BarrierType.EndsWith("敲入"))
{
if (!string.IsNullOrEmpty(t.trade_barrier_option.KnockInOutStatus) && t.trade_barrier_option.KnockInOutStatus.ToLower().Contains("in"))
{
model.KnockIn = "Y";
}
else
{
model.KnockIn = "N";
}
}
else
{
model.KnockIn = "N";
}
}
break;
case "SA":
case "GSA":
if (t.trade_snowball != null)
{
//初始敲入时,没敲入价也填
if (t.trade_snowball.IsInitialKnockedIn)
{
model.KnockIn = "Y";
}
else if (!string.IsNullOrEmpty(t.trade_snowball.KnockInOutStatus) && (t.trade_snowball.KnockInOutStatusCn.Contains("敲入")
|| t.trade_snowball.KnockInOutStatus.ToLower().Contains("in")))
{
model.KnockIn = "Y";
}
else
{
model.KnockIn = "N";
}
}
break;
case "PA":
if (t.trade_autocall != null)
{
if (!string.IsNullOrEmpty(t.trade_autocall.KnockInOutStatus) && (t.trade_autocall.KnockInOutStatusCn.Contains("敲入") || t.trade_autocall.KnockInOutStatus.ToLower().Contains("in")))
{
model.KnockIn = "Y";
}
else
{
model.KnockIn = "N";
}
}
break;
case "AS":
var QdpTrade = TradeCalcHelper.GetQdpTrade(t, _req.ValueDate);
if (QdpTrade != null && QdpTrade.Instrument != null && QdpTrade.Instrument is IOption opt)
{
var asianOpt = opt as AsianOption;
try
{
model.ObserveAverage = t.trade_asian_option != null && t.trade_asian_option.StrikeType == "Floating" ? asianOpt.ActualStrike : asianOpt.FinalPrice();
}
catch
{
model.ObserveAverage = _priceProvider.GetPrice(model.trade.UnderlyingCode);
}
}
break;
}
}
/// <summary>
/// 观察频率
/// </summary>
/// <param name="item"></param>
/// <param name="koOR"></param>
private void formatObservationRate(NewSuperviseReportPositionModel item, string observationRate = "")
{
string num = "", unit = "", unitStr = "";
string[] orArray;
if (!string.IsNullOrEmpty(observationRate))
{
orArray = observationRate.Split('|');
if (orArray.Length == 2)
{
if (orArray[1] == "OTHER")
{
item.ObservationPeriod = orArray[1];
}
else
{
num = orArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", "");
unitStr = orArray[1].Replace(num, "");
item.ObservationPeriod = unitStr;
item.ObservePeriodMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN;
}
}
else
{
num = observationRate.Substring(0, observationRate.Length - 1);
unit = observationRate.Substring(observationRate.Length - 1);
unitStr = getUnitStr(unit);
item.ObservationPeriod = unitStr;
item.ObservePeriodMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN;
}
}
else
{
if ((item.OptionProductStructure != "SA" && item.OptionProductStructure != "GSA" && item.OptionProductStructure != "PA"))
{
if (item.ObserveType == "DISCRETE")
{
num = "1";
unit = "D";
unitStr = getUnitStr(unit);
item.ObservationPeriod = unitStr;
item.ObservePeriodMultiplier = double.Parse(num);
}
else if (item.trade.TradeType == "自定义交易")
{
item.ObservationPeriod = "OTHER";
}
}
else if (item.OptionProductStructure == "SA" || item.OptionProductStructure == "GSA" || item.OptionProductStructure == "PA")
{
num = "1";
unit = "M";
unitStr = getUnitStr(unit);
item.ObservationPeriod = unitStr;
item.ObservePeriodMultiplier = double.Parse(num);
}
}
}
/// <summary>
/// 雪球 凤凰敲入观察频率
/// </summary>
/// <param name="item"></param>
/// <param name="kiOR"></param>
private void formatKiObservationRate(NewSuperviseReportPositionModel item, string kiOR = "")
{
string num = "", unit = "", unitStr = "";
string[] kiORArray;
//敲入观察频率
if (!string.IsNullOrEmpty(kiOR))
{
kiORArray = kiOR.Split('|');
if (kiORArray.Length == 2)
{
num = kiORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", "");
unitStr = kiORArray[1].Replace(num, "");
item.KnockInObservationPeriod = unitStr;
}
else
{
num = kiOR.Substring(0, kiOR.Length - 1);
unit = kiOR.Substring(kiOR.Length - 1);
unitStr = getUnitStr(unit);
item.KnockInObservationPeriod = unitStr;
}
}
else
{
num = "1";
unit = "D";
unitStr = getUnitStr(unit);
if (item.OptionProductStructure == "GSA")
{
unitStr = "";
}
item.KnockInObservationPeriod = unitStr;
}
}
/// <summary>
/// 互换产品观察频率
/// </summary>
/// <param name="item"></param>
/// <param name="kiOR"></param>
/// <param name="koOR"></param>
private void formatSWObservationRate(NewSuperviseReportPositionModel item, string getOR = "", string payOR = "")
{
string num = "", unit = "", unitStr = "";
string[] getORArray;
string[] payORArray;
if (!string.IsNullOrEmpty(getOR) && getOR != "TERM")
{
getORArray = getOR.Split('|');
if (getORArray.Length == 2)
{
if (getORArray[1] == "OTHER" || getORArray[1] == "TERM")
{
unitStr = getORArray[1];
}
else
{
num = getORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", "");
unitStr = getORArray[1].Replace(num, "");
}
}
else
{
num = getOR.Substring(0, getOR.Length - 1);
unit = getOR.Substring(getOR.Length - 1);
unitStr = getUnitStr(unit);
}
item.PaymentCycle = unitStr;
item.PaymentCycleMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN;
}
else if (!string.IsNullOrEmpty(payOR) && payOR != "TERM")
{
payORArray = payOR.Split('|');
if (payORArray.Length == 2)
{
if (payORArray[1] == "OTHER" || payORArray[1] == "TERM")
{
unitStr = payORArray[1];
}
else
{
num = payORArray[1].Replace("DAIL", "").Replace("WEEK", "").Replace("MNTH", "").Replace("YEAR", "");
unitStr = payORArray[1].Replace(num, "");
}
}
else
{
num = payOR.Substring(0, payOR.Length - 1);
unit = payOR.Substring(payOR.Length - 1);
unitStr = getUnitStr(unit);
}
item.PaymentCycle = unitStr;
item.PaymentCycleMultiplier = double.TryParse(num, out var temp) ? temp : double.NaN;
}
else
{
//互换产品未选支付周期,默认TERM
item.PaymentCycle = "TERM";
}
}
private string getUnitStr(string inputVal)
{
switch (inputVal)
{
case "D": return "DAIL";
case "W": return "WEEK";
case "M": return "MNTH";
case "Y": return "YEAR";
default: return "Other";
}
}
#endregion
}
}