Files
zszq-trs/YLErpDAL/Modules/EodModule/QueryModule/EodTradePositionExportService.cs
T
2024-05-09 14:06:26 +08:00

855 lines
44 KiB
C#

using BaseOUDAL;
using CsvHelper;
using CsvHelper.Configuration;
using ICSharpCode.SharpZipLib.Zip;
using System.Data;
using YLErp.Commons;
using YLErp.DBModels.Helpers;
using YLErp.Modules.ClientModule;
using YLErp.Modules.TradeModule;
using YLErp.Office.ExcelModule;
using YLErp.QdpModule;
namespace YLErp.Modules.EodModule.QueryModule
{
/// <summary>
/// 日终持仓导出服务
/// 暂时用于兴证数据接口导出
/// </summary>
public class EodTradePositionExportService : YLBaseService
{
public EodTradePositionExportService(OptUserInfo optUser) : base(optUser)
{
}
/// <summary>
/// 查询场外期权持仓列表
/// </summary>
public void SearchOptionTradeListForExport(DateTime valueDate
, out List<EodOptionPositionExportFields> listOption
, out List<EodPayOffSwapPositionExportFields> listSwap)
{
listSwap = null;
listOption = null;
var IsPVRounded = PS.Config.IsPVRounded;
valueDate = valueDate.Date;
var query = from et in DbContext.eod_trade
join etp in DbContext.eod_trade_position on et.TradeId equals etp.TradeId
join etr in DbContext.eod_trade_risk on et.TradeId equals etr.TradeId
where et.ValueDate == valueDate && etp.ValueDate == valueDate && etr.ValueDate == valueDate
&& et.TradeId > 0 && etp.TradeId > 0 && etr.TradeId > 0
&& et.TradeType != "结构化交易" && et.ClientId > 0
select new
{
et.TradeId,
et.TradeJson,
etp.Amount,
etp.Pv,
PositionPv = IsPVRounded ? etp.RoundedPv : etp.Pv,
PositionPnl = IsPVRounded ? etp.RoundedPositionPnL : etp.PositionPnL,
etr.Vol
};
//因为query还在读取中,所以不要用同一个dbcontext
var extendService = new TradeExtendService(OptUser);
foreach (var item in query)
{
var td = TradeHelper2.Deserialize(item.TradeJson);
if (td == null)
{
td = DbContext.trade.Find(item.TradeId);
}
if (td == null)
{
continue;
}
extendService.SetTradeExtend(new[] { td }, true);
if (td.TradeType == "收益互换")
{
var f = GetEodPayOffSwapPostionFields(td, item.Amount, item.PositionPnl, item.PositionPv);
if (listSwap == null)
{
listSwap = new List<EodPayOffSwapPositionExportFields>();
}
listSwap.Add(f);
}
else if (td.TradeType == "远期")
{
}
else
{
var f = GetEodOptionPostionFields(td, item.Amount, item.PositionPnl, item.PositionPv, item.Vol);
if (listOption == null)
{
listOption = new List<EodOptionPositionExportFields>();
}
listOption.Add(f);
}
}
}
//场外期权
private EodOptionPositionExportFields GetEodOptionPostionFields(trade td, double PositionTradeAmount, double PositionPnl, double PositionPv, double PositionVol)
{
var isMoneyness = td.IsMoneynessOption == "是";
var isPremiumRate = td.IsUsePremiumRate == true;
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(td.UnderlyingCode);
var volFormat = PS.Config.ErpElement.VolMoreAccurate ? "P2" : "P4";
var f = new EodOptionPositionExportFields
{
TradeNumber = td.TradeNumber,
AssetBookName = td.AssetBookName,
TraderName = td.TraderName,
ClientName = td.ClientName,
StructureType = td.TradeType,
ExerciseMode = td.ExerciseModeCn,
CallPut = td.CallPut,
TradeDate = td.TradeDate.OtcFormatDate(),
ExerciseDate = td.ExerciseDate.OtcFormatDate(),
SettlementDate = td.SettlementDate.OtcFormatDate(),
TradeSide = td.BuySell,
UnderlyingCode = td.UnderlyingCode,
UnderlyingName = underlying?.UnderlyingName,
InitSpotPrice = td.SpotPrice.OtcFormatUmPrice(),
Strike = td.Strike.OtcFormatUmPrice(isMoneyness),
IsMoneynessOption = isMoneyness ? "是" : "否",
Premium = isPremiumRate ? td.PremiumRate.OtcFormat(OtcFormatFlag.premiumRateP) : td.TradeSinglePrice.OtcFormat(OtcFormatFlag.tradeSinglePrice),
IsUsePremiumRate = isPremiumRate ? "是" : "否",
InitialMargin = td.InitialMargin.OtcFormatMoney(),
TradeAmount = td.OriginalNotional.OtcFormatNotional(),
TradePrice = td.TradePrice.OtcFormatMoney(),
StockEqvNotional = td.OriginalStockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional),
StockEqvNotionalReal = td.StockEqvNotionalReal.OtcFormat(OtcFormatFlag.StockEqvNotional),
IsAnnualized = td.IsAnnualized ? "是" : "否",
AnnualizeFactor = td.AnnualizeFactor?.ToString("F8"),
PrincipalRate = td.PrincipalRate.OtcFormatPercent(),
ParticipationRate = td.ParticipationRate.OtcFormatPercent(),
NoRiskRate = td.NoRiskRate.OtcFormatPercent(),
DividendRate = td.DividendRate.OtcFormatPercent(),
TradeOpenVolatility = td.TradeOpenVolatility?.ToString(volFormat),
TradeCloseVolatility = td.TradeCloseVolatility?.ToString(volFormat),
NumOfSmoothingDays = td.NumOfSmoothingDays?.ToString(),
Comments = td.Comments,
PositionPnl = Convert.ToDouble(PositionPnl).OtcFormatMoney(),
PositionPv = Convert.ToDouble(PositionPv).OtcFormatMoney(),
PositionTradeAmount = PositionTradeAmount.OtcFormatNotional(),
PositionVol = PositionVol.ToString(volFormat)
};
f.ClientNumber = ClientDataQueryService.GetClient(td.ClientId)?.Number;
switch (f.StructureType)
{
case "亚式期权":
if (td.trade_asian_option != null)
{
var ext = td.trade_asian_option;
f.AsianAveragingPeriodStartDate = ext.AveragingPeriodStartDate.OtcFormatDate();
f.AsianPayoffType = ext.PayoffTypeCn;
f.AsianStrikeType = ext.StrikeTypeCn;
f.AsianStrikeGearingFactor = ext.StrikeGearingFactor.OtcFormatPercent();
}
break;
case "障碍期权":
if (td.trade_barrier_option != null)
{
var ext = td.trade_barrier_option;
f.BarrierType = ext.BarrierType;
f.BarrierPrice = ext.BarrierPrice.OtcFormatUmPrice(isMoneyness);
f.BarrierPriceHigh = ext.UpperBarrierPrice.OtcFormatUmPrice(isMoneyness);
f.BarrierShift = ext.BarrierShift.OtcFormatUmPrice();
f.BarrierRebate = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateRate, ext.Rebate);
f.BarrierRebateType = ext.RebateTypeCn;
f.BarrierDiscrete = ext.Discrete;
f.BarrierKnockInOutStatus = ext.KnockInOutStatus;
f.BarrierKnockInOutDate = ext.KnockInOutDate.OtcFormatDate();
}
break;
case "双鲨期权":
if (td.trade_double_sharkfin_option != null)
{
var ext = td.trade_double_sharkfin_option;
f.DbsharkBarrierLow = ext.BarrierLow.OtcFormatUmPrice(isMoneyness);
f.DbsharkBarrierHigh = ext.BarrierHigh.OtcFormatUmPrice(isMoneyness);
f.DbsharkStrikeHigh = ext.StrikeHigh.OtcFormatUmPrice(isMoneyness);
f.DbsharkCallParticipationRate = ext.CallParticipationRate.OtcFormatPercent();
f.DbsharkPutParticipationRate = ext.PutParticipationRate.OtcFormatPercent();
f.DbsharkRebate = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateRate, ext.Rebate);
f.DbsharkRebateHigh = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.RebateHighRate, ext.RebateHigh);
f.DbsharkRebateType = TradeHelper.GetRebateTypeCn(ext.RebateType);
f.DbsharkDiscrete = ext.Discrete;
}
break;
case "二元期权":
if (td.trade_binary_option != null)
{
var ext = td.trade_binary_option;
f.BinaryPayoffType = ext.PayoffType;
f.BinaryUpperBarrier = ext.UpperBarrier.OtcFormatUmPrice(isMoneyness);
f.BinaryCashOrNothingAmount = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.CashOrNothingAmountRate, ext.CashOrNothingAmount);
f.BinaryCashOrNothingAmountHigh = OtcFormatHelper.FormatPremium(td.IsUsePremiumRate, ext.CashOrNothingAmountHighRate, ext.CashOrNothingAmountHigh);
f.BinaryMonitorType = ext.MonitorType;
f.BinaryRebateType = TradeHelper.GetRebateTypeCn(ext.RebateType);
}
break;
case "区间累积期权":
if (td.trade_rangeaccrual != null)
{
var ext = td.trade_rangeaccrual;
f.RangeAccrualLowerRange = ext.LowerRange.OtcFormatUmPrice(isMoneyness);
f.RangeAccrualUpperRange = ext.UpperRange.OtcFormatUmPrice(isMoneyness);
f.RangeAccrualBonusRate = ext.BonusRate.OtcFormatPercent(4);
f.CallPut = string.Empty;
}
break;
case "气囊结构":
if (td.trade_airbag != null)
{
var ext = td.trade_airbag;
f.AirbagBarrier = ext.Barrier.OtcFormatUmPrice(isMoneyness);
f.AirbagIsDiscrete = ext.IsDiscreteMonitored ? "是" : "否";
f.AirbagKIParticipationRate = ext.KIParticipationRate.OtcFormatPercent();
f.AirbagHasPayoffLimit = ext.HasPayoffLimit ? "是" : "否";
f.AirbagHighStrike = ext.HighStrike.OtcFormatUmPrice(isMoneyness);
f.CallPut = string.Empty;
}
break;
case "收益增强结构":
if (td.trade_underlying_enhance != null)
{
f.CallPut = string.Empty;
f.AnnualizedEnhanceRate = td.trade_underlying_enhance.AnnualizedEnhanceRate.OtcFormatPercent(4);
}
break;
case "凤凰期权":
if (td.trade_autocall != null)
{
var ext = td.trade_autocall;
f.AutocallIsFixedCoupon = ext.IsFixedCoupon ? "否" : "是";
f.AutocallCoupon = ext.Coupon.OtcFormatPercent();
f.AutocallCouponBarrier = ext.CouponBarrier.OtcFormatUmPrice(isMoneyness);
f.AutocallCouponPayType = ext.CouponPayTypeDesc();
f.AutocallKOBarrier = ext.KOBarrier.OtcFormatUmPrice(isMoneyness);
f.AutocallKIBarrier = ext.KIBarrier.OtcFormatUmPrice(isMoneyness);
f.AutocallIncludeCouponAfterKI = ext.IncludeCouponAfterKI ? "是" : "否";
f.AutocallKIPayoffType = ext.KIPayoffTypeDesc();
f.AutocallKIStrike1 = ext.SpreadStrike1.OtcFormatUmPrice(isMoneyness);
if (ext.KIPayoffType == KIPayoffTypeEnum.ToPutSpreadOption)
{
f.AutocallKIStrike2 = ext.SpreadStrike.OtcFormatUmPrice(isMoneyness);
}
var KOObservationDates = ext.KOObservationDates ?? string.Empty;
var index = KOObservationDates.IndexOf(';');
f.KOObservationDates = index > 0 ? ext.KOObservationDates.Substring(0, index) : KOObservationDates;
f.KIObservationDates = ext.ObservationDates;
f.IsAnnualized = ext.IsAnnualized2 ? "是" : "否";
}
break;
case "雪球期权":
if (td.trade_snowball != null)
{
var ext = td.trade_snowball;
f.SnowballKOBarrier = ext.KOBarrier.OtcFormatUmPrice(isMoneyness);
switch (ext.KOPayoffType)
{
case KOPayoffTypeEnum.Rebate:
f.SnowballKOPayoffType = "票息补偿";
f.SnowballIsFixedCoupon = ext.IsFixedCoupon ? "否" : "是";
f.SnowballKORebate = ext.KORebate.OtcFormatPercent();
f.SnowballAnnualizedPremiumRate = ext.AnnualizedPremiumRate.OtcFormatPercent();
f.SnowballKOObservationSettleDates = ext.KOObservationSettleDates;
break;
case KOPayoffTypeEnum.ToOption:
f.SnowballKOPayoffType = KOPayoffTypeEnumHelper.GetDesc(ext.KOPayoffType, td.CallPut);
f.SnowballKOStrike1 = ext.SpreadStrikeAtKO1.OtcFormatUmPrice(isMoneyness);
break;
case KOPayoffTypeEnum.ToSpreadOption:
f.SnowballKOPayoffType = KOPayoffTypeEnumHelper.GetDesc(ext.KOPayoffType, td.CallPut);
f.SnowballKOStrike2 = ext.SpreadStrikeAtKO.OtcFormatUmPrice(isMoneyness);
f.SnowballKOStrike1 = ext.SpreadStrikeAtKO1.OtcFormatUmPrice(isMoneyness);
break;
default:
f.SnowballKOPayoffType = ext.KOPayoffType.ToString();
break;
}
f.SnowballKORebateType = RebateTypeEnumHelper.GetDesc(ext.KORebateType);
f.SnowballKIBarrier = ext.KIBarrier.OtcFormatUmPrice(isMoneyness);
switch (ext.KIPayoffType)
{
case KIPayoffTypeEnum.None:
f.SnowballKIPayoffType = "无";
break;
case KIPayoffTypeEnum.ToPutOption:
f.SnowballKIPayoffType = "敲入转看跌";
f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness);
break;
case KIPayoffTypeEnum.ToPutSpreadOption:
f.SnowballKIPayoffType = "敲入转熊市价差";
f.SnowballKIStrike2 = ext.SpreadStrikeAtMaturity.OtcFormatUmPrice(isMoneyness);
f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness);
break;
case KIPayoffTypeEnum.ToCallOption:
f.SnowballKIPayoffType = "敲入转看涨";
f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness);
break;
case KIPayoffTypeEnum.ToCallSpreadOption:
f.SnowballKIPayoffType = "敲入转牛市价差";
f.SnowballKIStrike2 = ext.SpreadStrikeAtMaturity.OtcFormatUmPrice(isMoneyness);
f.SnowballKIStrike1 = ext.SpreadStrikeAtMaturity1.OtcFormatUmPrice(isMoneyness);
break;
default:
f.SnowballKIPayoffType = ext.KIPayoffType.ToString();
break;
}
f.SnowballNoKICoupon = ext.Coupon.OtcFormatPercent();
var KOObservationDates = ext.KOObservationDates ?? string.Empty;
var index = KOObservationDates.IndexOf(';');
f.KOObservationDates = index > 0 ? ext.KOObservationDates.Substring(0, index) : KOObservationDates;
f.KIObservationDates = ext.ObservationDates;
f.IsAnnualized = ext.IsAnnualized2 ? "是" : "否";
}
break;
}
if (td.TradeType == "凤凰期权" || td.TradeType == "雪球期权")
{
f.CallPut = f.ExerciseMode = string.Empty;
td.MetaDic.TryGetValue(nameof(OtcOptionTradeFull.AnnualizeFactor2), out var metaValue);
f.AnnualizeFactor = metaValue;
}
else
{
td.MetaDic.TryGetValue(nameof(OtcOptionTradeFull.AnnualizeFactor), out var metaValue);
f.AnnualizeFactor = metaValue;
}
return f;
}
//收益互换
private EodPayOffSwapPositionExportFields GetEodPayOffSwapPostionFields(trade td, double PositionTradeAmount, double PositionPnl, double PositionPv)
{
var swap = td.trade_swap ?? new trade_swap();
var f = new EodPayOffSwapPositionExportFields
{
TradeNumber = td.TradeNumber,
AssetBookName = td.AssetBookName,
TraderName = td.TraderName,
ClientName = td.ClientName,
TradeDate = td.TradeDate.OtcFormatDate(),
ExerciseDate = td.ExerciseDate.OtcFormatDate(),
StockEqvNotional = td.OriginalStockEqvNotional.OtcFormat(OtcFormatFlag.StockEqvNotional),
Comments = td.Comments,
GetFixedProfit = swap.GetFixedProfit.OtcFormatMoney(),
GetLongShort = swap.GetLongShort,
GetMarginRate = swap.GetMarginRate.OtcFormatFlex(minDecimals: 0, percent: true),
GetTradePrice = swap.GetTradePrice.OtcFormatMoney(),
GetUnderlyingCode = swap.GetUnderlyingCode,
GetSpotPrice = swap.GetSpotPrice.OtcFormatUmPrice(),
IsGetFloatingProfit = swap.IsGetFloatingProfit ? "是" : "否",
IsPayFloatingProfit = swap.IsPayFloatingProfit ? "是" : "否",
PayFixedProfit = swap.PayFixedProfit.OtcFormatMoney(),
PayLongShort = swap.PayLongShort,
PayMarginRate = swap.PayMarginRate.OtcFormatMoney(),
PaySpotPrice = swap.PaySpotPrice.OtcFormatUmPrice(),
PayTradePrice = swap.PayTradePrice.OtcFormatMoney(),
PayUnderlyingCode = swap.PayUnderlyingCode,
PositionPnl = Convert.ToDouble(PositionPnl).OtcFormatMoney(),
PositionPv = Convert.ToDouble(PositionPv).OtcFormatMoney(),
PositionStockEqvNotional = PositionTradeAmount.OtcFormat(OtcFormatFlag.StockEqvNotional)
};
f.ClientNumber = ClientDataQueryService.GetClient(td.ClientId)?.Number;
return f;
}
/// <summary>
/// 查询场内期权持仓列表
/// </summary>
public IEnumerable<EodExOptionPositionExportFields> SearchExOptionTradeListForExport(DateTime valueDate)
{
var IsPVRounded = PS.Config.IsPVRounded;
var umSource = DataCacheProvider.GetUnderlyingDataSource();
var exOptionSource = DataCacheProvider.GetExchangeListOptionDataSource();
var volFormat = PS.Config.ErpElement.VolMoreAccurate ? "P2" : "P4";
valueDate = valueDate.Date;
var query = from etp in DbContext.eod_trade_position
join etr in DbContext.eod_trade_risk on etp.TradeId equals etr.TradeId
where etp.ValueDate == valueDate && etr.ValueDate == valueDate
&& etp.TradeType == "场内期权"
select new
{
etp.UnderlyingCode,
etp.ExchangeOptionCode,
etp.Amount,
etp.PositionType,
PositionPv = IsPVRounded ? etp.RoundedPv : etp.Pv,
PositionPnl = IsPVRounded ? etp.RoundedPositionPnL : etp.PositionPnL,
etr.Vol
};
var list = new List<EodExOptionPositionExportFields>();
foreach (var item in query)
{
var exoption = exOptionSource.GetData(item.ExchangeOptionCode);
var f = new EodExOptionPositionExportFields
{
OptionCode = item.ExchangeOptionCode,
ExerciseMode = exoption?.ExerciseMode,
Strike = (exoption?.Strike)?.ToString("F4"),
UnderlyingCode = item.UnderlyingCode,
PositionType = item.PositionType,
PositionPnl = Convert.ToDouble(item.PositionPnl).OtcFormatMoney(),
PositionPv = Convert.ToDouble(item.PositionPv).OtcFormatMoney(),
PositionTradeAmount = item.Amount.OtcFormatNotional(),
PositionVol = item.Vol.ToString(volFormat)
};
list.Add(f);
}
return list;
}
/// <summary>
/// 导出兴证数据中心需要的文件
/// </summary>
public byte[] ExportXingZhengZipFile(DateTime valueDate, out string zipFileName, IEnumerable<int> clienIds = null)
{
valueDate = valueDate.Date;
if (QdpCalendarHelper.GetNonHoliday(valueDate) != valueDate)
{
throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'不是交易日!");
}
if (!DbContext.eodStatus.Any(n => n.ValueDate == valueDate && n.Status == "已收盘"))
{
throw new ServiceException($"所选日期'{valueDate:yyyy-MM-dd}'未收盘!");
}
SearchOptionTradeListForExport(valueDate, out var listOption, out var listSwap);
var listExOption = SearchExOptionTradeListForExport(valueDate);
var dateStr = valueDate.ToString("yyyyMMdd");
zipFileName = $"ylotc_position_{dateStr}.zip";
var clients = DbContextFactory.GetClientDbContext(UserInfo).client
.Where(d => d.ProcessStatus == "已开户" || d.ProcessStatus == "已休眠" || d.ProcessStatus == "已销户")
.Select(n => new InnerClientInfo { id = n.id, ClientNumber = n.Number, ClientName = n.Name, LicenseCode = n.LicenseCode, ClientType = n.ClientType }).ToArray();
#region 新增客户筛选 tw
if (clienIds != null)
{
clients = clients.Where(l => clienIds.Contains(l.id)).ToArray();
}
#endregion
using (var yldb = DbContextFactory.GetYLDbContext())
{
var sumQuery = from t in yldb.trade
where t.ValidState != ConsGlobal.InValid && t.IsGroup != 2
&& (t.TradeType != "结构化交易" || t.IsGroup == 1)
group t by t.ClientId into g
select new
{
clientId = g.Key,
sum = g.Sum(n => n.OriginalStockEqvNotional ?? 0)
};
var sumDic = sumQuery.ToDictionary(n => n.clientId, m => m.sum);
foreach (var c in clients)
{
if (sumDic.TryGetValue(c.id, out var sum))
{
c.StockEqvNotional = sum.ToString("F4");
}
}
}
using (var ms = new MemoryStream())
using (var outStream = new ZipOutputStream(ms))
using (var writer = new StreamWriter(outStream))
{
var csvConfig = new CsvConfiguration(System.Globalization.CultureInfo.InvariantCulture)
{
LeaveOpen = true,
Delimiter = "$#$"
};
outStream.PutNextEntry(new ZipEntry($"ylotc_position_option_{dateStr}.csv"));
using (var csv = new CsvWriter(writer, csvConfig))
{
csv.WriteRecords(listOption ?? Enumerable.Empty<EodOptionPositionExportFields>());
}
writer.Flush();
outStream.PutNextEntry(new ZipEntry($"ylotc_position_exoption_{dateStr}.csv"));
using (var csv = new CsvWriter(writer, csvConfig))
{
csv.WriteRecords(listExOption ?? Enumerable.Empty<EodExOptionPositionExportFields>());
}
writer.Flush();
outStream.PutNextEntry(new ZipEntry($"ylotc_position_payoffswap_{dateStr}.csv"));
using (var csv = new CsvWriter(writer, csvConfig))
{
csv.WriteRecords(listSwap ?? Enumerable.Empty<EodPayOffSwapPositionExportFields>());
}
writer.Flush();
outStream.PutNextEntry(new ZipEntry($"ylotc_client_{dateStr}.csv"));
using (var csv = new CsvWriter(writer, csvConfig))
{
csv.WriteRecords(clients);
}
writer.Flush();
writer.Close();
return ms.ToArray();
}
}
public byte[] GetClient()
{
var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/国投客户数据采集.xlsx");
using (var baseDb = new ClientDBContext())
{
//处理客户不属于 内部客户 n.IsInsided!=1
var ClientList = baseDb.client.Where(n => n.ProcessStatus == "已开户"&&n.IsInsided!=1).Select(x =>
new ClientInfo
{
ClientType = x.ClientType == "自然人" ? "个人" : x.ClientType,
ClientName = x.Name,
ClientTypeMemo = x.ClientType == "机构" ? "机构全称" : x.ClientType == "自然人" ? "" : "产品全称",
AdminFullName = x.ClientType == "产品" ? x.AdminFullName : "",
LicenseType = x.ClientType == "机构" ? "统一社会信用代码" : x.ClientType == "自然人" ? "居民身份证" : "产品编号",
AdminFullNameMome = x.ClientType == "产品" ? "产品管理人全称" : "",
IdentificationNumber = x.ClientType == "机构" ? x.LicenseCode : x.ClientType == "自然人" ? x.IdentificationNumber : x.ProductNumber,
AdminFullNameLicenseType = x.ClientType == "机构" ? "" : x.ClientType == "自然人" ? "" : "统一社会信用代码",
AdminRegisteredNum = x.ClientType == "产品" ? x.LicenseCode : "",
MainProtocolCode = x.MainProtocolCode
});
var buffer = ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = ClientList }).GenerateBytes();
return buffer;
}
}
public byte[] GetEodPosition(Model.EodPositionRisksReq req)
{
var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/国投数据采集.xlsx");
using (var baseDb = new ClientDBContext())
{
req.ValueDate = req.ValueDate;
req.EodSettlePriceMode = "收盘价";
req.IsOnlyExport = false;
req.IsParentTrade = false;
req.needSettleData = false;
req.VolType = "持仓";
//处理客户不属于 内部客户
req.ClientIds = baseDb.client.Where(n => n.IsInsided != 1).Select(l => l.id).ToList();
var result = new EodPositionRisksQueryService(UserInfo).SearchList(req);
var responEodPositions = new List<ResponEodPosition>();
foreach (var item in result.rows)
{
var responEodPosition = new ResponEodPosition();
var td = DbContext.trade.FirstOrDefault(l => l.id == item.id);
responEodPosition.bookName = item.AssetBookName;
responEodPosition.tradeId = item.TradeNumber;
responEodPosition.positionId = item.trade?.AssetId;
responEodPosition.underlyerInstrumentId = item.UnderlyingCode;
responEodPosition.underlyerMultiplier = GetunderlyerMultiplier(item.UnderlyingCode);
responEodPosition.productType = item.TradeType;
responEodPosition.initialNumber = item.TradeOriginalAmount;
responEodPosition.unwindNumber = td?.UnWindNotional;
responEodPosition.number = item.Notional;
responEodPosition.premium = item.TradePrice;
responEodPosition.marketValue = item.RoundedPV;
responEodPosition.pnl = item.dailyPnl;
responEodPosition.delta = item.Delta;
responEodPosition.deltaCash = item.DeltaCash;
responEodPosition.gamma = item.Gamma;
responEodPosition.gammaCash = item.GammaCash;
responEodPosition.vega = item.Vega;
responEodPosition.theta = item.Theta;
responEodPosition.rho = item.Rho;
responEodPosition.effectiveDate = td?.TradeDate;
responEodPosition.expirationDate = td?.ExerciseDate;
responEodPosition.message = "";
responEodPosition.pricingEnvironment = "";
responEodPosition.r = item.RiskFreeRate;
responEodPosition.q = item.DividendRate;
responEodPosition.vol = item.CurrentVolatility;
responEodPosition.listedOption = 0;//!
responEodPosition.price = item.UnderlyingPrice;
responEodPosition.notional = td?.StockEqvNotionalReal;
responEodPosition.initialNotional = item.StockEqvNotional;
responEodPosition.initialMargin = item.Margin;
responEodPosition.maintenanceMargin = td?.InitialMargin;
responEodPosition.initialVol = item.CurrentVolatility;
responEodPosition.masterAgreementId = GetmasterAgreement(item.ClientNumber);
responEodPosition.direction = td?.BuySell;
if (td != null)
{
responEodPosition.initialQ = GetinitialQ(item.id, req.ValueDate);
responEodPosition.initialR = GetinitialR(item.id, req.ValueDate);
responEodPosition.term = QdpModule.QdpCalendarHelper.AllBizDays(Convert.ToDateTime(td.TradeDate), Convert.ToDateTime(td.ExerciseDate)).Count;
var strike = DbContext.trade_double_sharkfin_option.FirstOrDefault(l => l.TradeId == item.id);
responEodPosition.highStrike = strike?.StrikeHigh;
responEodPosition.lowStrike = strike?.StrikeLow;
}
responEodPosition.settlementDate = td?.SettlementDate;//!
responEodPosition.tradeStatus = item.TradeStatus;
responEodPosition.lcmEventType = item.TradeStatus;
responEodPosition.initialSpot = td?.SpotPrice;
responEodPosition.highBarrier = item.RebateHigh;
responEodPosition.lowBarrier = item.Rebate;
responEodPosition.participationRates = item.ParticipationRate;
responEodPosition.rebate = item.Rebate;
responEodPosition.annualized = td?.IsAnnualized;
responEodPosition.specifiedPrice = td?.SettlementType == SettlementTypeEnum.ClosePrice ? "收盘价" : "结算价";
responEodPosition.frontPremium = item.TradeAmount;
responEodPosition.minimumPremium = td?.PrincipalRateWrite;
responEodPosition.daysInYear = item.InitialSpotPrice;//?
responEodPosition.initialPricingValue = item.TradeSinglePrice;
responEodPosition.initialUnderlyerPrice = td?.UnderlyingPrice;
responEodPosition.portfolioNames = item.TradeType;
responEodPosition.trader = td?.TraderName;
responEodPosition.tradeConfirmId = item.ContractCode;
responEodPosition.underlyerPrice = item.UnderlyingPrice;
responEodPosition.callput = item.trade?.CallPut;
responEodPositions.Add(responEodPosition);
}
var buffer = ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list2 = responEodPositions }).GenerateBytes();
return buffer;
}
}
/// <summary>
/// 获取开仓无风险利率
/// </summary>
public double? GetinitialQ(int tdId, DateTime dateTime)
{
return DbContext.TradeHisData.Where(l => l.TradeId == tdId && l.ValueDate == dateTime && l.ValueType == "NoRiskRate").FirstOrDefault()?.Value;
}
/// <summary>
/// 获取开仓分红率
/// </summary>
public double? GetinitialR(int tdId, DateTime dateTime)
{
return DbContext.TradeHisData.Where(l => l.TradeId == tdId && l.ValueDate == dateTime && l.ValueType == "DividendRate").FirstOrDefault()?.Value;
}
/// <summary>
/// 获取 合约乘数
/// </summary>
/// <param name="UnderlyingCode"></param>
/// <returns></returns>
public double? GetunderlyerMultiplier(string UnderlyingCode)
{
var underlyerMultiplier = DataCacheProvider.GetUnderlyingDataSource().GetData(UnderlyingCode).ContractSize;
return underlyerMultiplier;
}
/// <summary>
/// 获取sac主协议编号
/// </summary>
/// <param name="ClientNumber"></param>
/// <returns></returns>
public string GetmasterAgreement(string ClientNumber)
{
var clientdb = new ClientDBContext();
if (string.IsNullOrEmpty(ClientNumber))
{
return "";
}
return clientdb.client.First(l => l.Number == ClientNumber).MainProtocolCode;
}
// {{item.positionId}} {{item.underlyerInstrumentId}} {{item.underlyerInstrumentIds}} {{item.underlyerMultiplier}} {{item.underlyerMultipliers}}
// {{item.productType}} {{item.initialNumber}} {{item.initialNumbers}} {{item.unwindNumber}} {{item.unwindNumbers}} {{item.number}} {{item.numbers}}
// {{item.premium}} {{item.unwindAmount}} {{item.marketValue}} {{item.pnl}} {{item.delta}} {{item.deltas}} {{item.deltaCash}} {{item.deltaCashes}}
// {{item.deltaDecay}} {{item.deltaDecays}} {{item.deltaWithDecay}} {{item.deltaWithDecays}} {{item.gamma}} {{item.gammas}} {{item.gammaCash}}
// {{item.gammaCashes}} {{item.vega}} {{item.vegas}} {{item.theta}} {{item.rho}} {{item.tradeDate}} {{item.effectiveDate}} {{item.expirationDate}}
// {{item.message}} {{item.createdAt}} {{item.pricingEnvironment}} {{item.r}} {{item.q}} {{item.qs}} {{item.vol}} {{item.vols}} {{item.listedOption}}
// {{item.price}} {{item.correlation}} {{item.notional}} {{item.initialNotional}} {{item.initialMargin}} {{item.initialQ}} {{item.initialR}} {{item.initialVol}}
// {{item.maintenanceMargin}} {{item.masterAgreementId}} {{item.direction}} {{item.term}} {{item.settlementDate}} {{item.tradeStatus}} {{item.lcmEventType}}
// {{item.initialSpot}} {{item.initialSpots}} {{item.highStrike}} {{item.lowStrike}} {{item.highBarrier}} {{item.lowBarrier}} {{item.participationRates}}
// {{item.rebate}} {{item.annualized}} {{item.specifiedPrice}} {{item.frontPremium}} {{item.minimumPremium}} {{item.daysInYear}} {{item.initialPricingValue}}
// {{item.initialUnderlyerPrice}} {{item.initialPnl}} {{item.initialStdDelta}} {{item.initialDelta}} {{item.initialDeltaCash}} {{item.initialGamma}} {{item.initialGammaCash}} {{item.initialVega}} {{item.initialTheta}} {{item.initialRhoR}} {{item.initialStdGamma}} {{item.tradeCategory}} {{item.portfolioNames}} {{item.trader}} {{item.tradeConfirmId}} {{item.regulationAssetClass}} {{item.regulationAssetSubClass}} {{item.underlyerPrice}}
class ResponEodPosition
{
public string bookName { get; set; }
public string tradeId { get; set; }
public int? positionId { get; set; }
public string underlyerInstrumentId { get; set; }
public string underlyerInstrumentIds { get; set; }
public double? underlyerMultiplier { get; set; }
public string underlyerMultipliers { get; set; }
public string productType { get; set; }
public double? initialNumber { get; set; }
public double? initialNumbers { get; set; }
public double? unwindNumber { get; set; }
public double? unwindNumbers { get; set; }
public double? number { get; set; }
public double? numbers { get; set; }
public double? premium { get; set; }
public double? unwindAmount { get; set; }
public double? marketValue { get; set; }
public double? pnl { get; set; }
public double? delta { get; set; }
public double? deltas { get; set; }
public double? deltaCash { get; set; }
public double? deltaCashes { get; set; }
public double? deltaDecay { get; set; }
public double? deltaDecays { get; set; }
public double? deltaWithDecay { get; set; }
public double? deltaWithDecays { get; set; }
public double? gamma { get; set; }
public double? gammas { get; set; }
public double? gammaCash { get; set; }
public double? gammaCashes { get; set; }
public double? vega { get; set; }
public double? vegas { get; set; }
public double? theta { get; set; }
public double? rho { get; set; }
public string tradeDate { get; set; }
public DateTime? effectiveDate { get; set; }
public DateTime? expirationDate { get; set; }
public string message { get; set; }
public string createdAt { get; set; }
public string pricingEnvironment { get; set; }
public double? r { get; set; }
public double? q { get; set; }
public double? qs { get; set; }
public double? vol { get; set; }
public double? vols { get; set; }
public double? listedOption { get; set; }
public double? price { get; set; }
public double? correlation { get; set; }
public double? notional { get; set; }
public double? initialNotional { get; set; }
public double? initialMargin { get; set; }
public double? initialQ { get; set; }
public double? initialR { get; set; }
public double? initialVol { get; set; }
public double? maintenanceMargin { get; set; }
public string masterAgreementId { get; set; }
public string direction { get; set; }
public int term { get; set; }
public DateTime? settlementDate { get; set; }
public string tradeStatus { get; set; }
public string lcmEventType { get; set; }
public double? initialSpot { get; set; }
public double? initialSpots { get; set; }
public double? highStrike { get; set; }
public double? lowStrike { get; set; }
public double? highBarrier { get; set; }
public double? lowBarrier { get; set; }
public double? participationRates { get; set; }
public double? rebate { get; set; }
public bool? annualized { get; set; }
public string specifiedPrice { get; set; }
public double? frontPremium { get; set; }
public double? minimumPremium { get; set; }
public double? daysInYear { get; set; }
public double? initialPricingValue { get; set; }
public double? initialUnderlyerPrice { get; set; }
public double? initialPnl { get; set; }
public double? initialStdDelta { get; set; }
public double? initialDelta { get; set; }
public double? initialDeltaCash { get; set; }
public double? initialGamma { get; set; }
public double? initialGammaCash { get; set; }
public double? initialVega { get; set; }
public double? initialTheta { get; set; }
public double? initialRhoR { get; set; }
public double? initialStdGamma { get; set; }
public double? tradeCategory { get; set; }
public string portfolioNames { get; set; }
public string trader { get; set; }
public string tradeConfirmId { get; set; }
public string regulationAssetClass { get; set; }
public string regulationAssetSubClass { get; set; }
public double? underlyerPrice { get; set; }
public string callput { get; set; }
}
class ClientInfo
{
/// <summary>
/// 客户类型
/// </summary>
public string ClientType { get; set; }
/// <summary>
/// 客户名称
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// 客户类型备注 机构全称,产品全称,居民身份证
/// </summary>
public string ClientTypeMemo { get; set; }
/// <summary>
/// 证件类型
/// </summary>
public string LicenseType { get; set; }
/// <summary>
/// 证件号
/// </summary>
public string IdentificationNumber { get; set; }
/// <summary>
/// 产品管理人
/// </summary>
public string AdminFullName { get; set; }
/// <summary>
/// 主协议编号
/// </summary>
public string MainProtocolCode { get; set; }
/// <summary>
/// 证件类型备注 产品管理人全称
/// </summary>
public string AdminFullNameMome { get; set; }
/// <summary>
/// 产品管理人证件类型
/// </summary>
public string AdminFullNameLicenseType { get; set; }
/// <summary>
/// 产品管理人证件号
/// </summary>
public string AdminRegisteredNum { get; set; }
}
class InnerClientInfo
{
internal int id { get; set; }
public string ClientNumber { get; set; }
public string ClientName { get; set; }
public string LicenseCode { get; set; }
public string ClientType { get; set; }
public string StockEqvNotional { get; set; }
}
}
}