Files
zszq-trs/YLErpDAL/Modules/SwapModule/SwapFlowService.cs
T
2025-10-15 15:08:37 +08:00

769 lines
35 KiB
C#

using BaseOUDAL;
using MoreLinq;
using NPOI.SS.Formula.Functions;
using OfficeOpenXml;
using Org.BouncyCastle.Ocsp;
using YieldChain.Security;
using YLErp.BLL.Eod;
using YLErp.DBModels;
using YLErp.Helpers;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.Modules.SwapModule.Dto;
using YLErp.Office;
using YLErp.QdpModule;
namespace YLErp.Modules.SwapModule
{
/// <summary>
/// 互换流水导入
/// </summary>
public class SwapFlowService : SwapTradeBaseService
{
public SwapFlowService(OptUserInfo optUser) : base(optUser)
{
}
public SwapFlowService(YLBaseService baseService) : base(baseService)
{
}
/// <summary>
/// 查询今天是否有FR007的数据
/// </summary>
/// <returns></returns>
public eod_commodity_future_price SearchTodayFRData(DateTime dateTime)
{
var data = DbContext.eod_commodity_future_price.Where(a => a.ValueDate == dateTime).FirstOrDefault();
if (data == null)
{
data = new eod_commodity_future_price();
}
return data;
}
/// <summary>
/// 查询选择的时间是否拥有FR007的数据
/// </summary>
/// <returns></returns>
public List<eod_commodity_future_price> SearchdateFRData(List<DateTime> date)
{
var datafr007 = DbContext.eod_commodity_future_price.Where(a => date.Contains(a.ValueDate)).ToList();
return datafr007;
}
/// <summary>
/// 删除的RF007数据
/// </summary>
/// <param name="id">要删除的RF007数据Id</param>
/// <exception cref="ServiceException"></exception>
public bool DeleteFRData(int id)
{
var frdata = DbContext.eod_commodity_future_price.Find(id);
if (frdata == null)
{
throw new ServiceException("未找到FR007流水");
}
DbContext.eod_commodity_future_price.Remove(frdata);
DbContext.SaveChanges();
return true;
}
/// <summary>
/// 新增或者修改FR007数据
/// </summary>
/// <param name="price">FR007价格</param>
/// <param name="dateTime">新增或者修改时间</param>
/// <exception cref="ServiceException"></exception>
public bool AddOrUpdateFRdata(Double price, DateTime dateTime)
{
string beforedate = "";
var frdata = DbContext.eod_commodity_future_price.Where(a => a.ValueDate == dateTime).FirstOrDefault();
if (frdata == null)
{
frdata = new eod_commodity_future_price();
}
//修改
if (frdata != null && frdata?.UnderlyingCode != null)
{
frdata.ValueDate = dateTime;
frdata.HighPrice = 0;
frdata.LowPrice = 0;
beforedate = JsonHelper.Serialize(frdata);
}
else
{
//新增
var newestdata = DbContext.eod_commodity_future_price.OrderByDescending(a => a.ValueDate).FirstOrDefault();
if (newestdata == null)
{
var underlyingCode = DbContext.underlying_manager.Where(a => a.UnderlyingCode == "FR007").FirstOrDefault();
if (underlyingCode == null)
{
throw new ServiceException("找不到FR007的标的");
}
newestdata = new eod_commodity_future_price();
newestdata.UnderlyingId = underlyingCode.id;
}
frdata.ValueDate = dateTime;
frdata.UnderlyingCode = "FR007";
frdata.UnderlyingId = newestdata.UnderlyingId;
frdata.DataSource = "人工";
DbContext.Add(frdata);
}
frdata.ClosePrice = Math.Round(price, 4);
frdata.SettlePrice = Math.Round(price, 4);
frdata.ReferencePrice = Math.Round(price, 4);
frdata.OptId = UserInfo.UserId;
frdata.OptName = UserInfo.UserName;
frdata.OptDate = DateTime.Now;
DbContext.SaveChanges();
return true;
}
/// <summary>
/// 查询互换流水导入
/// </summary>
public SearchListResult<swap_flow> SearchList(SwapFlowQueryRequest req)
{
var predicate = PredicateBuilder.Create<swap_flow>(n => n.DataState == (int)SwapFlowDateStateEnum.等待完成);
if (req.TradeDateStart.HasValue)
{
predicate = predicate.And(n => n.OccurTime >= req.TradeDateStart.Value);
}
if (req.TradeDateEnd.HasValue)
{
predicate = predicate.And(n => n.OccurTime <= req.TradeDateEnd.Value);
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate = predicate.And(n => n.UnderlyingCode==req.UnderlyingCode);
}
if (req.TradeDate.HasValue)
{
predicate = predicate.And(n => n.OccurTime == req.TradeDate);
}
if (req.ClientId.HasValue)
{
predicate = predicate.And(n => n.ClientId == req.ClientId);
}
var flowquery = DbContext.swap_flow.Where(predicate);
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
var retListResult = flowquery.AsNoTracking().ToSearchList(req);
var trsIds= retListResult.rows.Where(x=>x.trs_deal_id>0).Select(r => r.trs_deal_id).ToList();
var underlyingCodes= retListResult.rows.Select(r => r.UnderlyingCode).ToList();
var riskChecks = DbContext.trade_risk_check_log.Where(x=> trsIds.Contains(x.flow_id)).ToList();
var underlyings=DbContext.underlying_manager.Where(x=>underlyingCodes.Contains(x.UnderlyingCode)).AsNoTracking().ToList();
foreach (var item in retListResult.rows)
{
var riskCheck = riskChecks.FirstOrDefault(x=>x.flow_id==item.trs_deal_id);
item.limit_alert_remark = riskCheck?.remark;
var um = underlyings.FirstOrDefault(x=>x.UnderlyingCode==item.UnderlyingCode);
if (um!=null&&um.IsBond())
{
item.TradingAmountAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountFeeAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountNet *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountNetFee *= ConsGlobal.bondShowPriceMultiple;
item.TradingQty /= ConsGlobal.bondShowPriceMultiple;
}
}
return retListResult;
}
/// <summary>
/// 查询互换流水汇总
/// </summary>
public SearchListResult<SwapFlowQueryResponse> SearchMergeList(SwapFlowQueryRequest req)
{
var predicate = PredicateBuilder.Create<swap_flow_merge>(n => n.DataState == (int)SwapFlowDateStateEnum.等待完成 && n.OccurTime == req.TradeDate);
var capitalQuery = DbContext.swap_fund_account.Where(x => x.Status == (int)SwapFoundAccountStatusEnum.正常);
if (!string.IsNullOrEmpty(req.TradeNumber))
{
capitalQuery = capitalQuery.Where(n => n.SwapTradeNo.Contains(req.TradeNumber.Trim()));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate = predicate.And(n => n.UnderlyingCode==req.UnderlyingCode);
}
if (req.ClientId.HasValue)
{
predicate = predicate.And(n => n.ClientId == req.ClientId);
}
var flowquery = DbContext.swap_flow_merge.Where(predicate);
var query = from flow in flowquery
join capital in capitalQuery on flow.FundAccount equals capital.FundAccount
select new SwapFlowQueryResponse
{
id = flow.id,
FundAccount = flow.FundAccount,
OccurTime = flow.OccurTime,
SwapTradeId = capital.SwapTradeId,
SwapTradeNo = capital.SwapTradeNo,
BsType = flow.BsType,
UnderlyingCode = flow.UnderlyingCode,
TradingQty = flow.TradingQty,
TradingAmount = flow.TradingAmount,
TradingFee = flow.TradingFee,
TradingAmountAvg = flow.TradingAmountAvg,
TradingAmountFeeAvg = flow.TradingAmountFeeAvg,
TradingAmountNet=flow.TradingAmountNetFeeAvg??0,
ContractSize = flow.ContractSize
};
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "OccurTime,FundAccount,UnderlyingCode,BsType";
req.sord = "asc";
}
var retListResult = query.ToSearchList(req);
var underlyingCodes = retListResult.rows.Select(r => r.UnderlyingCode).ToList();
var underlyings = DbContext.underlying_manager.Where(x => underlyingCodes.Contains(x.UnderlyingCode)).AsNoTracking().ToList();
foreach (var item in retListResult.rows)
{
var um = underlyings.FirstOrDefault(x => x.UnderlyingCode == item.UnderlyingCode);
if (um != null && um.IsBond())
{
item.TradingAmountAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountFeeAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountNet *= ConsGlobal.bondShowPriceMultiple;
item.TradingQty /= ConsGlobal.bondShowPriceMultiple;
}
}
return retListResult;
}
/// <summary>
/// 查询互换开平仓事件
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public SearchListResult<swap_flow_event> SearchEventList(SwapFlowQueryRequest req)
{
var predicate = PredicateBuilder.Create<swap_flow_event>(n =>n.PositionType>0&&n.DataState>0);
List<int> eventTypes = new List<int>() { (int)SwapEventTypeEnum.确认交易, (int)SwapEventTypeEnum.平仓 };
if (req.TradeDate.HasValue)
{
predicate = predicate.And(n=>n.EventDate==req.TradeDate);
}
if (req.TradeDateEnd.HasValue)
{
predicate = predicate.And(n => n.EventDate <= req.TradeDateEnd);
}
if (req.TradeDateStart.HasValue)
{
predicate = predicate.And(n => n.EventDate >= req.TradeDateStart);
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
predicate = predicate.And(n => n.SwapTradeNo.Contains(req.TradeNumber.Trim()));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate = predicate.And(n => n.UnderlyingCode.Contains(req.UnderlyingCode.Trim()));
}
if (req.ClientId.HasValue)
{
predicate = predicate.And(n => n.ClientId==req.ClientId);
}
var eventQuery =from se in DbContext.swap_flow_event.Where(predicate)
join t in DbContext.trade.Where(x=>x.ValidState==ConsGlobal.Valid) on se.SwapTradeId equals t.id
join s in DbContext.swap_event.Where(x => !x.Invalid && eventTypes.Contains(x.EventType)) on se.EventId equals s.id into stemp
from s in stemp.DefaultIfEmpty()
select se;
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "PositionId,id";
req.sord = "asc";
}
var retListResult = eventQuery.ToSearchList(req);
List<trade_extend> extendList = null;
Dictionary<int, decimal?> ytmMap = new Dictionary<int, decimal?>();
if (retListResult != null && retListResult.rows != null && retListResult.rows.Any())
{
var tradeIds = retListResult.rows.Where(p => p.PayDate == null || p.EventType != (int)SwapEventTypeEnum.平仓).Select(p => p.SwapTradeId).Distinct().ToList();
if (tradeIds != null && tradeIds.Count > 0)
{
extendList = DbContext.trade_extend.AsNoTracking().Where(p => tradeIds.Contains(p.TradeId)).ToList();
// 查询成交收益率
ytmMap = DbContext.trade.AsNoTracking().Where(p => tradeIds.Contains(p.id)).ToList().ToDictionary(t => t.id, t => t.InitYtm);
}
}
if (extendList == null)
{
extendList = new List<trade_extend>();
}
foreach (var item in retListResult.rows)
{
item.InitYtm = ytmMap.GetValueOrDefault(item.SwapTradeId);
if (ConsGlobal.InstrumentType.IsBond(item.UnderlyingInstrumentType))
{
item.TradingAmountAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountFeeAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountNetFeeAvg *= ConsGlobal.bondShowPriceMultiple;
item.TradingAmountNetAvg *= ConsGlobal.bondShowPriceMultiple;
item.Quantity /= ConsGlobal.bondShowPriceMultiple;
}
if (item.PayDate == null || item.EventType != (int)SwapEventTypeEnum.平仓)
{
var extend = extendList.FirstOrDefault(p => p.TradeId == item.SwapTradeId);
if (extend != null&& item.PayDate == null)
{
item.PayDate = item.UnwindDate.Value.AddDays(extend.ExtendObj.SettlementRules);
}
}
}
return retListResult;
}
/// <summary>
/// 重置流水
/// </summary>
/// <param name="clientId"></param>
/// <param name="valueDate"></param>
public void ResetFlows(int clientId,DateTime valueDate)
{
var flows= DbContext.swap_flow.Where(x=>x.ClientId==clientId&&x.OccurTime>=valueDate&&x.DataState==(int)SwapFlowDateStateEnum.完成);
var flowMerge= DbContext.swap_flow_merge.Where(x => x.ClientId == clientId && x.OccurTime >= valueDate && x.DataState == (int)SwapFlowDateStateEnum.完成);
flows.ForEach(x =>
{
x.SwapTradeId = null;
x.SwapTradeNo = null;
x.DataState = (int)SwapFlowDateStateEnum.等待完成;
});
DbContext.swap_flow_merge.RemoveRange(flowMerge);
DbContext.SaveChanges();
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
});
}
/// <summary>
/// 开平仓事件导出
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
/// <exception cref="ServiceException"></exception>
public byte[] exprotSwapFlowEventExcel(SwapFlowQueryRequest req)
{
//获取数据
var ret = SearchEventList(req);
List<SwapFlowEventExportModel> list = new List<SwapFlowEventExportModel>();
foreach (var item in ret.rows)
{
SwapFlowEventExportModel exportModel = new SwapFlowEventExportModel();
exportModel.EventDate = item.EventDate.OtcFormatDate();
exportModel.UnwindDate = item.UnwindDate.OtcFormatDate();
exportModel.PayDate = item.PayDate.OtcFormatDate();
exportModel.SwapTradeNo = item.SwapTradeNo;
exportModel.SwapPositionIdPadding = item.SwapPositionIdPadding;
exportModel.EventType = ((SwapFlowEventTypeEnum)item.EventType).ToString();
exportModel.EventReason = item.EventReason;
exportModel.PayDirection = ((SwapDirectionEnum)item.PayDirection).ToString();
exportModel.PositionType = item.PositionType==1?"多头":"空头";
exportModel.UnderlyingCode = item.UnderlyingCode;
exportModel.MatuirityDate = item.MatuirityDate.OtcFormatDate();
exportModel.TradingAmountAvg = item.TradingAmountAvg.OtcFormat(OtcFormatFlag.umprice);
exportModel.TradingAmountFeeAvg = item.TradingAmountFeeAvg.OtcFormat(OtcFormatFlag.umprice);
exportModel.Quantity = item.Quantity.OtcFormatMoney(false, 4);
exportModel.TradingAmount = item.TradingAmount.OtcFormatMoney(false, 4);
exportModel.ContractSize = item.ContractSize.ToString();
exportModel.TradingFee = item.TradingFee.OtcFormatMoney(false, 4);
exportModel.TradingFeePending = item.TradingFeePending.OtcFormatMoney(false, 4);
exportModel.DividendPending = item.DividendPending.OtcFormatMoney(false, 4);
exportModel.MarkClosePnl = item.MarkClosePnl.OtcFormatMoney(false, 4);
exportModel.DividendIn = item.DividendIn.OtcFormatMoney(false, 4);
exportModel.OptLog = item.OptLog;
exportModel.InitYtm = item.InitYtm;
list.Add(exportModel);
}
var tplFilePath = OtcAppContext.MapPath("/App_Docs");
var sourceFileName = Path.Combine(tplFilePath, "导出模板", "互换开平仓事件流水导出模板.xlsx");
var modelDict = new Dictionary<string, object>();
var model = new { list = list };
modelDict.Add("Sheet1", model);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
return new ExcelTemplateGenerator().SetTemplateFile(sourceFileName).SetTemplateData(modelDict).Output();
}
/// <summary>
/// 查询互换合成持仓
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public SearchListResult<SwapPositionResponse> SearchComposeList(SwapFlowQueryRequest req)
{
var predicate = PredicateBuilder.Create<swap_position>(n => n.PosiQuantity>0 && n.PosiStartDate == req.TradeDate && !n.Invalid&&!n.IsInitial);
List<string> eventDatas = new List<string>() { "系统操作-自动合成持仓", "流水自动簿记确认交易" };
var eventDate =QdpCalendarHelper.GetNonHolidayDefore(req.TradeDate.Value.AddDays(-1));
var swapEventPredicate = PredicateBuilder.Create<swap_event>(n => eventDatas.Contains(n.EventReason)&&!n.Invalid&&n.ValueDate== eventDate);
var tradePredicate = PredicateBuilder.Create<trade>(n => n.TradeType=="收益互换"&&n.ValidState!=ConsGlobal.InValid);
if (!string.IsNullOrEmpty(req.TradeNumber))
{
tradePredicate = tradePredicate.And(n => n.TradeNumber.Contains(req.TradeNumber.Trim()));
}
if (req.ClientId.HasValue)
{
tradePredicate = tradePredicate.And(n => n.ClientId==req.ClientId);
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate = predicate.And(n => n.UnderlyingCode.Contains(req.UnderlyingCode.Trim()));
}
var positionQuery = DbContext.swap_position.Where(predicate);
var swapTradeIds = DbContext.swap_event.Where(swapEventPredicate).Select(s => s.SwapTradeId).Distinct();
tradePredicate = tradePredicate.And(x=> swapTradeIds.Contains(x.id));
var tradeQuery = DbContext.trade.Where(tradePredicate);
var query = from position in positionQuery
join td in tradeQuery on position.SwapTradeId equals td.id
select new SwapPositionResponse
{
position = position,
TradeDate = td.StartDate.Value,
SwapTradeNo = td.TradeNumber,
StructureType = td.StructureType,
ClientName = td.ClientName
};
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "SwapTradeNo,position.UnderlyingCode";
req.sord = "asc";
}
var retListResult = query.ToSearchList(req);
foreach (var item in retListResult.rows)
{
if (ConsGlobal.InstrumentType.IsBond(item.position.UnderlyingInstrumentType))
{
item.position.PosiNetPrice *= ConsGlobal.bondShowPriceMultiple;
item.position.PosiGrossPrice *= ConsGlobal.bondShowPriceMultiple;
item.position.PosiNetNoFeePrice *= ConsGlobal.bondShowPriceMultiple;
item.position.PosiNetFeePrice *= ConsGlobal.bondShowPriceMultiple;
item.position.PosiQuantity /= ConsGlobal.bondShowPriceMultiple;
}
}
return retListResult;
}
/// <summary>
/// 保存流水
/// </summary>
/// <param name="req"></param>
public void SaveSwapFlow(swap_flow req)
{
CheckValid(req);
swap_flow swap_Flow = DbContext.swap_flow.Find(req.id);
if (swap_Flow == null)
{
swap_Flow = new swap_flow();
}
swap_Flow.OccurTime = req.OccurTime;
swap_Flow.FundAccount = req.FundAccount;
swap_Flow.TradingAmount = req.TradingAmount;
swap_Flow.TradingFee = req.TradingFee;
swap_Flow.TradingQty = req.TradingQty;
swap_Flow.UnderlyingCode = req.UnderlyingCode;
swap_Flow.BsType = req.BsType;
swap_Flow.ContractSize = req.ContractSize;
swap_Flow.TradingAmountAvg = req.TradingAmountAvg;
swap_Flow.TradingAmountFeeAvg = TradeFeeHelper.CalcPriceWithFee(req.TradingFee,req.TradingAmountAvg,req.TradingQty,req.BsType);
swap_Flow.ClientId = req.ClientId;
swap_Flow.ytm = req.ytm;
swap_Flow.TradingAmountNet = req.TradingAmountNet;
swap_Flow.ClientName = req.ClientName;
swap_Flow.UnderlyingName = req.UnderlyingName;
swap_Flow.TradingAmountNetFee = TradeFeeHelper.CalcPriceWithFee(req.TradingFee, req.TradingAmountNet??0, req.TradingQty, req.BsType);
swap_Flow.SettleDate=req.SettleDate;
swap_Flow.DataState = (int)SwapFlowDateStateEnum.等待完成;
UpdateDbOption(swap_Flow);
if (req.id == 0)
{
DbContext.swap_flow.Add(swap_Flow);
}
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
});
DbContext.SaveChanges();
Dictionary<long, List<string>> clientUmsDic = new Dictionary<long, List<string>>();
clientUmsDic.Add(swap_Flow.ClientId ?? 0, new List<string> { swap_Flow.UnderlyingCode });
new RiskCacheService().refreshRiskCache(clientUmsDic);
}
/// <summary>
/// 回退删除手动簿记流水
/// </summary>
/// <param name="tradeId"></param>
/// <param name="eventDate"></param>
public void DeleteSwapFlow(int tradeId,DateTime eventDate,bool skip)
{
var swapFlows = DbContext.swap_flow.Where(x => x.SwapTradeId == tradeId && x.OccurTime >= eventDate);
if (skip)
{
swapFlows= swapFlows.Skip(1);
}
DbContext.swap_flow.RemoveRange(swapFlows);
DbContext.SaveChanges();
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
});
}
/// <summary>
/// 保存流水
/// </summary>
/// <param name="req"></param>
public void SaveSwapFlowMerge(swap_flow req)
{
CheckValid(req);
swap_flow_merge swap_Flow = DbContext.swap_flow_merge.Find(req.id);
if (swap_Flow == null)
{
swap_Flow = new swap_flow_merge(); ;
}
swap_Flow.OccurTime = req.OccurTime.Value;
swap_Flow.ClientId = req.ClientId;
swap_Flow.FundAccount = req.FundAccount;
swap_Flow.TradingAmount = req.TradingAmount;
swap_Flow.TradingFee = req.TradingFee;
swap_Flow.TradingQty = req.TradingQty;
swap_Flow.UnderlyingCode = req.UnderlyingCode;
swap_Flow.BsType = req.BsType;
swap_Flow.DataState = (int)SwapFlowDateStateEnum.等待完成;
swap_Flow.ContractSize = req.ContractSize;
swap_Flow.TradingAmountAvg = req.TradingAmountAvg;
swap_Flow.TradingAmountFeeAvg = req.TradingAmountFeeAvg;
UpdateDbOption(swap_Flow);
if (req.id == 0)
{
DbContext.swap_flow_merge.Add(swap_Flow);
}
DbContext.SaveChanges();
}
/// <summary>
/// 删除流水
/// </summary>
/// <param name="id"></param>
/// <exception cref="ServiceException"></exception>
public void DeleteSwapFlow(long id)
{
var capitalAccount = DbContext.swap_flow.Find(id);
if (capitalAccount == null)
{
throw new ServiceException("未找到该互换流水");
}
DbContext.swap_flow.Remove(capitalAccount);
DbContext.SaveChanges();
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
});
Dictionary<long, List<string>> clientUmsDic = new Dictionary<long, List<string>>();
clientUmsDic.Add(capitalAccount.ClientId ?? 0, new List<string> { capitalAccount.UnderlyingCode });
new RiskCacheService().refreshRiskCache(clientUmsDic);
}
/// <summary>
/// 删除流水
/// </summary>
/// <param name="id"></param>
/// <exception cref="ServiceException"></exception>
public void DeleteSwapFlowMerge(long id)
{
var swap_Flow = DbContext.swap_flow_merge.Find(id);
if (swap_Flow == null)
{
throw new ServiceException("未找到该互换流水汇总");
}
DbContext.swap_flow_merge.Remove(swap_Flow);
DbContext.SaveChanges();
}
/// <summary>
/// 查看流水
/// </summary>
/// <param name="id"></param>
/// <exception cref="ServiceException"></exception>
public swap_flow GetSwapFlow(long id)
{
var swapFlow = DbContext.swap_flow.Find(id);
if (swapFlow == null)
{
throw new ServiceException("未找到该互换流水");
}
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlow.UnderlyingCode);
if (um != null && um.IsBond())
{
swapFlow.TradingAmountAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountFeeAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountNet *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountNetFee *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingQty /= ConsGlobal.bondShowPriceMultiple;
}
return swapFlow;
}
public swap_flow_merge GetSwapFlowMerge(long id)
{
var swapFlow = DbContext.swap_flow_merge.Find(id);
if (swapFlow == null)
{
throw new ServiceException("未找到该互换流水");
}
var um = DataCacheProvider.GetUnderlyingDataSource().GetData(swapFlow.UnderlyingCode);
if (um != null && um.IsBond())
{
swapFlow.TradingAmountAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountFeeAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountNetAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingAmountNetFeeAvg *= ConsGlobal.bondShowPriceMultiple;
swapFlow.TradingQty /= ConsGlobal.bondShowPriceMultiple;
}
return swapFlow;
}
/// <summary>
/// 流水汇总
/// </summary>
public void SwapFlowMerge(DateTime tradeDate)
{
new SysJobService(UserInfo).UpdateJob("互换流水合成持仓", 21, "互换流水汇总进行中");
var predicate = PredicateBuilder.Create<swap_flow>(n => n.DataState == (int)SwapFlowDateStateEnum.等待完成 && n.OccurTime == tradeDate && n.BsType != (int)EnumDirection.UnKnown);
var capitalQuery = DbContext.swap_fund_account.Where(x => x.Status == (int)SwapFoundAccountStatusEnum.正常);
var flowquery = DbContext.swap_flow.Where(predicate);
var tradeQuery = DbContext.trade.Where(t => t.TradeStatus == ConsTrade.确认成交
&& t.StructureType == ClientMarginTypeEnum.多空组合.ToString()
&& t.ValidState != "InValid"
&& t.StartDate <= tradeDate
&& t.ExerciseDate >= tradeDate);
List<SwapFlowQueryResponse> swapFlowSummaries = new List<SwapFlowQueryResponse>();
var query = from flow in flowquery
join capital in capitalQuery on flow.FundAccount equals capital.FundAccount
join td in tradeQuery on capital.SwapTradeId equals td.id
select new SwapFlowQueryResponse
{
id = flow.id,
FundAccount = flow.FundAccount,
OccurTime = flow.OccurTime,
SwapTradeId = capital.SwapTradeId,
SwapTradeNo = capital.SwapTradeNo,
BsType = flow.BsType,
UnderlyingCode = flow.UnderlyingCode,
TradingQty = flow.TradingQty,
TradingAmount = flow.TradingAmount,
TradingFee = flow.TradingFee,
TradingAmountAvg = flow.TradingAmountAvg,
TradingAmountFeeAvg = flow.TradingAmountFeeAvg,
ContractSize = flow.ContractSize
};
foreach (var item in query)
{
if (GetUnderlyingCode(item.UnderlyingCode))
{
swapFlowSummaries.Add(item);
}
}
if (swapFlowSummaries.Count == 0)
{
return;
}
foreach (var item in swapFlowSummaries)
{
var flow = flowquery.First(x => x.id == item.id);
flow.DataState = (int)SwapFlowDateStateEnum.完成;
}
var swapFlowGroup = swapFlowSummaries.GroupBy(g => new { g.SwapTradeId, g.OccurTime, g.UnderlyingCode, g.BsType });
foreach (var gourpItem in swapFlowGroup)
{
var swapflow = gourpItem.First();
swap_flow_merge swap_flow_summary = new swap_flow_merge()
{
OccurTime = swapflow.OccurTime.Value,
FundAccount = swapflow.FundAccount,
SwapTradeId = swapflow.SwapTradeId,
SwapTradeNo = swapflow.SwapTradeNo,
UnderlyingCode = swapflow.UnderlyingCode,
BsType = swapflow.BsType,
TradingQty = gourpItem.Sum(s => s.TradingQty),
TradingAmount = gourpItem.Sum(s => s.TradingAmount),
TradingFee = gourpItem.Sum(s => s.TradingFee),
DataState = (int)SwapFlowDateStateEnum.等待完成,
TradingAmountFeeAvg = gourpItem.Average(s => s.TradingAmountFeeAvg),
TradingAmountAvg = gourpItem.Average(s => s.TradingAmountAvg),
ContractSize = swapflow.ContractSize
};
UpdateDbOption(swap_flow_summary);
DbContext.swap_flow_merge.Add(swap_flow_summary);
}
DbContext.SaveChanges();
new SysJobService(UserInfo).UpdateJob("互换流水合成持仓", 22, "互换流水汇总完成");
}
public void UpdatePayDate(UpdatePayDateDto dto)
{
var id = long.Parse(DataProtect.Decrypt(dto.Id));
var model = DbContext.swap_flow_event.FirstOrDefault(p => p.id == id);
if(model!=null)
{
model.PayDate=dto.PayDate;
model.OptId = UserInfo.UserId;
model.OptName = UserInfo.UserName;
model.OptTime = DateTime.Now;
DbContext.SaveChanges();
}
}
#region 私有方法
/// <summary>
/// 必填项校验
/// </summary>
/// <param name="req"></param>
/// <exception cref="ServiceException"></exception>
private void CheckRequired(swap_flow req)
{
if (string.IsNullOrEmpty(req.UnderlyingCode) && string.IsNullOrEmpty(req.UnderlyingCode.Trim()))
{
throw new ServiceException("标的代码不能为空");
}
req.UnderlyingCode = req.UnderlyingCode.Trim();
}
/// <summary>
/// 数据有效性校验
/// </summary>
/// <param name="req"></param>
private void CheckValid(swap_flow req)
{
CheckRequired(req);
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException("没有找到标的信息:" + req.UnderlyingCode);
}
if (underlying != null && underlying.IsBond())
{
req.TradingAmountAvg *= ConsGlobal.bondPriceMultiple;
req.TradingAmountFeeAvg *= ConsGlobal.bondPriceMultiple;
req.TradingAmountNet *= ConsGlobal.bondPriceMultiple;
req.TradingAmountNetFee *= ConsGlobal.bondPriceMultiple;
req.TradingQty *= ConsGlobal.bondShowPriceMultiple;
}
}
#endregion
}
}