Files
zszq-trs/YLErpDAL/Modules/TradeModule/SwapModule/SwapMultiCloseService.cs
T
2024-05-09 14:06:26 +08:00

361 lines
15 KiB
C#

using System.Data;
using System.Linq.Expressions;
using System.Text.Json.Serialization;
using YLErp.Enums;
using YLErp.Office.ExcelModule;
namespace YLErp.Modules.TradeModule.SwapModule
{
public class SwapMultiCloseService : YLBaseService
{
public SwapMultiCloseService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 获取分页数据(互换 -- 目前只有国君定制化的)
/// </summary>
public IPagedList<TradeSwapFlowMultiCloseResultModel> GetPagedDatas(TradeMultiCloseQueryModel queryModel)
{
if (queryModel is null)
{
throw new ArgumentNullException(nameof(queryModel));
}
BuildPredicate(queryModel, out var tdPredicate, out var tcPredicate);
var basicQuery = DbContext.trade.Where(tdPredicate);
var query = from t in basicQuery.Where(tdPredicate)
join tc in DbContext.trade_cash.Where(tcPredicate) on t.id equals tc.TradeId
join optc in DbContext.trade_cash.Where(x => x.ValidState != "InValid" && !x.IsDeleted && x.Action == "系统操作-期权费") on t.id equals optc.TradeId
join sw in DbContext.trade_swap on t.id equals sw.TradeId
join tcsw in DbContext.trade_cash_swap on tc.id equals tcsw.TradeCashId
select new TradeSwapFlowMultiCloseResultModel
{
id = t.id,
TradeNumber = t.TradeNumber,
TraderName = t.TraderName,
AssetBookName = t.AssetBookName,
ClientName = t.ClientName,
TradeDate = t.TradeDate,
StartDate = t.StartDate,
ExerciseDate = t.ExerciseDate,
SettlementDate = t.SettlementDate,
CloseDate = tc.ValueDate,
OriginalNotional = t.OriginalNotional ?? 0,
Notional = tc.Notional - (tc.UnwindNotional ?? 0),
UnWindNotional = tc.UnwindNotional ?? 0,
UnderlyingCode = t.UnderlyingCode,
SpotPrice = t.SpotPrice,
TradeCommission = sw.GetTradePrice ?? (-sw.PayTradePrice) ?? 0,
//导入的期末价格使用的是UnwindPrice
UnwindPrice = tc.UnwindPrice ?? tc.FinalPrice ?? 0,
TradeCashId = tc.id,
CloseType = tc.Action,
Amount = tc.Amount,
RealizedPnl = tc.Amount + optc.Amount * (tc.UnwindPercentRate ?? 0),
QuoteRealizedPnl = (tc.QuoteAmount ?? tc.Amount) + (optc.QuoteAmount ?? optc.Amount) * (tc.UnwindPercentRate ?? 0),
OpenCurrencyRate = optc.CurrencyRate ?? 1,
CloseCurrencyRate = tc.CurrencyRate ?? 1,
trade_swap = sw
};
if (queryModel.UnWindTimes != null && queryModel.UnWindTimes >= 0)
{
var qgp = (from f in query
group f by f.id into fgp
where fgp.Count() == queryModel.UnWindTimes
select fgp.Key).ToList();
query = query.Where(q => qgp.Contains(q.id));
}
if (!string.IsNullOrWhiteSpace(queryModel.UnWindType) && queryModel.UnWindType != "全部")
{
if (queryModel.UnWindType == "终止")
{
query = query.Where(x => x.CloseType == ClientCashInCashOut.系统操作_平仓费);
}
else if (queryModel.UnWindType == "到期")
{
query = query.Where(x => x.CloseType == ClientCashInCashOut.系统操作_互换 && x.CloseDate == x.ExerciseDate);
}
else if (queryModel.UnWindType == "互换")
{
query = query.Where(x => x.CloseType == ClientCashInCashOut.系统操作_互换 && x.CloseDate < x.ExerciseDate);
}
}
if (string.IsNullOrEmpty(queryModel.SortExpression))
{
query = query.OrderByDescending(x => x.CloseDate).ThenBy(x => x.TradeCashId);
}
var pagedList = query.ToPagedList(queryModel);
TradeSwapFlowMultiCloseResultModel preData = null;
foreach (var data in pagedList)
{
var underlying = DataCacheModule.DataCacheManager.GetUnderlyingDataSource().GetData(data.UnderlyingCode);
underlying.Variety = DataCacheModule.DataCacheManager.GetVarietyDataSource().GetData(underlying.CommodityCode);
data.QuoteCurrency = underlying.Variety.QuoteCurrency ?? ConsGlobal.Currency.CNY;
data.CountRatio = underlying?.CountRatio ?? 1;
data.UnderlyingName = underlying?.UnderlyingName;
if (preData?.id == data.id)
{
data.CloseSeq = preData.CloseSeq + 1;
}
preData = data;
if (data.trade_swap.IsGetFloatingProfit)
{
data.trade_swap.GetOpenPrice = data.trade_swap.GetSpotPrice + (data.trade_swap.GetLongShort == "多头" ? 1 : -1) * ((data.trade_swap.PaySingleFee ?? 0) / underlying.ContractSize + (data.trade_swap.GetSpotPrice * data.trade_swap.PayUnAnnualRate ?? 0));
}
else
{
data.trade_swap.PayOpenPrice = data.trade_swap.PaySpotPrice + (data.trade_swap.PayLongShort == "多头" ? 1 : -1) * ((data.trade_swap.GetSingleFee ?? 0) / underlying.ContractSize + (data.trade_swap.PaySpotPrice * data.trade_swap.GetUnAnnualRate ?? 0));
}
data.OpenPrice = data.trade_swap.GetOpenPrice ?? data.trade_swap.PayOpenPrice ?? 0;
data.OriginalStockEqvNotional = data.OpenPrice * data.OriginalNotional * data.OpenCurrencyRate;
data.StockEqvNotional = data.OpenPrice * data.Notional * data.OpenCurrencyRate;
data.CloseStockEqvNotional = data.OpenPrice * (data.UnWindNotional ?? 0) * data.OpenCurrencyRate;
var details = DbContext.trade_cash_detail.Where(x => x.TradeCashId == data.TradeCashId);
data.FixedIncome = details.Where(x => x.TradeCashType == TradeCashTypeEnum.利息.ToString()).Sum(x => x.Amount);
data.UnwindFee = details.Where(x => x.TradeCashType == TradeCashTypeEnum.了结手续费.ToString()).Sum(x => x.QuoteAmount);
data.FloatIncome = data.Amount - data.FixedIncome;
if (data.trade_swap.IsGetFloatingProfit)
{
data.ClosePrice = data.UnwindPrice + ((data.trade_swap.GetLongShort == "多头" ? -1 : 1) * (-data.UnwindFee ?? 0) / data.UnWindNotional).Normalize();
}
else
{
data.ClosePrice = data.UnwindPrice + ((data.trade_swap.PayLongShort == "多头" ? -1 : 1) * (data.UnwindFee ?? 0) / data.UnWindNotional).Normalize();
}
if (data.CloseType == "系统操作-互换")
{
if (data.CloseDate == data.ExerciseDate)
{
data.CloseType = "到期";
}
else
{
data.CloseType = "互换";
}
}
else if (data.CloseType == "系统操作-平仓费")
{
data.CloseType = "终止";
}
}
return pagedList;
}
private void BuildPredicate(TradeMultiCloseQueryModel queryModel, out Expression<Func<trade, bool>> tdPredicate, out Expression<Func<trade_cash, bool>> tcPredicate)
{
tdPredicate = PredicateBuilder.Create<trade>(t => t.ValidState != ConsGlobal.InValid && t.TradeType == "收益互换");
if (queryModel.UserAssets != null && queryModel.UserClients != null)
{
tdPredicate = tdPredicate.And(n => queryModel.UserAssets.Contains(n.AssetId) || queryModel.UserClients.Contains(n.ClientId));
}
if (!string.IsNullOrWhiteSpace(queryModel.TradeNumber))
{
var TradeNumber = queryModel.TradeNumber.Trim();
tdPredicate = tdPredicate.And(n => n.TradeNumber.Contains(TradeNumber));
}
if (!string.IsNullOrEmpty(queryModel.TraderNames))
{
tdPredicate = tdPredicate.And(d => queryModel.TraderNamesList.Contains(d.TraderId));
}
if (queryModel.AssetIdList.Any())
{
tdPredicate = tdPredicate.And(d => queryModel.AssetIdList.Contains(d.AssetId));
}
if (queryModel.ClientIdList.Any())
{
tdPredicate = tdPredicate.And(n => queryModel.ClientIdList.Contains(n.ClientId));
}
if (queryModel.TradeDateStart != null)
{
tdPredicate = tdPredicate.And(n => n.TradeDate >= queryModel.TradeDateStart.Value);
}
if (queryModel.TradeDateEnd != null)
{
tdPredicate = tdPredicate.And(n => n.TradeDate <= queryModel.TradeDateEnd.Value);
}
if (queryModel.ExerciseDateStart != null)
{
tdPredicate = tdPredicate.And(n => n.ExerciseDate >= queryModel.ExerciseDateStart.Value);
}
if (queryModel.ExerciseDateEnd != null)
{
tdPredicate = tdPredicate.And(n => n.ExerciseDate <= queryModel.ExerciseDateEnd.Value);
}
if (queryModel.AssetUnitIds != null && queryModel.AssetUnitIds.Any(a => a > 0))
{
tdPredicate = tdPredicate.And(n => queryModel.AssetUnitIds.Contains(n.AssetId));
}
var underlyids = queryModel.UnderlyingIdList.ToList();
if (!string.IsNullOrWhiteSpace(queryModel.UnderlyingName))
{
var _underlyids = DbContext.underlying_manager.Where(x => x.UnderlyingName.Contains(queryModel.UnderlyingName)).Select(x => x.id).ToHashSet();
if (underlyids.Count() > 0)
{
underlyids = underlyids.Intersect(_underlyids).Distinct().ToList();
}
else
{
underlyids = _underlyids.ToList();
}
}
if (queryModel.UnderlyingIdList.Any(n => n > 0) || !string.IsNullOrWhiteSpace(queryModel.UnderlyingName))
{
tdPredicate = tdPredicate.And(n => underlyids.Contains(n.UnderlyingId));
}
if (!string.IsNullOrWhiteSpace(queryModel.TradeStatus))
{
var statuses = queryModel.TradeStatus.Split(',').ToList();
tdPredicate = tdPredicate.And(n => statuses.Contains(n.TradeStatus));
}
tcPredicate = PredicateBuilder.Create<trade_cash>(tc => tc.ValidState != "InValid" && !tc.IsDeleted && (tc.Action == "系统操作-行权费" || tc.Action == "系统操作-平仓费" || tc.Action == "系统操作-互换"));
if (queryModel.UnwindDateStart != null)
{
tcPredicate = tcPredicate.And(n => n.ValueDate >= queryModel.UnwindDateStart.Value);
}
if (queryModel.UnwindDateEnd != null)
{
tcPredicate = tcPredicate.And(n => n.ValueDate <= queryModel.UnwindDateEnd.Value);
}
if (queryModel.TradeCashIdList.Any())
{
tcPredicate = tcPredicate.And(x => queryModel.TradeCashIdList.Contains(x.id));
}
}
/// <summary>
/// 导出所有字段
/// </summary>
public byte[] ExportAllFieldsToExcel(TradeMultiCloseQueryModel queryModel)
{
var list = GetPagedDatas(queryModel);
var results = new List<Dictionary<string, string>>(list.Count());
var templateFile = OtcAppContext.MapPath("~/App_Docs/导出模板/国君互换了结导出模板.xlsx");
return ExcelGenerator.UseTemplateGenerator(templateFile).AddVariable(new { list = list }).GenerateBytes();
}
}
public class TradeSwapFlowMultiCloseResultModel : OtcTradeBase
{
/// <summary>
/// 了结日期
/// </summary>
public DateTime? CloseDate { get; set; }
/// <summary>
/// 了结序号
/// </summary>
public int CloseSeq { get; set; } = 1;
/// <summary>
/// 了结方式
/// </summary>
public string CloseType { get; set; }
/// <summary>
/// 互换类型 -- 固定为“普通”
/// </summary>
public string SwapType { get; set; } = "普通";
/// <summary>
/// 了结名义本金
/// </summary>
public double CloseStockEqvNotional { get; set; }
/// <summary>
/// 开仓标的价格(费后)
/// </summary>
public double OpenPrice { get; set; }
/// <summary>
/// 了结标的价格(费后)
/// </summary>
public double ClosePrice { get; set; }
/// <summary>
/// 平仓费用
/// </summary>
public double? UnwindFee { get; set; }
/// <summary>
/// 了结标的价格
/// </summary>
public double UnwindPrice { get; set; }
/// <summary>
/// 浮动收益
/// </summary>
public double? FloatIncome { get; set; }
/// <summary>
/// 固定收益
/// </summary>
public double? FixedIncome { get; set; }
/// <summary>
/// 平仓总额
/// </summary>
public double? Amount { get; set; }
/// <summary>
/// 实现盈亏
/// </summary>
public double RealizedPnl { get; set; }
/// <summary>
/// 实现盈亏(结算)
/// </summary>
public double QuoteRealizedPnl { get; set; }
[JsonIgnore]
public int TradeCashId { get; set; }
/// <summary>
/// 成交手续费(了结部分所占的开仓总费用)
/// </summary>
public double TradeCommission { get; set; }
/// <summary>
/// 标的名称
/// </summary>
public string UnderlyingName { get; set; }
/// <summary>
/// 开仓汇率
/// </summary>
public double OpenCurrencyRate { get; set; }
/// <summary>
/// 结算汇率
/// </summary>
public double CloseCurrencyRate { get; set; }
public trade_swap trade_swap { get; set; }
}
}