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

1213 lines
49 KiB
C#

using BaseOUDAL;
using Qdp.Foundation.Implementations;
using YLErp.BLL;
using YLErp.BLL.EodSettlement;
using YLErp.CustomizedBizLogic;
using YLErp.DBModels.Consts;
using YLErp.Model;
using YLErp.Model.Enum;
using YLErp.QdpModule;
namespace YLErp.Modules.TradeModule.SwapModule
{
/// <summary>
/// 互换交易服务
/// </summary>
public class TradeSwapService : YLBaseService
{
public TradeSwapService(OptUserInfo userInfo) : base(userInfo)
{
}
/// <summary>
/// 查询trade
/// </summary>
public SearchListResult<trade> SearchList(TradeReq req, out tradeGridSum gsum, bool isUnionToday = false, bool isExerciseDateReport = false, bool isWithStructTrade = false)
{
var query = CreateTradeQuery(req, isUnionToday, isExerciseDateReport);
var resultTrade = query.ToList();
var todaybalanceStatus = new List<string> { ConsTrade.已到期, ConsTrade.已执行, ConsTrade.已平仓 };
var observateTrades = new List<trade>();
if (req.ValueDate != null)
{
var dateStr = req.ValueDate?.ToString("yyyy-MM-dd");
var swapTradeIds = resultTrade.Select(o => o.id).ToList();
var swapTrades = DbContext.swap_position.Where(t => swapTradeIds.Contains(t.SwapTradeId) && t.InterestDirection > 0 && t.IsInitial&&!t.Invalid).ToList();
foreach (var r in resultTrade)
{
var interests = swapTrades.Where(x => x.SwapTradeId == r.id).ToList();
if (interests.Any(s => s.SwapIntervalList.Any(x => x.Date == req.ValueDate)))
{
observateTrades.Add(r);
}
}
query = observateTrades.AsQueryable();
}
var retListResult = query.ToSearchList(req);
if (req.TabIndex == (int)TradeTabIndexEnum.互换观察日)
{
var list = new List<trade>();
list.AddRange(retListResult.rows.Where(t => !todaybalanceStatus.Contains(t.TradeStatus)));
list.AddRange(retListResult.rows.Where(t => todaybalanceStatus.Contains(t.TradeStatus)));
retListResult.rows = list;
}
gsum = new tradeGridSum();
if (query.Any())
{
gsum.TradePriceSum = query.Sum(q => q.TradePrice);
}
//获取销售提成信息
foreach (var item in retListResult.rows)
{
item.SalesCommission = new SalesModule.SalesCommissionDataService(OptUser).GetTradeCommissionInfo(item.id);
if (PS.Config.ErpElement.SalesCommissionCalculation == "公式1" && item.SalesCommission?.Commission != null)
{
item.SalesCommission.Commission = item.SalesCommission.Commission * item.SalesCommission.SalesIds.Count();
}
item.SettlementDate ??= item.ExerciseDate;
}
retListResult.Sum = gsum;
return retListResult;
}
/// <summary>
/// trade_swap_flow
/// </summary>
public SearchListResult<trade_swap_flow> SearchFlowList(TradeFlowReq req)
{
var query = from source in DbContext.trade_swap_flow select source;
if (!string.IsNullOrEmpty(req.ClientNumber))
{
query = query.Where(d => d.ClientNumber == req.ClientNumber);
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
query = query.Where(d => d.TradeNumber == req.TradeNumber);
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
query = query.Where(d => d.UnderlyingCode.Contains(req.UnderlyingCode));
}
if (req.AssetUnitNames != null && req.AssetUnitNames.Count > 0)
{
query = query.Where(d => req.AssetUnitNames.Contains(d.AssetUnitName));
}
if (req.TradeDateStart != DateTime.MinValue)
{
query = query.Where(d => d.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd != DateTime.MinValue)
{
var TradeDateTemp = req.TradeDateEnd.AddDays(1);
query = query.Where(d => d.TradeDate < TradeDateTemp);
}
if (req.ExerciseDateStart != DateTime.MinValue)
{
query = query.Where(d => d.ExerciseDate >= req.ExerciseDateStart);
}
if (req.ExerciseDateEnd != DateTime.MinValue)
{
var ExerciseDateTemp = req.ExerciseDateEnd.AddDays(1);
query = query.Where(d => d.ExerciseDate < ExerciseDateTemp);
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeDate,id";
req.sord = "asc";
}
var retListResult = query.ToSearchList(req);
return retListResult;
}
/// <summary>
/// trade_swap_flow
/// </summary>
public SearchListResult<trade_flow_history> SearchFlowHistoryList(TradeFlowReq req)
{
var query = from source in DbContext.trade_flow_history select source;
if (req.ClientIds != null && req.ClientIds.Any())
{
query = query.Where(d => req.ClientIds.Contains(d.ClientId));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
query = query.Where(d => d.UnderlyingCode.Contains(req.UnderlyingCode));
}
if (req.TradeDateStart != DateTime.MinValue)
{
query = query.Where(d => d.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd != DateTime.MinValue)
{
query = query.Where(d => d.TradeDate <= req.TradeDateEnd);
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
var retListResult = query.ToSearchList(req);
return retListResult;
}
/// <summary>
/// client_variety_config
/// </summary>
public SearchListResult<client_variety_config> SearchClientVarietyConfigList(ClientVarietyConfigReq req)
{
var query = from source in DbContext.client_variety_config select source;
if (req.ClientId > 0)
{
query = query.Where(d => d.ClientId == req.ClientId);
}
if (req.VarietyId > 0)
{
query = query.Where(d => d.VarietyId == req.VarietyId);
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
var retListResult = query.ToSearchList(req);
foreach (var item in retListResult.rows)
{
var client = DataCacheProvider.GetClientDataSource().GetData(item.ClientId);
item.ClientName = client?.Name;
item.ClientNumber = client?.Number;
var variety = DataCacheProvider.GetVarietyDataSource().GetData(item.VarietyId);
item.VarietyCode = variety?.VarietyCode;
item.VarietyName = variety?.VarietyName;
}
return retListResult;
}
// isWithStructTrade 是否 查找结构化交易的子交易默认false
private IQueryable<trade> CreateTradeQuery(TradeReq req, bool isUnionToday = false, bool isExerciseDateReport = false)
{
var predicate = PredicateBuilder.Create<trade>(n => n.ValidState != "InValid" && n.TradeType == "收益互换" && n.IsGroup != 2);
if (req.UserAssets != null && req.UserClients != null)
{
predicate = predicate.And(n => req.UserAssets.Contains(n.AssetId) || req.UserClients.Contains(n.ClientId));
}
if (req.TagIds != null && req.TagIds.Count > 0)
{
var tradeTagIdQuery = from tt in DbContext.trade_tag
where req.TagIds.Contains(tt.TagId)
select tt.TradeId;
predicate = predicate.And(p => tradeTagIdQuery.Contains(p.id));
}
var query = DbContext.trade.Where(predicate);
if (!string.IsNullOrEmpty(req.ContractCode))
{
query = from source in query
join tcrConfirm in DbContext.trade_contract_r.Where(aa => aa.Type == ContractTypeEnum.Trade && aa.IsValid) on new { id = source.ParentTradeId > 0 ? source.ParentTradeId : source.id } equals new { id = tcrConfirm.TradeId } into tcrConfirms
from tcrConfirm in tcrConfirms.DefaultIfEmpty()
where tcrConfirm.ContractCode.Contains(req.ContractCode)
select source;
}
var predicate_sw = PredicateBuilder.Create<trade_swap>(x => 1 == 1);
var issw = false;
if (!string.IsNullOrEmpty(req.UnderlyingIds))
{
predicate_sw = predicate_sw.And(n => req.UnderlyingIdsInt.Contains(n.GetUnderlyingId ?? 0) || req.UnderlyingIdsInt.Contains(n.PayUnderlyingId ?? 0));
issw = true;
}
if (req.UnderlyingId != null)
{
predicate_sw = predicate_sw.And(d => d.GetUnderlyingId == req.UnderlyingId || d.PayUnderlyingId == req.UnderlyingId);
issw = true;
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
predicate_sw = predicate_sw.And(d => d.GetUnderlyingCode.Contains(req.UnderlyingCode) || d.PayUnderlyingCode.Contains(req.UnderlyingCode));
issw = true;
}
if (req.UnderlyingCodeList != null)
{
predicate_sw = predicate_sw.And(d => req.UnderlyingCodeList.Contains(d.GetUnderlyingCode) || req.UnderlyingCodeList.Contains(d.PayUnderlyingCode));
issw = true;
}
if (issw)
{
query = from source in query
join sw in DbContext.trade_swap.Where(predicate_sw) on source.id equals sw.TradeId
select source;
}
if (!string.IsNullOrEmpty(req.UnderlyingAssetClass))
{
query = query.Where(d => d.UnderlyingAssetClass.Contains(req.UnderlyingAssetClass));
}
if (!string.IsNullOrEmpty(req.ClientIds))
{
query = query.Where(d => req.ClientIdsInt.Contains(d.ClientId));
}
if (!string.IsNullOrEmpty(req.UnderlyingInstrumentTypes))
{
query = query.Where(d => req.UnderlyingInstrumentTypesList.Contains(d.UnderlyingInstrumentType));
}
if (!string.IsNullOrEmpty(req.OptIds))
{
query = query.Where(d => req.OptIdsList.Contains(d.OptId + ""));
}
if (!string.IsNullOrEmpty(req.Comments))
{
query = query.Where(d => d.Comments.Contains(req.Comments));
}
if (!string.IsNullOrEmpty(req.TradeIds))
{
query = query.Where(d => req.TradeIdList.Contains(d.id));
}
if (req.AssetIdList.Any())
{
query = query.Where(d => req.AssetIdList.Contains(d.AssetId));
}
//获取当日成交的数据
//当日成交包括操作日期和交易日为当前系统日期的数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日成交)
{
var optDateStart = valuedateBLL.ValueDate;
var optDateEnd = valuedateBLL.ValueDate.AddDays(1);
var tradeDateStart = valuedateBLL.ValueDate;
var tradeDateEnd = valuedateBLL.ValueDate.AddDays(1);
query = query.Where(d => (d.TradeDate >= tradeDateStart && d.TradeDate < tradeDateEnd) || (d.OptDate >= optDateStart && d.OptDate < tradeDateEnd));
}
else
{
if (req.TradeDateStart != DateTime.MinValue)
{
query = query.Where(d => d.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd != DateTime.MinValue)
{
var TradeDateTemp = req.TradeDateEnd.AddDays(1);
query = query.Where(d => d.TradeDate < TradeDateTemp);
}
if (req.OptDateStart != DateTime.MinValue)
{
query = query.Where(d => d.OptDate >= req.OptDateStart);
}
if (req.OptDateEnd != DateTime.MinValue)
{
var OptDateTemp = req.OptDateEnd.AddDays(1);
query = query.Where(d => d.OptDate < OptDateTemp);
}
}
//获取当日到期日数据
if (req.TabIndex == (int)TradeTabIndexEnum.今日到期)
{
query = query.Where(d => d.ExerciseDate == valuedateBLL.ValueDate);
}
//获取明日到期日数据
else if (req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
var tommorow = QdpCalendarHelper.GetNonHoliday(valuedateBLL.ValueDate.AddDays(1));
query = query.Where(d => d.ExerciseDate == tommorow);
}
else
{
if (req.ExerciseDateEnd == null)
{
req.ExerciseDateEnd = DateTime.MaxValue;
}
if (req.ExerciseDateStart == null)
{
req.ExerciseDateStart = DateTime.MinValue;
}
if (isExerciseDateReport)
{
query = query.Where(d => d.ExerciseDate >= req.ExerciseDateStart && d.ExerciseDate <= req.ExerciseDateEnd);
}
else
{
query = query.Where(d => d.ExerciseDate == null || (d.ExerciseDate >= req.ExerciseDateStart && d.ExerciseDate <= req.ExerciseDateEnd));
}
}
if (req.SettlementDateEnd != null && req.SettlementDateEnd != DateTime.MinValue)
{
var TradeDateTemp = req.SettlementDateEnd.Value.AddDays(1);
query = query.Where(d => (d.SettlementDate ?? d.ExerciseDate) < TradeDateTemp);
}
if (req.SettlementDateStart != null && req.SettlementDateStart != DateTime.MinValue)
{
query = query.Where(d => (d.SettlementDate ?? d.ExerciseDate) >= req.SettlementDateStart);
}
if (!string.IsNullOrEmpty(req.TraderNames))
{
query = query.Where(d => req.TraderNamesList.Contains(d.TraderId));
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
var tradequery = DbContext.trade.Where(t => t.TradeNumber.Equals(req.TradeNumber));
query = query.Where(d => d.TradeNumber.Contains(req.TradeNumber) || tradequery.Select(x => x.ParentTradeId).Contains(d.id) || (tradequery.Select(x => x.ParentTradeId).Contains(d.ParentTradeId) && d.ParentTradeId > 0));
}
if (req.ClientId != null)
{
query = query.Where(d => d.ClientId == req.ClientId);
}
if (!string.IsNullOrEmpty(req.ClientName))
{
query = query.Where(d => d.ClientName.Contains(req.ClientName));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
query = query.Where(d => d.BuySell.Contains(req.BuySell));
}
if (!string.IsNullOrEmpty(req.OptionType))
{
query = query.Where(d => d.OptionType == req.OptionType);
}
if (req.StartDateStart != DateTime.MinValue)
{
query = query.Where(d => d.StartDate >= req.StartDateStart);
}
if (req.StartDateEnd != DateTime.MinValue)
{
var StartDateTemp = req.StartDateEnd.AddDays(1);
query = query.Where(d => d.StartDate < StartDateTemp);
}
//过滤已平仓,已到期,已执行数据
else if (req.TabIndex == (int)TradeTabIndexEnum.今日到期 || req.TabIndex == (int)TradeTabIndexEnum.明日到期)
{
query = query.Where(d => d.TradeStatus != ConsTrade.已平仓 && d.TradeStatus != ConsTrade.已到期 && d.TradeStatus != ConsTrade.已执行);
}
if (!string.IsNullOrEmpty(req.TradeStatus))
{
var statuses = req.TradeStatus.Split(',').ToList();
query = query.Where(d => statuses.Contains(d.TradeStatus));
}
if (req.TradeStatusList != null)
{
query = query.Where(d => req.TradeStatusList.Contains(d.TradeStatus));
}
if (req.AssetIdList.Any())
{
query = query.Where(d => req.AssetIdList.Contains(d.AssetId));
}
if (req.ClientIdsInt.Any())
{
query = query.Where(d => req.ClientIdsInt.Contains(d.ClientId));
}
if (req.SettlementFlags != null && req.SettlementFlags.Any())
{
query = query.Where(d => req.SettlementFlags.Contains(d.SettlementFlag));
}
if (!string.IsNullOrEmpty(req.OptName))
{
query = query.Where(d => d.OptName.Contains(req.OptName));
}
query = query.Where(d => !d.ValidState.Equals("InValid"));
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "id";
req.sord = "desc";
}
if (isUnionToday)
{
var todaybalanceStatus = new List<string> { "已到期", "已执行", "已平仓" };
var curDate = valuedateBLL.ValueDate;
//+ trade今天被exercise/expire的option. 排序按照optDate,从新到旧排
query = query.Union(from s in DbContext.trade where s.ClientId == req.ClientId && todaybalanceStatus.Contains(s.TradeStatus) && s.OptDate >= curDate select s);
}
query = query.OrderByDescending(s => s.OptDate);
return query;
}
public void DeleteTradeFlowOnly(int id)
{
var tradeSwapFlow = DbContext.trade_swap_flow.Find(id);
DbContext.trade_swap_flow.Remove(tradeSwapFlow);
DbContext.SaveChanges();
}
public void DeleteTradeFlow(int id)
{
using var trans = BeginTransaction();
var tradeSwapFlow = DbContext.trade_swap_flow.Find(id);
new SwapTradeFlowImportService(this).BackSwapTradeByTradeFlow(tradeSwapFlow);
var tradeSwapFlows = DbContext.trade_swap_flow.Where(x => x.UnderlyingCode == tradeSwapFlow.UnderlyingCode && x.ClientNumber == tradeSwapFlow.ClientNumber && ((x.id > tradeSwapFlow.id && x.TradeDate == tradeSwapFlow.TradeDate) || x.TradeDate > tradeSwapFlow.TradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).ToList();
tradeSwapFlows.ForEach(x =>
{
new SwapTradeFlowImportService(this).HandleSwapTrade(x);
x.Status = "已完成";
});
DbContext.trade_swap_flow.Remove(tradeSwapFlow);
DbContext.SaveChanges();
trans.Commit();
}
public void ComposeTrade(List<int> ids)
{
var service = new SwapTradeFlowImportService(UserInfo);
var flows = DbContext.trade_swap_flow.Where(x => ids.Contains(x.id)).ToList();
if (flows.Any(x => x.Status == "已完成"))
{
throw new ServiceException("存在已完成的交易流水,不能重复合成");
}
if (true)
{
var flowGroups = flows.GroupBy(x => new { x.ClientNumber, x.UnderlyingCode, x.BuySell, x.TradeDate }).Select(x => new trade_swap_flow()
{
id = x.Min(y => y.id),
ClientNumber = x.Key.ClientNumber,
UnderlyingCode = x.Key.UnderlyingCode,
BuySell = x.Key.BuySell,
AssetUnitName = x.FirstOrDefault().AssetUnitName,
ClearingAgency = x.FirstOrDefault().ClearingAgency,
ClientShortName = x.FirstOrDefault().ClientShortName,
Comments = "",
ExerciseDate = x.Max(y => y.ExerciseDate),
IsNight = x.FirstOrDefault().IsNight,
IsTradePriceWhenOpen = x.FirstOrDefault().IsTradePriceWhenOpen,
Lots = x.Sum(y => y.Lots),
NeedCostFee = x.FirstOrDefault().NeedCostFee,
Number = "",
UnAnnualRate = x.FirstOrDefault().UnAnnualRate,
QuoteCurrency = x.FirstOrDefault().QuoteCurrency,
SettlementDate = x.FirstOrDefault().SettlementDate,
SingleFee = x.FirstOrDefault().SingleFee,
SpotPrice = x.Sum(y => y.SpotPrice * y.Lots) / x.Sum(y => y.Lots),
StartDate = x.FirstOrDefault().StartDate,
TradeDate = x.Key.TradeDate,
OptDate = DateTime.Now,
OptName = UserName,
OptId = UserId
}).OrderBy(x => x.id).ToList();
flowGroups.ForEach(x =>
{
service.HandleSwapTrade(x);
});
}
else
{
//flows.ForEach(x =>
//{
// service.HandleSwapTrade(x);
//});
}
flows.ForEach(x =>
{
x.Status = "已完成";
x.OptDate = DateTime.Now;
x.OptName = UserName;
x.OptId = UserId;
});
DbContext.SaveChanges();
}
public void FIFOTradeFlow()
{
using var trans = BeginTransaction();
var tradeSwapFlows = DbContext.trade_swap_flow.Where(x => x.TradeDate == valuedateBLL.ValueDate && x.Status != "已完成").OrderBy(x => x.id).ToList();
tradeSwapFlows.ForEach(x =>
{
if (string.IsNullOrEmpty(x.TradeNumber))
{
new SwapTradeFlowImportService(this).HandleSwapTrade(x);
x.Status = "已完成";
}
});
DbContext.SaveChanges();
trans.Commit();
}
public trade_swap_flow SaveTradeFlow(trade_swap_flow req)
{
if (req.UnAnnualRate != null)
{
req.UnAnnualRate /= 100;
}
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
if (req.id > 0)
{
return UpdateTradeFlow(req);
}
else
{
return AddTradeFlow(req);
}
}
public trade_swap_flow AddOrUpdateTradeFlowOnly(trade_swap_flow req)
{
req.UnAnnualRate /= 100;
if (string.IsNullOrEmpty(req.TradeNumber) && string.IsNullOrEmpty(req.ClientNumber))
{
throw new ServiceException($"普通互换客户编号不能为空");
}
if (string.IsNullOrEmpty(req.TradeNumber) && string.IsNullOrEmpty(req.AssetUnitName))
{
throw new ServiceException($"普通互换簿记账户不能为空");
}
if (req.ExerciseDate == null)
{
//标的代码(必需)
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的代码[{req.UnderlyingCode}]在系统中不存在");
}
else
{
req.ExerciseDate = underlying.MaturityDate;
}
}
var variety = DataCacheProvider.GetVariety(req.UnderlyingCode);
if (variety == null)
{
throw new Exception($"该标的[{req.UnderlyingCode}]对应的品种在系统中不存在");
}
else
{
if (string.IsNullOrWhiteSpace(variety.QuoteCurrency) && DbContext.currency.Any())
{
throw new Exception($"标的代码[{req.UnderlyingCode}]对应的品种币种不能为空");
}
else
{
req.QuoteCurrency = variety.QuoteCurrency;
}
}
if (req.ExerciseDate == null)
{
throw new Exception($"客户编号[{req.ClientNumber}]标的代码[{req.UnderlyingCode}]到期日不能为空");
}
if (req.SettlementDate != null && req.SettlementDate < req.ExerciseDate)
{
throw new Exception($"客户编号[{req.ClientNumber}]标的代码[{req.UnderlyingCode}]的结算日期不应该小于到期日");
}
if (string.IsNullOrEmpty(req.Number) && PS.Config.Company == Configuration.CompanyEnum.中金)
{
req.Number = new BizLogicZJ().GenerateFlowNumber(req, DbContext);
}
var flow = new trade_swap_flow();
if (req.id > 0)
{
flow = DbContext.trade_swap_flow.Find(req.id);
flow.ClientNumber = req.ClientNumber;
flow.UnderlyingCode = req.UnderlyingCode;
flow.TradeNumber = req.TradeNumber;
flow.Number = req.Number;
flow.AssetUnitName = req.AssetUnitName;
flow.ClientShortName = req.ClientShortName;
flow.SpotPrice = req.SpotPrice;
flow.Lots = req.Lots;
flow.BuySell = req.BuySell;
flow.TradeDate = req.TradeDate;
flow.StartDate = req.StartDate;
flow.ExerciseDate = req.ExerciseDate;
flow.SettlementDate = req.SettlementDate;
flow.SingleFee = req.SingleFee;
flow.UnAnnualRate = req.UnAnnualRate;
flow.IsTradePriceWhenOpen = req.IsTradePriceWhenOpen;
flow.NeedCostFee = req.NeedCostFee;
flow.IsNight = req.IsNight;
flow.Comments = req.Comments;
flow.ClearingAgency = req.ClearingAgency;
flow.Status = "已修改";
}
else
{
flow = req;
SetDBModelCreator(flow);
DbContext.trade_swap_flow.Add(flow);
}
flow.OptId = UserId;
flow.OptName = UserName;
flow.OptDate = DateTime.Now;
DbContext.SaveChanges();
return flow;
}
private trade_swap_flow UpdateTradeFlow(trade_swap_flow req)
{
using var trans = BeginTransaction();
var tradeSwapFlow = DbContext.trade_swap_flow.Find(req.id);
var originalClientNumber = tradeSwapFlow.ClientNumber;
var originalUnderlyingCode = tradeSwapFlow.UnderlyingCode;
var originalTradeDate = tradeSwapFlow.TradeDate;
var tradeDate = req.TradeDate < tradeSwapFlow.TradeDate ? req.TradeDate : tradeSwapFlow.TradeDate;
var isDiff = tradeSwapFlow.ClientNumber != req.ClientNumber || tradeSwapFlow.UnderlyingCode != req.UnderlyingCode;
//相同客户相同标的不同交易日,需要选取小的来进行回退
if (req.TradeDate != tradeSwapFlow.TradeDate || req.ClientNumber != tradeSwapFlow.ClientNumber || req.UnderlyingCode != tradeSwapFlow.UnderlyingCode || req.BuySell != tradeSwapFlow.BuySell)
{
req.Number = new BizLogicZJ().GenerateFlowNumber(req, DbContext);
}
if (!isDiff)
{
tradeSwapFlow.TradeDate = tradeDate;
}
new SwapTradeFlowImportService(this).BackSwapTradeByTradeFlow(tradeSwapFlow);
if (isDiff)
{
var client = ClientModule.ClientDataQueryService.GetClientByNumber(req.ClientNumber);
if (client == null)
{
throw new ServiceException($"该客户编号[{req.ClientNumber}]在系统中不存在");
}
tradeSwapFlow.ClientNumber = req.ClientNumber;
tradeSwapFlow.UnderlyingCode = req.UnderlyingCode;
var flow = DbContext.trade_swap_flow.Where(x => x.ClientNumber == req.ClientNumber && x.UnderlyingCode == req.UnderlyingCode && ((x.id > tradeSwapFlow.id && x.TradeDate == req.TradeDate) || x.TradeDate > req.TradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).FirstOrDefault();
if (flow != null)
{
new SwapTradeFlowImportService(this).BackSwapTradeByTradeFlow(flow);
}
}
tradeSwapFlow.Number = req.Number;
tradeSwapFlow.AssetUnitName = req.AssetUnitName;
tradeSwapFlow.ClientShortName = req.ClientShortName;
tradeSwapFlow.SpotPrice = req.SpotPrice;
tradeSwapFlow.Lots = req.Lots;
tradeSwapFlow.BuySell = req.BuySell;
tradeSwapFlow.TradeDate = req.TradeDate;
tradeSwapFlow.StartDate = req.StartDate;
tradeSwapFlow.ExerciseDate = req.ExerciseDate;
tradeSwapFlow.SettlementDate = req.SettlementDate;
tradeSwapFlow.SingleFee = req.SingleFee;
tradeSwapFlow.UnAnnualRate = req.UnAnnualRate;
tradeSwapFlow.IsTradePriceWhenOpen = req.IsTradePriceWhenOpen;
tradeSwapFlow.NeedCostFee = req.NeedCostFee;
tradeSwapFlow.IsNight = req.IsNight;
tradeSwapFlow.Comments = req.Comments;
tradeSwapFlow.ClearingAgency = req.ClearingAgency;
tradeSwapFlow.OptId = UserId;
tradeSwapFlow.OptName = UserName;
tradeSwapFlow.OptDate = DateTime.Now;
if (tradeSwapFlow.ExerciseDate == null)
{
//标的代码(必需)
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的代码[{req.UnderlyingCode}]在系统中不存在");
}
else
{
tradeSwapFlow.ExerciseDate = underlying.MaturityDate;
}
}
if (tradeSwapFlow.ExerciseDate == null)
{
throw new ServiceException($"客户编号[{tradeSwapFlow.ClientNumber}]标的代码[{tradeSwapFlow.UnderlyingCode}]到期日不能为空");
}
if (tradeSwapFlow.SettlementDate != null && tradeSwapFlow.SettlementDate < tradeSwapFlow.ExerciseDate)
{
throw new ServiceException($"客户编号[{tradeSwapFlow.ClientNumber}]标的代码[{tradeSwapFlow.UnderlyingCode}]的结算日期不应该小于到期日");
}
DbContext.SaveChanges();
//同一客户同一标的(可能不同交易日)的场景
var tradeSwapFlows = DbContext.trade_swap_flow.Where(x => x.UnderlyingCode == tradeSwapFlow.UnderlyingCode && x.ClientNumber == tradeSwapFlow.ClientNumber && ((x.id >= tradeSwapFlow.id && x.TradeDate == tradeDate) || x.TradeDate > tradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).ToList();
//不同客户或者不同标的的场景
if (isDiff)
{
//新客户或者标的
tradeSwapFlows = DbContext.trade_swap_flow.Where(x => x.UnderlyingCode == tradeSwapFlow.UnderlyingCode && x.ClientNumber == tradeSwapFlow.ClientNumber && ((x.id >= tradeSwapFlow.id && x.TradeDate == tradeSwapFlow.TradeDate) || x.TradeDate > tradeSwapFlow.TradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).ToList();
//原始客户标的
tradeSwapFlows.AddRange(DbContext.trade_swap_flow.Where(x => x.UnderlyingCode == originalUnderlyingCode && x.ClientNumber == originalClientNumber && ((x.id >= tradeSwapFlow.id && x.TradeDate == originalTradeDate) || x.TradeDate > originalTradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).ToList());
}
tradeSwapFlows.ForEach(x =>
{
new SwapTradeFlowImportService(this).HandleSwapTrade(x);
x.Status = "已完成";
});
DbContext.SaveChanges();
trans.Commit();
return tradeSwapFlow;
}
private trade_swap_flow AddTradeFlow(trade_swap_flow req)
{
using var trans = BeginTransaction();
var flow = DbContext.trade_swap_flow.Where(x => x.ClientNumber == req.ClientNumber && x.UnderlyingCode == req.UnderlyingCode && x.TradeDate > req.TradeDate).OrderBy(x => x.TradeDate).ThenBy(x => x.id).FirstOrDefault();
if (flow != null)
{
new SwapTradeFlowImportService(this).BackSwapTradeByTradeFlow(flow);
}
req.Number = new BizLogicZJ().GenerateFlowNumber(req, DbContext);
DbContext.trade_swap_flow.Add(req);
req.OptId = UserId;
req.OptName = UserName;
req.OptDate = DateTime.Now;
req.CreatorId = UserId;
req.CreatorName = UserName;
req.CreateDate = DateTime.Now;
if (req.ExerciseDate == null)
{
//标的代码(必需)
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的代码[{req.UnderlyingCode}]在系统中不存在");
}
else
{
req.ExerciseDate = underlying.MaturityDate;
}
}
var variety = DataCacheProvider.GetVariety(req.UnderlyingCode);
if (variety == null)
{
throw new Exception($"该标的[{req.UnderlyingCode}]对应的品种在系统中不存在");
}
else
{
if (string.IsNullOrWhiteSpace(variety.QuoteCurrency) && DbContext.currency.Any())
{
throw new Exception($"标的代码[{req.UnderlyingCode}]对应的品种币种不能为空");
}
else
{
req.QuoteCurrency = variety.QuoteCurrency;
}
}
if (req.ExerciseDate == null)
{
throw new Exception($"客户编号[{req.ClientNumber}]标的代码[{req.UnderlyingCode}]到期日不能为空");
}
if (req.SettlementDate != null && req.SettlementDate < req.ExerciseDate)
{
throw new Exception($"客户编号[{req.ClientNumber}]标的代码[{req.UnderlyingCode}]的结算日期不应该小于到期日");
}
DbContext.SaveChanges();
var tradeSwapFlows = DbContext.trade_swap_flow.Where(x => x.UnderlyingCode == req.UnderlyingCode && x.ClientNumber == req.ClientNumber && ((x.id >= req.id && x.TradeDate == req.TradeDate) || x.TradeDate > req.TradeDate)).OrderBy(x => x.TradeDate).ThenBy(x => x.id).ToList();
tradeSwapFlows.ForEach(x =>
{
new SwapTradeFlowImportService(this).HandleSwapTrade(x);
x.Status = "已完成";
});
DbContext.SaveChanges();
trans.Commit();
return req;
}
public client_variety_config SaveClientVarietyConfig(client_variety_config req)
{
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
if (DbContext.client_variety_config.Any(x => x.id != req.id && x.ClientId == req.ClientId && x.VarietyId == req.VarietyId && x.ValueDate == req.ValueDate))
{
throw new Exception("同一客户同一品种不支持在同一天有多条配置记录");
}
if (req.SingleFee > 0 && req.UnAnnualRate > 0)
{
throw new Exception($"按手数收费和按名义本金收费不能同时设置");
}
var clientVarietyConfig = DbContext.client_variety_config.Find(req.id);
if (clientVarietyConfig == null)
{
clientVarietyConfig = new client_variety_config();
DbContext.client_variety_config.Add(clientVarietyConfig);
}
UpdateChanges(clientVarietyConfig, req);
var types = new List<int>();
if (clientVarietyConfig.SingleFee != 0)
{
types.Add(1);
}
if (clientVarietyConfig.AnnualRate != 0)
{
types.Add(2);
}
if (clientVarietyConfig.UnAnnualRate != 0)
{
types.Add(3);
}
clientVarietyConfig.FeeType = string.Join(",", types);
clientVarietyConfig.OptDate = DateTime.Now;
clientVarietyConfig.OptId = UserId;
clientVarietyConfig.OptName = UserName;
DbContext.SaveChanges();
return clientVarietyConfig;
}
#region 交易流水 -- 国君
/// <summary>
/// trade_swap_flow_more
/// </summary>
public SearchListResult<trade_swap_flow_more> SearchFlowMoreList(TradeFlowMoreReq req)
{
var query = from source in DbContext.trade_swap_flow_more.Where(x => !x.IsDelete) select source;
if (!string.IsNullOrEmpty(req.ClientNumber))
{
query = query.Where(d => d.ClientNumber.Contains(req.ClientNumber));
}
if (!string.IsNullOrEmpty(req.TradeNumber))
{
query = query.Where(d => d.TradeNumber.Contains(req.TradeNumber));
}
if (!string.IsNullOrEmpty(req.UnderlyingCode))
{
query = query.Where(d => d.UnderlyingCode.Contains(req.UnderlyingCode));
}
if (!string.IsNullOrEmpty(req.BuySell))
{
query = query.Where(d => d.BuySell == req.BuySell);
}
if (req.TradeDateStart != DateTime.MinValue)
{
query = query.Where(d => d.TradeDate >= req.TradeDateStart);
}
if (req.TradeDateEnd != DateTime.MinValue)
{
var TradeDateTemp = req.TradeDateEnd.AddDays(1);
query = query.Where(d => d.TradeDate < TradeDateTemp);
}
if (req.ExerciseDateStart != DateTime.MinValue)
{
query = query.Where(d => d.ExerciseDate >= req.ExerciseDateStart);
}
if (req.ExerciseDateEnd != DateTime.MinValue)
{
var ExerciseDateTemp = req.ExerciseDateEnd.AddDays(1);
query = query.Where(d => d.ExerciseDate < ExerciseDateTemp);
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeDate,id";
req.sord = "asc";
}
var retListResult = query.ToSearchList(req);
foreach (var item in retListResult.rows)
{
item.ClientName = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.Number == item.ClientNumber)?.Name;
item.UnderlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.UnderlyingName;
}
return retListResult;
}
public trade_swap_flow_more SaveTradeFlowMore(trade_swap_flow_more req)
{
if (req is null)
{
throw new ArgumentNullException(nameof(req));
}
using var trans = BeginTransaction();
var client = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(n => req.ClientNumber.Equals(n.Number, StringComparison.OrdinalIgnoreCase));
if (client == null)
{
throw new ServiceException($"该客户编号[{req.ClientNumber}]在系统中不存在");
}
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
if (underlying == null)
{
throw new ServiceException($"该标的代码[{req.UnderlyingCode}]在系统中不存在");
}
var swapFlow = DbContext.trade_swap_flow_more.Find(req.id);
if (req.BuySell == "开仓")
{
if (DbContext.trade.Where(x => x.TradeNumber == req.TradeNumber && x.ValidState != "InValid" && x.id != swapFlow.id).Any())
{
throw new ServiceException($"该交易已存在,编号[{req.TradeNumber}]");
}
if (DbContext.trade_swap_flow_more.Where(x => x.TradeNumber == req.TradeNumber && x.BuySell == "开仓" && !x.IsDelete && x.id != swapFlow.id).Any())
{
throw new ServiceException($"开仓流水已存在该交易编号,编号[{req.TradeNumber}]");
}
}
var traders = UserBLL.GetUsersByPosition().FirstOrDefault(x => x.Id == req.TraderId);
swapFlow.TraderId = traders.Id;
swapFlow.TraderName = traders.Name;
var assetUnit = DataCacheProvider.GetAssetUnitDataSource().AsQueryable().FirstOrDefault(x => x.Name == req.AssetBookName);
if (!("," + assetUnit.TraderIds + ",").Contains("," + swapFlow.TraderId + ","))
{
throw new ServiceException($"该交易员[{swapFlow.TraderName}]不在簿记账户[{req.AssetBookName}]中");
}
swapFlow.AssetId = assetUnit.id;
swapFlow.AssetBookName = assetUnit.Name;
swapFlow.ClientNumber = req.ClientNumber;
swapFlow.ClientId = client.id;
swapFlow.UnderlyingCode = req.UnderlyingCode;
var longShort = req.Notional > 0 ? "多头" : "空头";
swapFlow.LongShort = longShort;
swapFlow.Notional = req.Notional;
swapFlow.BuySell = req.BuySell; ;
swapFlow.TradeNumber = req.TradeNumber;
swapFlow.TradeDate = req.TradeDate;
swapFlow.ExerciseDate = req.ExerciseDate;
swapFlow.Price = req.Price;
swapFlow.CurrencyRate = req.CurrencyRate;
swapFlow.AnnualRate = req.AnnualRate;
swapFlow.TotalFee = req.TotalFee;
swapFlow.MargeRate = req.MargeRate;
if (swapFlow.BuySell == "平仓")
{
swapFlow.UnwindDate = req.UnwindDate;
swapFlow.UnwindPrice = req.UnwindPrice;
swapFlow.UnwindNotional = req.UnwindNotional;
swapFlow.Amount = req.Amount;
}
swapFlow.OptId = UserId;
swapFlow.OptName = UserName;
swapFlow.OptDate = DateTime.Now;
DbContext.SaveChanges();
trans.Commit();
return swapFlow;
}
public SearchListResult<trade_swap_flow_more> SearchFlowMoreHistory(TradeReq req)
{
var query = SearchFlowMoreQuery(req);
var retListResult = query.ToSearchList(req);
foreach (var item in retListResult.rows)
{
item.ClientName = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.Number == item.ClientNumber)?.Name;
item.UnderlyingName = DataCacheProvider.GetUnderlyingDataSource().GetData(item.UnderlyingCode)?.UnderlyingName;
item.LongShort = item.LongShort == "多头" ? "空头" : "多头";
item.Notional = -item.Notional;
item.TotalFee = -item.TotalFee;
item.FixedIncome = -item.FixedIncome;
item.UnwindNotional = -item.UnwindNotional;
item.AnnualRate = -item.AnnualRate;
item.NotionalString = int.TryParse(item.NotionalString, out var n) ? n.ToString() : "0";
item.UnwindNotional = int.TryParse((item.UnwindNotional ?? 0).ToString(), out var un) ? un : 0;
item.Amount = -item.Amount ?? 0;
item.QuoteAmount = (item.CurrencyRate ?? 0) * (item.Amount ?? 0);
}
var gsum = new trade_contract_groupGridSum();
if (query.Any())
{
gsum.WinLossSum = retListResult.rows.Where(x => x.BuySell != "开仓").Sum(x => x.Amount.OtcFormatValue(OtcFormatFlag.tradePrice));
gsum.QuoteWinLossSum = retListResult.rows.Where(x => x.BuySell != "开仓").Sum(x => x.QuoteAmount.OtcFormatValue(OtcFormatFlag.tradePrice));
}
retListResult.Sum = gsum;
return retListResult;
}
public List<trade_swap_flow_more> SearchFlowMoreHistoryList(TradeReq req)
{
var query = SearchFlowMoreQuery(req);
var list = query.ToList();
foreach (var item in list)
{
item.ClientName = DataCacheProvider.GetClientDataSource().AsQueryable().FirstOrDefault(x => x.Number == item.ClientNumber)?.Name;
item.LongShort = item.LongShort == "多头" ? "空头" : "多头";
item.Notional = -item.Notional;
item.TotalFee = -item.TotalFee;
item.FixedIncome = -item.FixedIncome;
item.UnwindNotional = -item.UnwindNotional;
item.AnnualRate = -item.AnnualRate;
item.NotionalString = int.TryParse(item.NotionalString, out var n) ? n.ToString() : "0";
item.UnwindNotional = int.TryParse((item.UnwindNotional ?? 0).ToString(), out var un) ? un : 0;
item.Amount = -item.Amount ?? 0;
item.QuoteAmount = (item.CurrencyRate ?? 0) * (item.Amount ?? 0);
}
return list;
}
private IQueryable<trade_swap_flow_more> SearchFlowMoreQuery(TradeReq req)
{
var query = from source in DbContext.trade_swap_flow_more.Where(x => !x.IsDelete && x.IsCompose)
select source;
if (req.ClientId != null && req.ParentFlag)
{
var lists = ClientBalanceUtility.GetSubclientId(req.ClientId.Value);
query = query.Where(d => lists.Contains(d.ClientId));
}
else if (req.ClientId != null && !req.ParentFlag)
{
query = query.Where(x => x.ClientId == req.ClientId);
}
if (req.ValueDateStart.Year > 2000)
{
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate >= req.ValueDateStart) || (x.BuySell == "平仓" && x.UnwindDate >= req.ValueDateStart));
}
if (req.ValueDateEnd.Year > 2000)
{
var TradeDateTemp = req.ValueDateEnd.AddDays(1);
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate < TradeDateTemp) || (x.BuySell == "平仓" && x.UnwindDate < TradeDateTemp));
}
if (string.IsNullOrEmpty(req.sidx))
{
req.sidx = "TradeDate,id";
req.sord = "asc";
}
return query;
}
public int SearchFlowMoreCount(int clientId, DateTime ValueDateStart, DateTime ValueDateEnd)
{
var query = from source in DbContext.trade_swap_flow_more select source;
if (clientId > 0)
{
query = query.Where(x => x.ClientId == clientId);
}
if (ValueDateStart.Year > 2000)
{
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate >= ValueDateStart) || (x.BuySell == "平仓" && x.UnwindDate >= ValueDateStart));
}
if (ValueDateEnd.Year > 2000)
{
var TradeDateTemp = ValueDateEnd.AddDays(1);
query = query.Where(x => (x.BuySell == "开仓" && x.TradeDate < TradeDateTemp) || (x.BuySell == "平仓" && x.UnwindDate < TradeDateTemp));
}
var result = query.Count();
return result;
}
public void FlowMoreComposeTrade()
{
var service = new SwapTradeFlowMoreImportService(UserInfo);
var tradeNumbers = DbContext.trade_swap_flow_more.Where(x => !x.IsCompose && !x.IsDelete).Select(x => x.TradeNumber).Distinct().ToList();
tradeNumbers.ForEach(x =>
{
service.HandleSwapTrade(x);
});
}
#endregion
}
}