从山证v2.3.0拷贝

This commit is contained in:
吴方海
2024-05-09 14:06:26 +08:00
parent 566ff33259
commit f9d8a256a6
4471 changed files with 1203456 additions and 9 deletions
@@ -0,0 +1,29 @@
using System.Linq.Expressions;
namespace YLErp.Modules.TradeModule.QueryModule
{
public class BatchGetTradeRelationDataService<T> where T : DBModelBase
{
public List<T> GetListByWhere(Expression<Func<T, bool>> expression, DbSet<T> dataSet, int batchSize = 500)
{
var result = new List<T>();
var newExpression = expression;
while (true)
{
var list = dataSet.AsNoTracking().Where(newExpression).OrderBy(p => p.id).Take(batchSize).ToList();
if (list != null && list.Count > 0)
{
result.AddRange(list);
}
if (list == null || list.Count < batchSize)
{
break;
}
var maxId = list.Max(p => p.id);
newExpression = expression.And(p => p.id > maxId);
}
return result;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
namespace YLErp.Modules.TradeModule.QueryModule.Dto
{
/// <summary>
/// 交易数据传输对象,用于今日到期 交易查询效率优化
/// </summary>
public class TradeQueryDto
{
public int id { get; set; }
public double? TradePrice { get; set; }
public string BuySell { get; set; }
public int ParentTradeId { get; set; }
public string ValidState { get; set; }
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,72 @@
namespace YLErp.Modules.TradeModule.QueryModule
{
public class TradeCloseInfoQueryApiService : YLBaseService
{
public TradeCloseInfoQueryApiService(OptUserInfo userInfo) : base(userInfo)
{
}
public IEnumerable<OtcTradeDetail> GetTradeCloseInfoList(TradeCloseInfoRequestModel req)
{
int[] clientIds = null;
using (var clientDB = DbContextFactory.GetClientDbContext(OptUser))
{
if (!string.IsNullOrEmpty(req.ClientNumber))
{
clientIds = clientDB.client.Where(n => n.Number == req.ClientNumber).Select(n => n.id).ToArray();
}
else if (!string.IsNullOrEmpty(req.ClientName))
{
clientIds = clientDB.client.Where(n => n.Name == req.ClientName).Select(n => n.id).ToArray();
}
if (clientIds != null && !clientIds.Any())
{
return Enumerable.Empty<OtcTradeDetail>();
}
}
var tdPredicate = PredicateBuilder.Create<trade>(t => t.ValidState != ConsGlobal.InValid);
if (clientIds != null)
{
tdPredicate = tdPredicate.And(t => clientIds.Contains(t.ClientId));
}
var tcActions = new[] { ClientCashInCashOut._平仓费, ClientCashInCashOut._行权费 };
var query = from tc in DbContext.trade_cash.AsNoTracking()
join td in DbContext.trade.AsNoTracking().Where(tdPredicate) on tc.TradeId equals td.id
join et in DbContext.eod_trade.Where(O => O.ValueDate == req.ValueDate) on td.id equals et.TradeId into tempEt
from et in tempEt.DefaultIfEmpty()
where tc.ValidState != ConsGlobal.InValid && tc.ValueDate == req.ValueDate && tcActions.Contains(tc.Action)
select new
{
et,
trade = td,
detail = new OtcTradeDetail
{
TcId = tc.id,
TcValueDate = tc.HappenedDate != null ? tc.HappenedDate : tc.ValueDate,
TcFinalPrice = tc.FinalPrice,
TcUnwindPrice = tc.UnwindPrice,
TcUnwindPricePercent = tc.UnwindPricePercentRate,
TcAmount = tc.Amount,
UnWindNotional = tc.UnwindNotional ?? tc.Notional,
TcUnwindTradeAmount = tc.UnwindTradeAmount,
TcUnwindPercent = tc.UnwindPercentRate,
TcAction = tc.Action,
TcExerciseWay = tc.ExerciseWay,
}
};
var list = query.ToList();
return list.Select(n =>
{
YLAutoMapper.Map(n.et?.trade ?? n.trade, n.detail);
return n.detail;
}).ToList();
}
}
}
@@ -0,0 +1,420 @@
using BaseOUDAL;
using System.Linq.Expressions;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeModule.QueryModule
{
public class TradeCreditRiskQueryService : YLBaseService
{
public TradeCreditRiskQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
public TradeCreditRiskQueryService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
/// 查询客户交易明细
/// </summary>
public SearchListResult<TradeCreditRisk> SearchTradeCreditRisk(TradeCreditRiskReq req)
{
BuildTradePredicate(req, out var tradPredicate);
DateTime tradingday = QdpCalendarHelper.GetNonHolidayDefore(req.EndDate.Value);
DateTime lastdate = req.EndDate.Value.AddDays(1 - req.EndDate.Value.Day).AddMonths(1).AddDays(-1);
DateTime lastdatetrading = QdpCalendarHelper.GetNonHolidayDefore(lastdate);
if (tradingday != lastdatetrading)
{
lastdatetrading = QdpCalendarHelper.GetNonHolidayDefore(lastdate.AddDays(1 - lastdate.Day).AddDays(-1));
}
var query = from td in DbContext.trade.Where(tradPredicate)
join et in DbContext.eod_trade.Where(O => O.ValueDate == req.EndDate.Value) on td.id equals et.TradeId into tempEt
from et in tempEt.DefaultIfEmpty()
join etp in DbContext.eod_trade_position.Where(O => O.ValueDate == lastdate) on td.id equals etp.TradeId into tempEtp
from etp in tempEtp.DefaultIfEmpty()
where et != null
select new TradeCreditRisk
{
id = td.id,
TradeNumber = td.TradeNumber,
tradecode = "",
ClientId = td.ClientId,
BuySell = td.BuySell,
OptionType = td.OptionType,
StructureType = td.StructureType,
TradeType = td.TradeType,
TradeDate = td.TradeDate,
ExerciseDate = td.ExerciseDate,
SettlementDate = td.SettlementDate,
PremiumPayDate = td.PremiumPayDate,
Strike = td.Strike,
UnderlyingCode = td.UnderlyingCode,
BasisUnderlyingCode = td.BasisUnderlyingCode,
StockEqvNotional = td.StockEqvNotional,
StockEqvNotionalMax = td.StockEqvNotionalMax,
OriginalStockEqvNotional = td.OriginalStockEqvNotional,
TradePrice = td.TradePrice,
InitialMargin = td.TradePrice,
Notional = td.Notional,
tradevalue = etp == null ? 0 : etp.Pv,
et = et,
};
if (string.IsNullOrWhiteSpace(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
var list = query.ToSearchList(req);
var clients = DataCacheProvider.GetClientDataSource().AsQueryable();
var underly = DataCacheProvider.GetUnderlyingDataSource().AsQueryable();
var varietys = DataCacheProvider.GetVarietyDataSource().AsQueryable();
var markets = DataCacheProvider.GetMarketDataSource().AsQueryable();
foreach (var item in list.rows)
{
if (item.et != null)
{
item.Strike = item.et.trade.Strike;
item.UnderlyingCode = item.et.trade.UnderlyingCode;
item.BasisUnderlyingCode = item.et.trade.BasisUnderlyingCode;
item.StockEqvNotional = item.et.trade.StockEqvNotional;
item.StockEqvNotionalMax = item.et.trade.StockEqvNotionalMax;
item.OriginalStockEqvNotional = item.et.trade.OriginalStockEqvNotional;
item.TradePrice = item.et.trade.TradePrice;
item.InitialMargin = item.et.trade.InitialMargin;
item.Notional = item.et.trade.Notional;
}
var client = clients.FirstOrDefault(x => x.id == item.ClientId);
item.ClientName = client.Name;
item.ClientNumber = client.Number;
item.MainProtocolCode = client.MainProtocolCode;
item.LicenseType = client.LicenseType;
item.LicenseCode = client.LicenseCode;
item.buysell_show = item.BuySell == "买入" ? "B" : "S";
item.CallorPut = item.OptionType == "看涨" ? "Call" : "Put";
item.multishort = item.OptionType == "看涨" ? "多头" : "空头";
item.tradetype_show = item.StructureType ?? item.TradeType;
var un = underly.FirstOrDefault(x => x.UnderlyingCode == item.UnderlyingCode);
var va = un == null ? null : varietys.FirstOrDefault(x => x.id == un.UnderlyingTypeId);
var ma = un == null ? null : markets.FirstOrDefault(x => x.ExchangeNo == un.MarketCode);
item.UnderlyingAssetName = un?.UnderlyingName;
item.QuoteCurrency = va?.QuoteCurrency ?? "CNY";
item.UnderlyingAssetName = un?.UnderlyingName;
item.MarketName = ma?.MarketName;
if (item.et != null)
{
var eodpostion = DbContext.eod_trade_position.FirstOrDefault(O => O.ValueDate == req.EndDate && O.TradeId == item.et.TradeId);
item.pv = eodpostion?.Pv;
item.valuedate = eodpostion?.ValueDate;
}
if (item.TradeType == "远期")
{
var lasteodpostion = DbContext.eod_trade_position.FirstOrDefault(O => O.ValueDate == lastdatetrading && O.TradeId == item.et.TradeId);
item.tradevalue = lasteodpostion?.Pv;
item.producttype = string.IsNullOrWhiteSpace(item.BasisUnderlyingCode) ? "商品远期" : "商品互换";
}
else if (item.TradeType == "收益互换")
{
var swap = DbContext.trade_swap.FirstOrDefault(O => O.TradeId == item.id && O.TradeId == item.et.TradeId);
item.payfloattype = swap.IsPayFloatingProfit == true ? "2:支付浮动" : "1:支付固定";
item.producttype = "收益互换";
if (swap.IsPayFloatingProfit)
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(swap.GetSwapTimeAndRate);
if (customizedResults.Item1 == null)
{
item.SwapTime = null;
}
else
{
item.SwapTime = customizedResults.Item1[0];
}
item.Strike = swap.PaySpotPrice + (swap.PayLongShort == "多头" ? 1 : -1) * ((swap.GetSingleFee ?? 0) / un.ContractSize + (swap.PaySpotPrice * swap.GetUnAnnualRate ?? 0));
}
else
{
var customizedResults = QdpHelper.ParseAutocallCustomizedInfo(swap.PaySwapTimeAndRate);
if (customizedResults.Item1 == null)
{
item.SwapTime = null;
}
else
{
item.SwapTime = customizedResults.Item1[0];
}
item.Strike = swap.GetSpotPrice + (swap.GetLongShort == "多头" ? 1 : -1) * ((swap.PaySingleFee ?? 0) / un.ContractSize + (swap.GetSpotPrice * swap.PayUnAnnualRate ?? 0));
}
}
else
{
item.producttype = un == null ? "商品期货" : un.IsCommoditySpot() ? "商品现货" : "商品期货";
if(item.et != null && item.et.trade.IsGroup ==1)
{
if (double.TryParse(item.et.trade.Propertys?.Where(x => x.name == "行权价格").FirstOrDefault()?.value ?? "", out double strike))
{
item.Strike = strike;
}
if (DateTime.TryParse(item.et.trade.Propertys?.Where(x => x.name == "期权费支付日").FirstOrDefault()?.value ?? "", out DateTime premiumPayDate))
{
item.PremiumPayDate = premiumPayDate;
}
else
{
item.PremiumPayDate = item.TradeDate;
}
var callorPut = item.et.trade.Propertys?.Where(x => x.name == "期权方向").FirstOrDefault()?.value ?? "";
item.CallorPut = callorPut == "看涨" ? "Call" : "Put";
item.multishort = callorPut == "看涨" ? "多头" : "空头";
var subid = DbContext.trade.Where(x => x.ParentTradeId == item.et.TradeId && x.ValidState != "InValid" && x.IsGroup == 2).Select(x => x.id).ToArray();
var subpv = DbContext.eod_trade_position.Where(O => O.ValueDate == req.EndDate && subid.Contains(O.TradeId)).Sum(x => x.Pv);
item.pv = subpv;
item.valuedate = req.EndDate;
}
}
}
return list;
}
private void BuildTradePredicate(TradeCreditRiskReq req,
out Expression<Func<trade, bool>> tradPredicate)
{
//交易明细页面:组合互换 提前终止和到期都按照子交易展示
if (req.CreditRiskType == "期权")
{
tradPredicate = PredicateBuilder.True<trade>().And(x => x.TradeType != "远期" && x.TradeType != "收益互换");
}
//交易明细页面:组合互换 成交按照主交易可展开形式展示
else if (req.CreditRiskType == "远期")
{
tradPredicate = PredicateBuilder.True<trade>().And(x => x.TradeType == "远期");
}
//交易明细导出:组合互换都按照子交易展示
else if (req.CreditRiskType == "互换")
{
tradPredicate = PredicateBuilder.True<trade>().And(x => x.TradeType == "收益互换");
}
else
{
tradPredicate = PredicateBuilder.True<trade>();
}
var endDate = req.EndDate.Value;
tradPredicate = tradPredicate.And(t => t.TradeDate <= endDate && t.ValidState != "InValid" && (t.TradeType != "结构化交易" || t.IsGroup == 1) && t.IsGroup != 2);
if (req.StartDate != null)
{
tradPredicate = tradPredicate.And(t => t.TradeDate >= req.StartDate);
}
if (!string.IsNullOrWhiteSpace(req.ClientIds))
{
if (req.ClientIds.Substring(0, 1) != ",")
{
tradPredicate = tradPredicate.And(t => req.ClientIdsInt.Contains(t.ClientId));
}
}
}
}
/// <summary>
/// 交易查熏
/// </summary>
public class TradeCreditRiskReq : BaseSearchReq
{
/// <summary>
/// 客户ID列表
/// </summary>
public string ClientIds { get; set; }
public List<int> ClientIdsInt
{
get
{
if (string.IsNullOrEmpty(ClientIds))
{
return new List<int>();
}
return (ClientIds + "").Split(',').Select(c => Convert.ToInt32(c)).ToList();
}
}
/// <summary>
/// 开始日期
/// </summary>
public DateTime? StartDate { get; set; }
/// <summary>
/// 结束日期
/// </summary>
public DateTime? EndDate { get; set; }
/// <summary>
/// 类型
/// </summary>
public string CreditRiskType { get; set; }
}
public class TradeCreditRisk : OtcTradeDto
{
/// <summary>
/// client
/// </summary>
public string MainProtocolCode { get; set; }
public string ClientNumber { get; set; }
public string LicenseType { get; set; }
public string LicenseCode { get; set; }
/// <summary>
/// trade
/// </summary>
public string buysell_show { get; set; }
public string CallorPut { get; set; }
public string multishort { get; set; }
public string tradetype_show { get; set; }
public string accountCode
{
get
{
return "HAZB0001";
}
}
public string accountName
{
get
{
return "华安资本账户0001";
}
}
//public string financeCode = "自定义";
//public string financeName = "标的合约代码";
public string producttype { get; set; }
/// <summary>
/// SPT_CMDT(商品现货)、FUT_CMDT(商品期货)、SWP_S(收益互换)、SWP_CMDT(商品互换)、FWD_FUT_CMDT(商品远期)、OPT_FUT_CMDT(场内期权)
/// </summary>
public string assetstype
{
get
{
if (producttype == "商品现货")
{
return "SPT_CMDT";
}
else if (producttype == "商品期货")
{
return "FUT_CMDT";
}
else if (producttype == "收益互换")
{
return "SWP_S";
}
else if (producttype == "商品互换")
{
return "SWP_CMDT";
}
else if (producttype == "商品远期")
{
return "FWD_FUT_CMDT";
}
else if (producttype == "商品远期")
{
return "OPT_FUT_CMDT";
}
else
{
return "";
}
}
}
public string MarketName { get; set; }
/// <summary>
/// 商品现货:大连商品交易所(XDCE),上海期货交易所(XSGE),郑州商品交易所(XZCE) 金交所(SGEX)
/// 商品远期:NONE、收益互换:NONE、场外期权:NONE
/// 商品期货:深交所(XSHE),上交所(XSHG)
/// </summary>
public string markettype
{
get
{
if (producttype == "商品现货")
{
if (MarketName == "大连商品交易所")
{
return "XDCE";
}
else if (MarketName == "上海期货交易所")
{
return "XSGE";
}
else if (MarketName == "郑州商品交易所")
{
return "XZCE";
}
else if (MarketName == "金融资产交易所")
{
return "SGEX";
}
}
else if (producttype == "商品期货")
{
if (MarketName == "上海证券交易所")
{
return "XSHE";
}
else if (MarketName == "深圳证券交易所")
{
return "XSHG";
}
}
return "NONE";
}
}
/// <summary>
/// 远期
/// </summary>
public double? pv { get; set; }
public double? pnl { get; set; }
public DateTime? valuedate { get; set; }
/// <summary>
/// 互换
/// </summary>
public string payfloattype { get; set; }
public DateTime? SwapTime { get; set; }
public string tradecode { get; set; }
public double? tradevalue { get; set; }
public eod_trade et { get; set; }
/// <summary>
/// 抵押品
/// </summary>
public string productCode { get; set; }
public string productName { get; set; }
public string productMaketName { get; set; }
public string productMaketType { get; set; }
}
}
@@ -0,0 +1,233 @@
using System.Data;
using System.Linq.Expressions;
using YLErp.Modules.TradeModule.BaseModels;
namespace YLErp.Modules.TradeModule.QueryModule
{
/// <summary>
/// OTC-13931 交易明细API业务代码
/// </summary>
public class TradeDetailQueryApiService : YLBaseService
{
public TradeDetailQueryApiService(OptUserInfo userInfo) : base(userInfo)
{
}
public TradeDetailQueryApiService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
///
/// </summary>
public IPagedList<TradeDetailQueryApiResult> TradeDetailPageList(TradeDetailQueryApiModel queryModel)
{
var predicate = CreateTradePredicate(queryModel);
var pagedList = DbContext.trade.Where(predicate).ToPagedList(queryModel);
var tradeIds = pagedList.Select(x => x.id).ToList();
var trade_cashlist = DbContext.trade_cash.Where(x => x.ValidState != ConsGlobal.InValid && tradeIds.Contains(x.TradeId) && !x.IsDeleted).ToList();
var tradeList = pagedList.Select(n =>
{
var otcTrade = new TradeDetailQueryApiResult();
YLAutoMapper.Map<OtcTradeBase, OtcTradeBase>(n, otcTrade);
otcTrade.RealizedPnl = trade_cashlist?.Where(x => x.TradeId == n.id).Sum(x => x.Amount);
otcTrade.ClientNumber = ClientModule.ClientDataQueryService.GetClient(otcTrade.ClientId)?.Number;
return otcTrade;
}).ToArray();
var pagedList2 = new PagedList<TradeDetailQueryApiResult>
{
PageSize = pagedList.PageSize,
PageIndex = pagedList.PageIndex,
Items = tradeList,
TotalCount = pagedList.TotalCount
};
new TradeExtendService(this).SetTradeExtend(pagedList2, true);
return pagedList2;
}
/// <summary>
/// 根据查询参数拼接查询条件
/// </summary>
protected Expression<Func<trade, bool>> CreateTradePredicate(TradeDetailQueryApiModel queryModel)
{
var predicate = PredicateBuilder.Create<trade>(t => t.ValidState != ConsGlobal.InValid);
if (queryModel.IncludeGroupMain)
{
predicate = predicate.And(n => n.TradeType != "结构化交易" || n.IsGroup == 1);
}
else
{
predicate = predicate.And(n => n.TradeType != "结构化交易");
}
// 交易类型
if (queryModel.TradeTypes.HasNonEmptyItem())
{
predicate = predicate.And(d => queryModel.TradeTypes.Contains(d.TradeType));
}
// 簿记账户名称
var assetIds = GetAssetIds(queryModel.AssetBookNames);
if (assetIds != null)
{
predicate = predicate.And(d => assetIds.Contains(d.AssetId));
}
//交易员名称( 使用参数),不使用登录名进行匹配
var traderIds = GetTraderId(queryModel.TraderNames);
if (traderIds != null)
{
predicate = predicate.And(d => traderIds.Contains(d.TraderId));
}
//客户 优先使用客户编号
var clientIds = GetClientIdsByNumber(queryModel.ClientNumbers)
?? GetClientIdsByName(queryModel.ClientNames);
if (clientIds != null)
{
predicate = predicate.And(d => clientIds.Contains(d.ClientId));
}
//交易编号
if (!string.IsNullOrEmpty(queryModel.TradeNumber))
{
//第2个条件的适用场景为传入了结构化交易主交易的交易编号则匹配出来子交易
predicate = predicate.And(d => d.TradeNumber.Equals(queryModel.TradeNumber) ||
DbContext.trade.Any(n => n.TradeNumber.Equals(queryModel.TradeNumber) && n.id == d.ParentTradeId));
}
//交易标的代码
if (queryModel.UnderlyingCodes.HasNonEmptyItem())
{
predicate = predicate.And(d => queryModel.UnderlyingCodes.Contains(d.UnderlyingCode));
}
//交易方向: 买入|卖出
if (!string.IsNullOrEmpty(queryModel.BuySell))
{
predicate = predicate.And(d => d.BuySell == queryModel.BuySell);
}
//看涨看跌: Call|Put
if (!string.IsNullOrEmpty(queryModel.OptionType))
{
var optionType = ConsGlobal.CallPut.ConvertToCN(queryModel.OptionType);
predicate = predicate.And(d => d.OptionType == optionType);
}
//行权方式:American|European
if (!string.IsNullOrEmpty(queryModel.ExerciseMode))
{
predicate = predicate.And(d => d.ExerciseMode == queryModel.ExerciseMode);
}
//成交日期
if (queryModel.TradeDate.HasValue)
{
predicate = predicate.And(d => d.TradeDate == queryModel.TradeDate);
}
//到期日期
if (queryModel.ExerciseDate.HasValue)
{
predicate = predicate.And(d => d.ExerciseDate == queryModel.ExerciseDate);
}
//结算日期
if (queryModel.SettlementDate.HasValue)
{
predicate = predicate.And(d => d.SettlementDate == queryModel.SettlementDate);
}
//交易状态:确认成交、新增待确认、已平仓、已到期。。。等等
if (queryModel.TradeStatus != null && queryModel.TradeStatus.Any())
{
predicate = predicate.And(d => queryModel.TradeStatus.Contains(d.TradeStatus));
}
return predicate;
}
#region id再构建查询条件
/// <summary>
/// 获取簿记账户id
/// </summary>
private List<int> GetAssetIds(IEnumerable<string> AssetBookName)
{
if (!AssetBookName.HasNonEmptyItem())
{
return null;
}
return DbContext.assetunit.Where(x => AssetBookName.Contains(x.Name)).Select(x => x.id).ToList();
}
/// <summary>
/// 返回交易员ID
/// </summary>
private IEnumerable<int> GetTraderId(IEnumerable<string> traderNames)
{
if (!traderNames.HasNonEmptyItem())
{
return null;
}
using (var sysdb = DbContextFactory.GetErpBaseContext())
{
return sysdb.SystemUsers.Where(su => traderNames.Contains(su.LoginName)).Select(n => n.Id).ToArray();
}
}
/// <summary>
/// 根据交易对手方编号返回交易对手方ID
/// </summary>
/// <param name="clientNumbers">交易对手方编号</param>
private List<int> GetClientIdsByNumber(IEnumerable<string> clientNumbers)
{
if (!clientNumbers.HasNonEmptyItem())
{
return null;
}
using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser))
{
return clientDbContext.client.Where(x => clientNumbers.Contains(x.Number)).Select(x => x.id).ToList();
}
}
/// <summary>
/// 根据客户名称返回客户ID
/// </summary>
private List<int> GetClientIdsByName(IEnumerable<string> clientNames)
{
if (!clientNames.HasNonEmptyItem())
{
return null;
}
using (var clientDbContext = DbContextFactory.GetClientDbContext(OptUser))
{
return clientDbContext.client.Where(x => clientNames.Contains(x.Name)).Select(x => x.id).ToList();
}
}
#endregion
}
/// <summary>
/// 交易明细API
/// </summary>
public class TradeDetailQueryApiResult : OtcOptionTradeFull
{
/// <summary>
/// 实现盈亏
/// </summary>
public double? RealizedPnl { get; set; }
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,451 @@
using BaseOUDAL;
using System.Data;
using YLErp.BLL.EodSettlement;
using YLErp.Commons;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.ClientModule;
namespace YLErp.Modules.TradeModule.QueryModule
{
/// <summary>
/// 历史交易查询服务(迁移自TradeBLL)
/// </summary>
public class TradeHistoryQueryService : YLBaseService
{
public TradeHistoryQueryService(YLBaseService baseService) : base(baseService)
{
}
public TradeHistoryQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 盯市报告历史交易总数
/// </summary>
public int SearchHistoryCount(TradeReq req)
{
return CreateTradeHistoryQuery(req).Count();
}
public List<trade_contract_group_simple> SearchHistoryListOnly(TradeReq req, bool isFromTradeMarketReport = false)
{
var query = CreateTradeHistoryQuery(req, isFromTradeMarketReport);
List<trade_contract_group_simple> retListResult = query.ToList();
retListResult.ForEach(x =>
{
var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1;
x.CountRatio = CountRatio;
if (x.trade_cash.IsLastAction)
{
if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1)
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
else if (x.trade.TradeType == "收益互换")
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
}
if (x.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
var tcTradeNotional = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
tcTradeNotional += y.UnwindNotional??0.0;
});
x.WinLoss = -(x.trade_cash.Amount + tcTradePrice);
x.trade_cash.UnwindNotional = tcTradeNotional;
}
if (x.TradeMultipleType == "现金流交易")
{
x.trade.OriginalNotional = null;
x.trade.TradeOriginalAmount = null;
x.trade_cash.TradeAmount = null;
x.trade_cash.UnwindTradeAmount = null;
}
});
return retListResult;
}
/// <summary>
/// 查询历史交易
/// </summary>
public SearchListResult<trade_contract_group_simple> SearchHistoryList(TradeReq req, out trade_contract_groupGridSum gsum)
{
var query = CreateTradeHistoryQuery(req);
var retListResult = query.ToSearchList(req, true);
var parentTradeIds = retListResult.rows.Select(x => x.trade.ParentTradeId).ToArray();
var parentTrades = DbContext.trade.Where(x => parentTradeIds.Contains(x.id)).ToArray();
foreach (var x in retListResult.rows)
{
//处理累计换月交易数据
new Modules.TradeModule.OptionTradeActionRestoreService(this.UserInfo).RestoreTradeDataToSpecialDay(x.trade, Convert.ToDateTime(req.ValueDateEnd));
var CountRatio = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.CountRatio ?? 1;
x.CountRatio = CountRatio;
if (!ConsTrade.TradeTypesForHedge.Contains(x.trade.TradeType))
{
x.trade.TradeOriginalAmount = x.trade.OriginalNotional / CountRatio;
}
//针对最后一次了结的记录,需要把存续的票息和互换金额算进最后一次的了结金额里
if (x.trade_cash.IsLastAction)
{
if (x.trade.TradeType == "凤凰期权" || x.trade.IsGroup == 1)
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-票息" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
else if (x.trade.TradeType == "收益互换")
{
var tradeCashs = DbContext.trade_cash.Where(y => y.ValidState != "InValid" && y.TradeId == x.trade_cash.TradeId && y.Action == "系统操作-互换" && y.id != x.trade_cash.id);
if (tradeCashs.Any())
{
x.trade_cash.Amount += tradeCashs.Sum(y => y.Amount);
}
}
}
if (x.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == x.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && x.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == x.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
});
x.WinLoss = -(x.trade_cash.Amount + tcTradePrice);
}
if (x.TradeMultipleType == "现金流交易")
{
x.trade.OriginalNotional = null;
x.trade.TradeOriginalAmount = null;
x.trade_cash.TradeAmount = null;
x.trade_cash.UnwindTradeAmount = null;
}
if (x.trade.IsGroup == 2 && x.trade.TradeType == "收益互换")
{
var parentTrade = parentTrades.FirstOrDefault(y => y.id == x.trade.ParentTradeId);
if (parentTrade != null)
{
x.trade.TradeNumber = parentTrade.TradeNumber;
}
}
if (PS.Config.ErpElement.IsSettlementReportAccOptionContainMultiplier && x.TradeType == "累计期权" && x.trade.trade_accumulator_option != null)
{
x.trade.trade_accumulator_option = DbContext.trade_accumulator_option.Where(l => l.TradeId == x.trade.id).FirstOrDefault();
// 累计了结时相应的乘数(标准累计:看涨乘数,看跌乘数;三段式:乘数1,乘数2,乘数3) 当乘数为0不处理
x.ACCMultiplier = ClientAssetDataService.GetTradeAccumulatorOptionMultiplier(x.trade, x.trade_cash.FinalPrice.Value, x.trade_cash.ValueDate);
}
x.trade.UnderlyingAssetName = x.trade.UnderlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(x.trade.UnderlyingCode)?.UnderlyingName;
x.trade.SettlementDate = x.trade.SettlementDate ?? x.trade.ExerciseDate;
}
gsum = new trade_contract_groupGridSum();
if (query.Any())
{
var queryList = query.ToList();
foreach (var item in queryList)
{
if (item.trade.IsGroup == 1)
{
//如果为最后一条了结记录,需要找到其存续时的票息相关记录,参与实现盈亏处理
var tradeCashCouponIds = DbContext.trade_cash.Where(y => y.TradeId == item.trade.id && y.Action == "系统操作-票息" && y.ValidState != "InValid" && !y.IsLastAction && item.trade_cash.IsLastAction).Select(y => y.id).ToArray();
var childTradeCashs = DbContext.trade_cash.Where(y => y.ParentTradeCashId == item.trade_cash.id || tradeCashCouponIds.Contains(y.ParentTradeCashId)).ToList();
var childTradeIds = childTradeCashs.Select(y => y.TradeId).Distinct().ToList();
var childTrades = DbContext.trade.Where(y => childTradeIds.Contains(y.id)).ToList();
var tcTradePrice = 0.0;
childTradeCashs.ForEach(y =>
{
var trade = childTrades.FirstOrDefault(z => z.id == y.TradeId);
tcTradePrice += (y.UnwindPercentRate * trade?.TradePrice * (trade?.BuySell == "买入" ? -1 : 1)) ?? 0;
});
item.WinLoss = -(item.trade_cash.Amount + tcTradePrice);
}
}
gsum.TradePriceSum =
queryList.Select(x =>
new
{
x.trade.id,
x.trade.TradePrice,
x.trade.BuySell,
x.trade.OptionType,
x.trade.TradeType
})
.Distinct().Sum(q =>
OtcFormatHelper.GetTradePriceDouble(q.TradePrice ?? 0) *
("卖出".Equals(q.BuySell) || q.TradeType == "远期" ? -1 : 1));
gsum.MinusAmountSum = queryList.Sum(q => -q.trade_cash.Amount).FormatValue(2);
gsum.StockEqvNotionalSum = queryList.Select(x => new { x.trade.id, x.trade.OriginalStockEqvNotional }).Distinct().Sum(q => Math.Round((q.OriginalStockEqvNotional ?? 0) * 100) / 100);
gsum.WinLossSum = queryList.Sum(n => n.WinLoss).FormatValue(2);
}
retListResult.Sum = gsum;
return retListResult;
}
private IQueryable<trade_contract_group_simple> CreateTradeHistoryQuery(TradeReq req, bool isFromTradeMarketReport = false)
{
var actionList = new[] { ClientCashInCashOut._行权费, ClientCashInCashOut._平仓费 };
var actionAllList = new[] { ClientCashInCashOut._行权费, ClientCashInCashOut._平仓费, ClientCashInCashOut._期权费 };
IQueryable<trade_contract_group_simple> query;
if (isFromTradeMarketReport && PS.Config.Is申万)
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionAllList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id
where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut._平仓费 ? tradeCash.UnwindVol : null
};
}
else if (!req.IsHistoryWithUnconfirmed)
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" && tradeObj.IsGroup != 1 || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 && tradeObj.TradeType == "收益互换") select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings
from underlyingInfo in underlyings.DefaultIfEmpty()
join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets
from asset in assets.DefaultIfEmpty()
where trade.ValidState != ConsGlobal.InValid && tradeCash.ValidState != ConsGlobal.InValid && !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut._平仓费 ? tradeCash.UnwindVol : null,
UserGroup = asset.UserGroup
};
DbContext.SetDebugLog();
}
else
{
query = from trade in from tradeObj in DbContext.trade where !ConsTrade.TradeTypesForHedge.Contains(tradeObj.TradeType) && (tradeObj.TradeType != "结构化交易" || tradeObj.IsGroup == 1 && tradeObj.TradeType == "结构化交易") && (tradeObj.IsGroup != 2 || tradeObj.IsGroup == 2 ) select tradeObj
join tradeCash in from tradeCash1 in DbContext.trade_cash where (actionList.Contains(tradeCash1.Action) || tradeCash1.IsLastAction) && !tradeCash1.IsDeleted select tradeCash1 on trade.id equals tradeCash.TradeId
join underlyingInfo in DbContext.underlying_manager on trade.UnderlyingId equals underlyingInfo.id into underlyings
from underlyingInfo in underlyings.DefaultIfEmpty()
join asset in DbContext.assetunit on trade.AssetId equals asset.id into assets
from asset in assets.DefaultIfEmpty()
where trade.ValidState != "InValid"
&& (tradeCash.ValidState != "InValid" || (trade.TradeStatus == "平仓待复核" && tradeCash.Action == ClientCashInCashOut._平仓费) || (trade.TradeStatus == "行权待复核" && tradeCash.Action == ClientCashInCashOut._行权费))
&& !tradeCash.IsDeleted
select new trade_contract_group_simple
{
id = tradeCash.id,
trade = trade,
ClientName = trade.ClientName,
trade_cash = tradeCash,
underlying_manager = underlyingInfo,
UnwindVol = tradeCash.Action == ClientCashInCashOut._平仓费 ? tradeCash.UnwindVol : null,
UserGroup = asset.UserGroup
};
}
//if (req.ClientId != null && !EodPnlBLL.IsBaseClient(req.ClientId.Value))
//{
//query = query.Where(d => d.trade.ClientId == req.ClientId);
//}
if (req.ClientId != null && req.ParentFlag)
{
var lists = ClientBalanceUtility.GetSubclientId(req.ClientId.Value);
query = query.Where(d => lists.Contains(d.trade.ClientId));
}
else if (req.ClientId != null && !req.ParentFlag)
{
query = query.Where(d => d.trade.ClientId == req.ClientId);
}
if (req.ValueDateStart.Year > 2000)
{
query = query.Where(d => d.trade_cash.ValueDate >= req.ValueDateStart && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate >= req.ValueDateStart);
}
if (req.ValueDateEnd.Year > 2000)
{
DateTime ValueDateTemp = req.ValueDateEnd.AddDays(1);
query = query.Where(d => d.trade_cash.ValueDate < ValueDateTemp && d.trade_cash.HappenedDate == null || d.trade_cash.HappenedDate < ValueDateTemp);
}
if (!string.IsNullOrEmpty(req.ClientIds))
{
query = query.Where(d => req.ClientIdsInt.Contains(d.trade.ClientId));
}
if (!string.IsNullOrEmpty(req.TradeTypes))
{
query = query.Where(d => req.TradeTypesList.Contains(d.trade.TradeType) || req.TradeTypesList.Contains(d.trade.StructureType));
}
if (req.NotInTradeTypes != null && req.NotInTradeTypes.Any())
{
query = query.Where(d => !req.NotInTradeTypes.Contains(d.trade.TradeType));
}
if (!string.IsNullOrEmpty(req.UnderlyingIds))
{
query = query.Where(d => req.UnderlyingIdsInt.Contains(d.trade.UnderlyingId));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
query = query.Where(d => d.trade.BuySell.Contains(req.BuySell));
}
if (!string.IsNullOrEmpty(req.OptionType))
{
query = query.Where(d => d.trade.OptionType == req.OptionType);
}
if (!string.IsNullOrEmpty(req.ExerciseMode))
{
query = query.Where(d => d.trade.ExerciseMode == req.ExerciseMode);
}
if (req.TradeDateStart.Year > 2000)
{
query = query.Where(d => d.trade.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd.Year > 2000)
{
DateTime TradeDateTemp = req.TradeDateEnd.AddDays(1);
query = query.Where(d => d.trade.TradeDate < TradeDateTemp);
}
if (req.TabIndex == (int)TradeTabIndexEnum.)
{
//已平仓,部分平仓,美式期权提前行权
if (req.IsHistoryWithUnconfirmed)
{
query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut._平仓费 ||
((d.trade.TradeStatus == ConsTrade. || d.trade.TradeStatus == ConsTrade.) && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权"));
}
else
{
query = query.Where(d => d.trade_cash.Action == ClientCashInCashOut._平仓费 ||
(d.trade.TradeStatus == ConsTrade. && d.trade.ExerciseMode == "American" && d.trade_cash.ExerciseWay != "到期行权"));
}
}
if (req.ExerciseDateStart != null || req.ExerciseDateEnd != null)
{
if (req.ExerciseDateEnd == null)
{
req.ExerciseDateEnd = DateTime.MaxValue;
}
if (req.ExerciseDateStart == null)
{
req.ExerciseDateStart = DateTime.MinValue;
}
//股票的到期日为null
query = query.Where(d => string.IsNullOrEmpty(d.trade.ExerciseMode) || d.trade.ExerciseDate == null ||
((d.trade.ExerciseMode == "European" && d.trade.ExerciseDate >= req.ExerciseDateStart &&
d.trade.ExerciseDate <= req.ExerciseDateEnd)
|| (d.trade.ExerciseMode == "American" &&
((d.trade.ExerciseDate >= req.ExerciseDateStart &&
d.trade.ExerciseDate <= req.ExerciseDateEnd)
|| (d.trade.StartDate >= req.ExerciseDateStart &&
d.trade.StartDate <= req.ExerciseDateEnd)
|| (d.trade.StartDate <= req.ExerciseDateStart &&
d.trade.ExerciseDate >= req.ExerciseDateEnd)
))
));
}
if (!string.IsNullOrEmpty(req.TradeStatus))
{
List<string> statuses = req.TradeStatus.Split(',').ToList();
query = query.Where(d => statuses.Contains(d.trade.TradeStatus));
}
if (req.TradeStatusList != null)
{
query = query.Where(d => req.TradeStatusList.Contains(d.trade.TradeStatus));
}
if (!string.IsNullOrEmpty(req.TraderNames))
{
query = query.Where(d => req.TraderNamesList.Contains(d.trade.TraderId));
}
if (req.AssetIdList.Any())
{
query = query.Where(d => req.AssetIdList.Contains(d.trade.AssetId));
}
if (string.IsNullOrEmpty(req.sidx))
{
query = query.OrderBy(n => n.trade.UnderlyingInstrumentType).ThenByDescending(s => s.trade_cash.id);
}
else if (req.sidx == "trade_cash.ValueDateString")
{
req.sidx = "trade_cash.ValueDate";
}
else
{
query = query.OrderBy(n => n.trade.UnderlyingInstrumentType);
}
return query;
}
}
}
@@ -0,0 +1,216 @@
using System.Data;
namespace YLErp.Modules.TradeModule
{
/// <summary>
/// 多次了结服务查询Model
/// </summary>
public class TradeMultiCloseQueryModel : PagedQueryModel
{
/// <summary>
/// 了结次数
/// </summary>
public int? UnWindTimes { get; set; }
public string TradeCashIds { get; set; }
public List<int> TradeCashIdList
{
get
{
if (string.IsNullOrEmpty(TradeCashIds))
{
return new List<int>();
}
return (TradeCashIds + "").Split(',').Select(c => Convert.ToInt32(c)).ToList();
}
}
/// <summary>
/// 买卖方向
/// </summary>
public string BuySell { get; set; }
/// <summary>
/// 了结方式
/// </summary>
public string UnWindType { get; set; }
public string TradeNumber { get; set; }
public string ClientIds { get; set; }
private List<int> _ClientIdList { get; set; }
public List<int> ClientIdList
{
get
{
if (_ClientIdList == null)
{
_ClientIdList = string.IsNullOrEmpty(ClientIds) ? new List<int>() : (ClientIds + "").Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(c => Convert.ToInt32(c)).ToList();
}
return _ClientIdList;
}
set
{
_ClientIdList = value;
}
}
public List<int> AssetUnitIds { get; set; }
public string UnderlyingIds { get; set; }
public IEnumerable<int> UnderlyingIdList
{
get
{
if (string.IsNullOrEmpty(UnderlyingIds))
{
return new List<int>();
}
return UnderlyingIds.Split(',').Select(c => Convert.ToInt32(c));
}
}
public DateTime? TradeDateStart { get; set; }
public DateTime? TradeDateEnd { get; set; }
public DateTime? ExerciseDateStart { get; set; }
public DateTime? ExerciseDateEnd { get; set; }
public DateTime? UnwindDateStart { get; set; }
public DateTime? UnwindDateEnd { get; set; }
public string ExerciseMode { get; set; }
public string TradeTypes { get; set; }
public string StructureType { get; set; }
public string TradeStatus { get; set; }
/// <summary>
/// 查询结果中是否要包含互换和远期
/// </summary>
public bool UseForwardASwap { get; set; }
public List<int> UserAssets { get; set; }
public List<int> UserClients { get; set; }
public int? LoginUserId { get; set; }
public List<int> CurUserTradeIds { get; set; }
string _AssetIds;
List<int> _AssetIdList;
private string _traderNames;
/// <summary>
/// 簿记账户筛选
/// </summary>
public string AssetIds
{
get
{
return _AssetIds;
}
set
{
_AssetIds = value; _AssetIdList = null;
}
}
/// <summary>
/// 簿记账户筛选
/// </summary>
public List<int> AssetIdList
{
get
{
if (_AssetIdList == null)
{
_AssetIdList = string.IsNullOrEmpty(AssetIds) ? new List<int>()
: (AssetIds + "").Split(',').Select(c => Convert.ToInt32(c)).ToList();
}
return _AssetIdList;
}
set
{
_AssetIdList = value;
}
}
/// <summary>
/// 簿记账户组筛选
/// </summary>
public List<int> AssetIdGroupList { get; set; }
/// <summary>
/// 其实是traderid
/// </summary>
public string TraderNames
{
get => _traderNames;
set
{
_traderNames = value;
_traderNamesList = null;
}
}
List<int> _traderNamesList;
public List<int> TraderNamesList
{
get
{
if (string.IsNullOrEmpty(TraderNames))
{
return new List<int>();
}
return _traderNamesList ?? (_traderNamesList = (TraderNames + "").Split(',').Select(t => Convert.ToInt32(t)).ToList());
}
set
{
_traderNamesList = value;
}
}
public string UnderlyingName { get; set; }
/// <summary>
/// 所选标签Id
/// </summary>
public List<int> TagIds { get; set; }
/// <summary>
/// 排序字段名称
/// </summary>
public string sidx { get; set; }
/// <summary>
/// 排序规则 asc or desc
/// </summary>
public string sord { get; set; }
/// <summary>
/// pageindex 页数
/// </summary>
public int page { get; set; }
/// <summary>
/// pagesize 行数
/// </summary>
public int rows { get; set; }
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,733 @@
using BaseOUDAL;
using System.Text.RegularExpressions;
using YieldChain.Helpers;
using YLErp.Enums;
using YLErp.Helpers;
using YLErp.Modules.DataCacheModule;
using YLErp.MsOffice;
using YLErp.Office;
using YLErp.Office.Converters;
namespace YLErp.Modules.TradeModule.QueryModule
{
public class TradeSwapDetailsQueryService : YLBaseService
{
public TradeSwapDetailsQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
public TradeSwapDetailsQueryService(YLBaseService baseService) : base(baseService)
{
}
public TradeSwapDetailsReport TradeSwapDetailsReport { private set; get; }
public string ExportReport(TradeDetailsReq req, string biaoTou = null, string biaoWei = null)
{
var client = DataCacheProvider.GetClientDataSource().GetData(req.ClientId != 0 ? req.ClientId : req.ClientIdsInt[0]);
if (client == null)
{
throw new ServiceException("系统中没有此客户,clientId:" + req.ClientId);
}
var resultList = SearchFlowMoreDetails(req);
return ConfirmDanzhang(resultList, client, req, biaoTou, biaoWei);
}
private string ConfirmDanzhang(SearchListResult<TradeFlowMoreDetails> resultList, Client client, TradeDetailsReq req, string biaoTou = null, string biaoWei = null)
{
if (!resultList.rows.Any())
{
throw new ServiceException(client.Name + "没有交易明细");
}
var report = new TradeSwapDetailsReport();
report.TradeFlowListAll = resultList.rows.ToList();
report.TradeFlowListSum = (TradeFlowMoreSum)resultList.Sum;
report.ClientId = client.id;
report.ClientName = string.IsNullOrEmpty(client.Abbreviation) ? client.Name : client.Abbreviation;
report.ClientFullName = client.Name;
report.ClientNumber = client.Number;
report.ClientAbbreviation = client.Abbreviation;
report.CompanyName = PS.Config.CompanyFullName;
report.ReportStart = req.StartDate == null ? DateTime.MinValue : req.StartDate.Value;
report.ReportEnd = req.EndDate.Value;
// 主 客户编号+A; 补充 客户编号+B;履约 客户编号+D; 主确认书:客户编号 + W
report.ClientNumberA = client.Number + "A";
report.ClientNumberB = client.Number + "B";
report.ClientNumberD = client.Number + "D";
report.ClientNumberW = client.Number + "W";
var startDate = report.ReportStart;
if (startDate == DateTime.MinValue)
{
report.TradeDetailsCode = client.Number + "_" + report.ReportEnd.ToString("yyyyMMdd");
}
else
{
report.TradeDetailsCode = client.Number + "_" + report.ReportStart.ToString("yyyyMMdd") + "_" + report.ReportEnd.ToString("yyyyMMdd");
}
#region
var biaoTouList = Regex.Split(biaoTou, "</p>", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
var newBiaoTouList = new List<string>();
biaoTouList.ForEach(x =>
{
x = Regex.Replace(x, "<[^>]+>", "");
x = Regex.Replace(x, "&[^;]+;", "");
newBiaoTouList.Add(x);
});
report.BiaoTouLines = newBiaoTouList;
report.BiaoTou = string.Join("\n", newBiaoTouList);
var biaoWeiList = Regex.Split(biaoWei, "</p>", RegexOptions.IgnoreCase).Where(x => !string.IsNullOrWhiteSpace(x)).ToList();
var newBiaoWeiList = new List<string>();
biaoWeiList.ForEach(x =>
{
x = Regex.Replace(x, "<[^>]+>", "");
x = Regex.Replace(x, "&[^;]+;", "");
newBiaoWeiList.Add(x);
});
report.BiaoWeiLines = newBiaoWeiList;
report.BiaoWei = string.Join("\n", newBiaoWeiList);
#endregion
report.OutputFolder = req.OutputFolder;
TradeSwapDetailsReport = report;
return GenerateTradeDetailsReportV2(report, client);
}
private string GenerateTradeDetailsReportV2(TradeSwapDetailsReport report, Client client)
{
//获取盯市报告模板信息
var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/收益互换明细模板-单章.xlsx");
//if (client.ConfirmBookMode == "双章版")
var targetFolder = report.OutputFolder;
if (string.IsNullOrEmpty(targetFolder))
{
var date = report.ReportEnd;
targetFolder = OtcAppContext.MapPath($"~/App_Docs/Download/{date:yyyyMM}/");
}
string excelFileName;
var startDate = report.ReportStart;
if (startDate == DateTime.MinValue)
{
excelFileName = $"收益互换交易结算确认书_{report.ReportEnd:MMdd}_{report.ClientName}.xlsx";
}
else
{
excelFileName = $"收益互换交易结算确认书_{startDate:MMdd}_{report.ReportEnd:MMdd}_{report.ClientName}.xlsx";
}
var excelFilePath = Path.Combine(targetFolder, excelFileName);
Directory.CreateDirectory(targetFolder);
ExcelTemplate.GeneratePDFFromExeclTemplateV2(templateFile, excelFilePath,
new Dictionary<string, object> { { "交易明细", report } },
shouldDeleteSheet: true, needToPdf: false);
return excelFilePath;
}
public SearchListResult<TradeFlowMoreDetails> SearchFlowMoreDetails(TradeDetailsReq req)
{
if (req.ClientId < 1 && string.IsNullOrWhiteSpace(req.ClientIds))
{
return new SearchListResult<TradeFlowMoreDetails>();
}
if (req.EndDate == null)
{
throw new ServiceException("请选择结束日期");
}
if (req.StartDate != null && req.StartDate > req.EndDate)
{
throw new ServiceException("起始日期不能大于结束日期");
}
var clientIdsInt = new List<int>();
if (!string.IsNullOrWhiteSpace(req.ClientIds))
{
clientIdsInt.AddRange(req.ClientIdsInt);
}
else if (req.ClientId > 0)
{
clientIdsInt.Add(req.ClientId);
}
if (req.ParentFlag)
{
var clientIdList = DataCacheProvider.GetClientDataSource().AsQueryable(O => clientIdsInt.Contains(O.ParentId)).Select(O => O.id).ToList().ToHashSet();
clientIdsInt.AddRange(clientIdList);
}
var query = from source in DbContext.trade_swap_flow_more
join tradecashswap in DbContext.trade_cash_swap on source.id equals tradecashswap.FlowId into tradecashswap
from swap in tradecashswap.DefaultIfEmpty()
where !source.IsDelete && source.IsCompose && clientIdsInt.Contains(source.ClientId)
select new TradeFlowMoreDetails
{
id = source.id,
BuySell = source.BuySell,
TradeNumber = source.TradeNumber,
UnderlyingCode = source.UnderlyingCode,
TradeDate = source.TradeDate,
ExerciseDate = source.ExerciseDate,
Price = source.Price,
Notional = -source.Notional,
AnnualRate = -source.AnnualRate,
CurrencyRate = source.BuySell == "开仓" ? null : source.CurrencyRate,
UnwindDate = source.BuySell == "开仓" ? null : source.UnwindDate,
UnwindPrice = source.BuySell == "开仓" ? null : source.UnwindPrice,
UnwindNotional = source.BuySell == "开仓" ? null : -source.UnwindNotional,
TradeId = swap.TradeId,
TradeCashId = swap.TradeCashId,
TradeType = source.BuySell,
TotalFee = (source.TotalFee ?? 0),
StockEqvNotional = Math.Abs(source.Notional) * source.Price,
LongShort = source.LongShort,
OrderbyDate = source.BuySell == "开仓" ? source.TradeDate : source.UnwindDate,
OrderbyNumber = source.TradeNumber.Length >= 5 ? source.TradeNumber.Substring(source.TradeNumber.Length - 5, 5) : source.TradeNumber
};
if (req.DetailStatuses == "成交")
{
query = query.Where(x => x.BuySell == "开仓");
if (req.StartDate.HasValue)
{
query = query.Where(x => x.TradeDate >= req.StartDate);
}
if (req.EndDate.HasValue)
{
DateTime TradeDateTemp = req.EndDate.Value.AddDays(1);
query = query.Where(x => x.TradeDate < TradeDateTemp);
}
}
else if (req.DetailStatuses == "了结")
{
query = query.Where(x => x.BuySell == "平仓");
if (req.StartDate.HasValue)
{
query = query.Where(x => x.UnwindDate >= req.StartDate);
}
if (req.EndDate.HasValue)
{
DateTime TradeDateTemp = req.EndDate.Value.AddDays(1);
query = query.Where(x => x.UnwindDate < TradeDateTemp);
}
}
else
{
if (req.StartDate.HasValue)
{
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate >= req.StartDate) || (x.BuySell == "平仓" && x.UnwindDate >= req.StartDate));
}
if (req.EndDate.HasValue)
{
DateTime TradeDateTemp = req.EndDate.Value.AddDays(1);
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate < TradeDateTemp) || (x.BuySell == "平仓" && x.UnwindDate < TradeDateTemp));
}
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "OrderbyDate,OrderbyNumber";
req.sord = "asc";
}
var retListResult = query.ToSearchList(req);
var tcids = retListResult.rows.Select(x => x.TradeCashId).ToHashSet();
var tradedetail = DbContext.trade_cash_detail.Where(x => tcids.Contains(x.TradeCashId)).ToList();
var tradenumbers = retListResult.rows.Select(x => x.TradeNumber).ToHashSet();
var opentradeswapflowmore = DbContext.trade_swap_flow_more.Where(x => tradenumbers.Contains(x.TradeNumber) && x.BuySell == "开仓" && !x.IsDelete && x.IsCompose).ToList();
var underlying = DataCacheProvider.GetUnderlyingDataSource();
var instrumentTypeArr = new List<string>() { ConsGlobal.InstrumentType.Stock, ConsGlobal.InstrumentType.StockIF };
foreach (var item in retListResult.rows)
{
var un = underlying.GetData(item.UnderlyingCode);
if (un != null && un.IsCommodity())
{
item.UnderlyingCode = un.MarketCode == null || un.MarketCode == "" ? un.UnderlyingCode : un.UnderlyingCode + "." + un.MarketCode;
}
var detail = tradedetail.Where(x => x.TradeCashId == item.TradeCashId);
if (detail.Any() && item.BuySell == "平仓")
{
//item.FloatIncome = (-detail.FirstOrDefault(x => x.TradeCashType == TradeCashTypeEnum.浮动收益.ToString())?.Amount ?? 0);
item.FixedIncome = (-detail.FirstOrDefault(x => x.TradeCashType == TradeCashTypeEnum..ToString())?.Amount ?? 0);
item.Amount = (-detail.Sum(x => x.Amount) ?? 0);
item.FloatIncome = item.Amount - item.FixedIncome;
}
if (item.BuySell == "开仓")
{
var totalFee = (item.TotalFee / Math.Abs(item.Notional)).Normalize() * (item.LongShort == "多头" ? -1 : 1);
item.Price += totalFee;
}
else
{
var openflow = opentradeswapflowmore.Where(x => x.TradeNumber == item.TradeNumber).FirstOrDefault();
var optotalFee = ((openflow.TotalFee ?? 0) / Math.Abs(item.Notional)).Normalize() * (openflow.LongShort == "多头" ? -1 : 1);
var totalFee = (item.TotalFee / Math.Abs(item.UnwindNotional ?? 0)).Normalize() * (openflow.LongShort == "多头" ? 1 : -1);
item.Price += optotalFee;
item.UnwindPrice += totalFee;
}
item.TradeNumber = item.OrderbyNumber;
}
TradeFlowMoreSum sum = new TradeFlowMoreSum();
if (retListResult.rows.Any())
{
sum.FloatIncomeSum = retListResult.rows.Sum(x => (x.FloatIncome ?? 0));
sum.FixedIncomeSum = retListResult.rows.Sum(x => (x.FixedIncome ?? 0));
sum.AmountSum = retListResult.rows.Sum(x => (x.Amount ?? 0));
}
retListResult.Sum = sum;
return retListResult;
}
public SendTradeDetailReportResult SendTradeDetailReport(TradeDetailsReq req, TradeSwapDetailsReport report, string luoKuan,
string reportFilePath, string template, List<string> receiver = null, bool skip = false)
{
var AppendixType = DBCacheManager.Single.GetStr(CacheTable.TradeSwapDerailsNeedAppendix, template);
var path = string.Empty;
if (AppendixType == "PDF")
{
path = FileHelper.ReplaceExtension(reportFilePath, ".pdf");
path = GeneratePDFReport(reportFilePath);
}
else
{
path = reportFilePath;
}
var filePathes = new List<string>() { path };
var clientContacts = new ClientDBContext().clientduty.Where(x => x.ApprovalOrder < 1 && x.ClientId == req.ClientId
&& (x.DeadLine == null || x.DeadLine > DateTime.Now)
&& x.IsReceiveEmail.HasValue
&& x.IsReceiveEmail == 1).ToList();
var clientContactMails = new List<string>();
if (receiver != null && receiver.Count > 0)
{
foreach (var item in clientContacts)
{
var ids = item.ContactTypeId.Split(',');
if (ids.Intersect(receiver).Count() != 0)
{
clientContactMails.Add(item.Email);
}
}
}
else
{
clientContactMails = clientContacts.Select(o => o.Email).ToList();
}
var emails = DataConvert.EmailsSplitByComma(clientContactMails);
// var attachFiles = new List<string> { reportFilePath };
var startstr = req.StartDate.HasValue ? req.StartDate.Value.ToString("yyyy-MM-dd") : "";
var gh = req.StartDate.HasValue && req.EndDate.HasValue ? "-" : "";
var endstr = req.EndDate.HasValue ? req.EndDate.Value.ToString("yyyy-MM-dd") : "";
var endPart = (startstr == endstr) ? startstr : (startstr + gh + endstr);
//邮件标题格式 "【当前公司】"+ 客户名称 + "-场外交易确认-" + 确认日期或区间
var title = $"【国君风管】{report.ClientName}-场外商品互换交易确认-{endPart}";
if (PS.Config.IsGuoJun)
{
title = $"【国君风管】{report.ClientName}-场外商品互换交易确认-{endPart}";
}
var status = EmailTradeConfirmResultType.Succeed;
string sendMailMsg = null;
var ccemail = DBCacheManager.Single.GetStr(CacheTable.CCEmail, template);
var sendUser = DBCacheManager.Single.GetStr(CacheTable.TradeDetailsSendUser, template);
if (emails.All(o => string.IsNullOrWhiteSpace(o)))
{
status = EmailTradeConfirmResultType.NoEmailSetting;
}
else
{
emails = emails.Where(o => !string.IsNullOrWhiteSpace(o));
if (!string.IsNullOrWhiteSpace(AppendixType))
{
sendMailMsg = EmailHelper.SendMail(string.Join(";", emails), $"{report.ClientAbbreviation ?? ""}{title}", $"{luoKuan}", true, filePathes, ccemail, mailFrom: sendUser);
}
else
{
sendMailMsg = EmailHelper.SendMail(string.Join(";", emails), $"{report.ClientAbbreviation ?? ""}{title}", $"{luoKuan}", true, null, ccemail, mailFrom: sendUser);
}
if (!string.IsNullOrEmpty(sendMailMsg))
{
status = EmailTradeConfirmResultType.EmailSentFailed;
}
}
return new SendTradeDetailReportResult
{
ResultType = status,
ErrorMsg = sendMailMsg
};
}
private string GeneratePDFReport(string excelPath)
{
var tempFolder = OtcAppContext.MapPath("~/App_Docs/Temp");
if (!Directory.Exists(tempFolder))
{
Directory.CreateDirectory(tempFolder);
}
var tempExcelFilePath = FileHelper.GetTargetFilePath(excelPath, tempFolder, true);
File.Copy(excelPath, tempExcelFilePath);
var pdfFilePath = FileHelper.ReplaceExtension(excelPath, ".pdf");
var excelfilepath2 = FileHelper.ReplaceExtension(excelPath, ".xlsx");
var wordfilepath = FileHelper.ReplaceExtension(excelPath, ".docx");
if (File.Exists(excelfilepath2))
{
OfficeFileConverter.ConvertFileFormat(excelfilepath2, pdfFilePath);
}
else
{
OfficeFileConverter.ConvertDocxToPDF(wordfilepath, pdfFilePath);
}
return pdfFilePath;
}
}
public class TradeSwapDetailsReport
{
public YLErp.Configuration.IErpConfig Config => PS.Config.ErpElement;
public string CompanyName { get; set; }
public string TradeDetailsCode { get; set; }
public string ClientNumber { get; set; }
/// <summary>
/// 主 客户编号+A; 补充 客户编号+B;履约 客户编号+D; 主确认书:客户编号 + W
/// </summary>
public string ClientNumberA { get; set; }
public string ClientNumberB { get; set; }
public string ClientNumberD { get; set; }
public string ClientNumberW { get; set; }
public int? ClientId { get; set; }
/// <summary>
/// 有简称则用简称(应该是国君的需求)
/// </summary>
public string ClientName { get; set; }
/// <summary>
/// 客户全称
/// </summary>
public string ClientFullName { get; set; }
/// <summary>
/// 客户简称
/// </summary>
public string ClientAbbreviation { get; set; }
public DateTime ReportStart { get; set; }
public DateTime ReportEnd { get; set; }
public string ReportEndString => (ReportStart != DateTime.MinValue ? ($"{ReportStart.ToString("yyyy年M月d日")}至{ReportEnd.ToString("yyyy年M月d日")}") : ReportEnd.ToString("yyyy年M月d日"));
public DateTime ReportNow { get; set; }
public string ReportDateRange
{
get
{
var startDate = ReportStart;
if (startDate == DateTime.MinValue)
{
return $"{ReportEnd:yyyy/MM/dd}";
}
return $"{startDate:yyyy/MM/dd}-{ReportEnd:yyyy/MM/dd}";
}
}
public string BiaoTou { get; set; }
public string BiaoWei { get; set; }
/// <summary>
/// 用于Excel导出模板(交易明细)
/// </summary>
public IEnumerable<string> BiaoTouLines { get; set; }
/// <summary>
/// 用于Excel导出模板(交易明细)
/// </summary>
public IEnumerable<string> BiaoWeiLines { get; set; }
public string LuoKuan { get; set; }
public string Today => DateTime.Now.ToString("yyyy年M月d日");
/// <summary>
/// 导出文件输出文件夹路径
/// </summary>
public string OutputFolder { get; set; }
public List<TradeFlowMoreDetails> TradeFlowListAll { get; set; }
public TradeFlowMoreSum TradeFlowListSum { get; set; }
}
public class TradeFlowMoreDetails
{
public int id { get; set; }
public string TradeNumber { get; set; }
/// <summary>
/// 交易编号
/// </summary>
public string BuySell { get; set; }
/// <summary>
/// 标的代码
/// </summary>
public string UnderlyingCode { get; set; }
/// <summary>
/// 交易日期
/// </summary>
public DateTime? TradeDate { get; set; }
/// <summary>
/// 到期日期
/// </summary>
public DateTime? ExerciseDate { get; set; }
public string TradeDateString
{
get
{
return TradeDate?.ToString("yyyy/MM/dd");
}
}
public string ExerciseString
{
get
{
return ExerciseDate?.ToString("yyyy/MM/dd");
}
}
/// <summary>
/// 标的价格
/// </summary>
public double Price { get; set; }
public string PriceString
{
get
{
return Price.ToString("0.000000");
}
}
/// <summary>
/// 份额
/// </summary>
public double Notional { get; set; }
public string NotionalString
{
get
{
return (double.TryParse(Notional.ToString(), out double c) == true ? c.ToString() : 0.ToString());
}
}
/// <summary>
/// 利率
/// </summary>
public double? AnnualRate { get; set; }
public string AnnualRateString
{
get
{
return AnnualRate?.ToString("0.0000");
}
}
/// <summary>
/// 汇率
/// </summary>
public double? CurrencyRate { get; set; }
public string CurrencyRateString
{
get
{
return BuySell == "开仓" ? "--" : CurrencyRate?.ToString("0.0000");
}
}
/// <summary>
/// 平仓日期
/// </summary>
public DateTime? UnwindDate { get; set; }
public string UnwindDateString
{
get
{
return BuySell == "开仓" ? "--" : UnwindDate?.ToString("yyyy/MM/dd");
}
}
/// <summary>
/// 平仓价格
/// </summary>
public double? UnwindPrice { get; set; }
public string UnwindPriceString
{
get
{
return BuySell == "开仓" ? "--" : UnwindPrice?.ToString("0.000000");
}
}
/// <summary>
/// 平仓数量
/// </summary>
public double? UnwindNotional { get; set; }
public string UnwindNotionalString
{
get
{
return BuySell == "开仓" ? "--" : (int.TryParse(UnwindNotional?.ToString(), out int c) == true ? c.ToString() : 0.ToString());
}
}
/// <summary>
/// 浮动收益
/// </summary>
public double? FloatIncome { get; set; }
public string FloatIncomeString
{
get
{
return BuySell == "开仓" ? "--" : FloatIncome?.ToString("0.00");
}
}
/// <summary>
/// 固定收益
/// </summary>
public double? FixedIncome { get; set; }
public string FixedIncomeString
{
get
{
return BuySell == "开仓" ? "--" : FixedIncome?.ToString("0.00");
}
}
/// <summary>
/// 平仓总额
/// </summary>
public double? Amount { get; set; }
public string AmountString
{
get
{
return BuySell == "开仓" ? "--" : Amount?.ToString("0.00");
}
}
public string TradeType { get; set; }
public double StockEqvNotional { get; set; }
public string StockEqvNotionalString
{
get
{
return StockEqvNotional.ToString("0.00");
}
}
public string PayType
{
get
{
if (TradeNumber.Contains("W"))
{
return AnnualRate > 0 ? "商品互换\r\n收固定付浮动" : "商品互换\r\n付固定收浮动";
}
else if (TradeNumber.Contains("S"))
{
return AnnualRate > 0 ? "权益互换\r\n收固定付浮动" : "权益互换\r\n付固定收浮动";
}
else if (TradeNumber.Contains("F"))
{
return AnnualRate > 0 ? "仓单互换\r\n收固定付浮动" : "仓单互换\r\n付固定收浮动";
}
else
{
return AnnualRate > 0 ? "收固定付浮动" : "付固定收浮动";
}
}
}
public int? TradeId { get; set; }
public int? TradeCashId { get; set; }
/// <summary>
/// 手续费
/// </summary>
public double TotalFee { get; set; }
public string LongShort { get; set; }
/// <summary>
/// 排序规则时间
/// </summary>
public DateTime? OrderbyDate { get; set; }
public string OrderbyNumber { get; set; }
}
public class TradeFlowMoreSum
{
public double FloatIncomeSum { get; set; }
public double FixedIncomeSum { get; set; }
public double AmountSum { get; set; }
}
}
@@ -0,0 +1,59 @@
using BaseOUDAL;
using YieldChain.Helpers;
namespace YLErp.Modules.TradeModule.QueryModule
{
/// <summary>
/// 交易持仓波动率记录表查询
/// </summary>
public class TradeVolatilityQueryService : YLBaseService
{
public TradeVolatilityQueryService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 查询trade_volatility
/// </summary>
public SearchListResult<TradeVolatilityDto> SearchList(TradeVolatilityQueryModel req)
{
var tdQuery = DbContext.trade.AsQueryable();
if (!string.IsNullOrWhiteSpace(req.TradeNumber))
{
tdQuery = tdQuery.Where(n => n.TradeNumber == req.TradeNumber);
}
var query = from tdVol in DbContext.TradeVolatility
join td in tdQuery on tdVol.TradeId equals td.id
orderby tdVol.id descending
select new
{
tdVol,
td.TradeNumber
};
req.sidx = null;
var result = query.ToSearchList(req);
var result2 = new SearchListResult<TradeVolatilityDto>(result, result.rows.Select(n =>
{
var m = ObjectHelper.MapValues<TradeVolatilityDto>(n.tdVol);
m.TradeNumber = n.TradeNumber;
return m;
}));
return result2;
}
}
/// <summary>
/// 交易持仓波动率记录表查询
/// </summary>
public class TradeVolatilityQueryModel : BaseSearchReq
{
public string TradeNumber { get; set; }
}
}