421 lines
17 KiB
C#
421 lines
17 KiB
C#
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; }
|
|
|
|
}
|
|
}
|