TRS-ZS-566、TRS-ZS-568 客户保证金率需求完成

This commit is contained in:
吴方海
2025-07-18 17:44:58 +08:00
parent 723dc682eb
commit aa26f712bb
27 changed files with 1696 additions and 118 deletions
@@ -437,7 +437,6 @@ namespace YLErp.Modules.SwapModule
&& !ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus)).ToList();
var swapTradeIds = swaptrades.Select(s => s.id);
var tradeExtends = DbContext.trade_extend.Where(x => swapTradeIds.Contains(x.TradeId));
var clientMarginTemplates = DbContext.client_marginrate.Where(x => x.ValueDate <= valueDate).OrderByDescending(o => o.ValueDate).ToList();
var restSwapTrades = new List<trade>();
foreach (var swaptrade in swaptrades)
{
@@ -454,7 +453,7 @@ namespace YLErp.Modules.SwapModule
int dealCount = 0;
foreach (var groupItem in flowquery)
{
MergeRestModelItem(groupItem, restSwapTrades, swapPositions, floatRateQuery, clientMarginTemplates, ref dealCount, action);
MergeRestModelItem(groupItem, restSwapTrades, swapPositions, floatRateQuery, ref dealCount, action);
}
}
/// <summary>
@@ -476,14 +475,13 @@ namespace YLErp.Modules.SwapModule
&& !ConsTrade.TradeCompleteStatus.Contains(t.TradeStatus)).ToList();
var swapTradeIds = swaptrades.Select(s => s.id);
var swapPositions = DbContext.swap_position.Where(x => swapTradeIds.Contains(x.SwapTradeId) && x.PosiDirection > 0 && !x.IsInitial && x.PosiQuantity > 0 && !x.Invalid).ToList();
var clientMarginTemplates = DbContext.client_marginrate.Where(x => x.ValueDate <= valueDate).OrderByDescending(o => o.ValueDate).ToList();
var matuirityDate = QdpCalendarHelper.GetNonHolidayDefore(valueDate.AddDays(14));
var floatRatePredicate = PredicateBuilder.Create<SwapFloatRate>(x => x.StartDate <= valueDate && x.EndDate >= matuirityDate);
var floatRateQuery = DbContext.swap_float_rate.Where(floatRatePredicate);
int dealCount = 0;
foreach (var groupItem in flowquery)
{
MergeAvgModelItem(groupItem, swaptrades, swapPositions, floatRateQuery, clientMarginTemplates, ref dealCount, action);
MergeAvgModelItem(groupItem, swaptrades, swapPositions, floatRateQuery, ref dealCount, action);
}
}
public void UpdateSwapFlowState(List<swap_flow> swapFlows)
@@ -507,8 +505,7 @@ namespace YLErp.Modules.SwapModule
private void MergeRestModelItem(IGrouping<int?, swap_flow_merge> groupItem,
List<trade> swaptrades,
List<swap_position> swapPositions,
IQueryable<SwapFloatRate> floatRateQuery,
List<client_marginrate> client_Marginrates, ref int dealCount, Action<int>? action)
IQueryable<SwapFloatRate> floatRateQuery, ref int dealCount, Action<int>? action)
{
var clientId = groupItem.Key;
var client = DataCacheProvider.GetClientDataSource().GetData(clientId ?? 0);
@@ -535,11 +532,6 @@ namespace YLErp.Modules.SwapModule
{
throw new ServiceException($"{etradeRule.AssetAccount_0}的簿记账户未设置交易员");
}
var clientMarginTemplate = client_Marginrates.FirstOrDefault(x => x.ClientId == clientId);
if (clientMarginTemplate == null)
{
clientMarginTemplate = client_Marginrates.FirstOrDefault(x => x.ClientId == 0);
}
var underlyingGroup = groupItem.GroupBy(g => g.UnderlyingCode);
var clientSwapTrades = swaptrades.Where(x => x.ClientId == clientId).ToList();
var clientSwapTradeIds = clientSwapTrades.Select(s => s.id);
@@ -583,11 +575,11 @@ namespace YLErp.Modules.SwapModule
}
if (!hasPayPosition)//没有持仓
{
DealNoPosition(mergeList, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, cashNeedAfter);
DealNoPosition(mergeList, client, asset, underlying, floatRate, clearingAgency, cashNeedAfter);
}
else
{
DealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clientMarginTemplate, clearingAgency, cashNeedAfter);
DealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades,clearingAgency, cashNeedAfter);
}
}
@@ -607,8 +599,7 @@ namespace YLErp.Modules.SwapModule
private void MergeAvgModelItem(IGrouping<int?, swap_flow_merge> groupItem,
List<trade> swaptrades,
List<swap_position> swapPositions,
IQueryable<SwapFloatRate> floatRateQuery,
List<client_marginrate> client_Marginrates, ref int dealCount, Action<int>? action)
IQueryable<SwapFloatRate> floatRateQuery,ref int dealCount, Action<int>? action)
{
var clientId = groupItem.Key;
var client = DataCacheProvider.GetClientDataSource().GetData(clientId ?? 0);
@@ -619,11 +610,6 @@ namespace YLErp.Modules.SwapModule
var clientSwapTrades = swaptrades.Where(x => x.ClientId == clientId).ToList();
var clientSwapTradeIds = clientSwapTrades.Select(s => s.id);
var clientSwapPositions = swapPositions.Where(x => clientSwapTradeIds.Contains(x.SwapTradeId));//现有客户持仓
var clientMarginTemplate = client_Marginrates.FirstOrDefault(x => x.ClientId == clientId);
if (clientMarginTemplate == null)
{
clientMarginTemplate = client_Marginrates.FirstOrDefault(x => x.ClientId == 0);
}
var underlyingCodes = underlyingGroup.Select(s => s.Key).ToList();
var underlyings = DataCacheProvider.GetUnderlyingDataSource().AsQueryable(x => underlyingCodes.Contains(x.UnderlyingCode));
foreach (var underlyingGroupItem in underlyingGroup)
@@ -643,11 +629,11 @@ namespace YLErp.Modules.SwapModule
if (!hasPayPosition)//没有持仓
{
var bsType = mergeList.OrderBy(o => o.OptTime).First().BsType;
AvgDealNoPosition(mergeList, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, bsType);
AvgDealNoPosition(mergeList, client, asset, underlying, floatRate, clearingAgency, bsType);
}
else
{
AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clientMarginTemplate, clearingAgency);
AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clearingAgency);
}
}
@@ -667,7 +653,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency,
bool cashNeedAfter)
{
@@ -675,7 +660,7 @@ namespace YLErp.Modules.SwapModule
swap_flow_merge flowMergeMax = mergeOrderList.First();//先开最早的一条
swap_flow_merge flowMergeMin = mergeOrderList.Last();
var swapTradeService = new SwapTradeService(UserInfo);
var trade = swapTradeService.NewSwapTrade(flowMergeMax, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, cashNeedAfter: cashNeedAfter);
var trade = swapTradeService.NewSwapTrade(flowMergeMax, client, asset, underlying, floatRate, clearingAgency, cashNeedAfter: cashNeedAfter);
flowMergeMax.SwapTradeNo = trade.TradeNumber;
flowMergeMin.SwapTradeNo = trade.TradeNumber;
if (mergeList.Count == 2)//有两条流水
@@ -707,7 +692,7 @@ namespace YLErp.Modules.SwapModule
var posi = DbContext.swap_position.FirstOrDefault(x => x.SwapTradeId == trade.id && x.PosiDirection > 0 && !x.IsInitial);
SetNewOpenData(flowMergeMin, flowMergeClone, posi);
}
var trade2 = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
var trade2 = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clearingAgency);
flowMergeMax.SwapTradeNo = trade2.TradeNumber;
flowMergeMin.SwapTradeNo = trade2.TradeNumber;
}
@@ -728,7 +713,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency,
int byType)
{
@@ -736,9 +720,9 @@ namespace YLErp.Modules.SwapModule
var sameFlow = swapFlows.Where(x => x.BsType == byType).FirstOrDefault();
if (negativeFlow==null)
{
return NewSwapTrade(sameFlow, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
return NewSwapTrade(sameFlow, client, asset, underlying, floatRate,clearingAgency);
}
return DealTwoDirectionFlows(sameFlow, negativeFlow, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
return DealTwoDirectionFlows(sameFlow, negativeFlow, client, asset, underlying, floatRate, clearingAgency);
}
/// <summary>
/// 当前无持仓,且有2个方向流水合成簿记
@@ -758,7 +742,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var sameQty = sameFlow.TradingQty;
@@ -771,7 +754,7 @@ namespace YLErp.Modules.SwapModule
sameFlowClone= DataHelper.DeepCopyObject(negativeFlow);
negaFlowClone = DataHelper.DeepCopyObject(sameFlow);
}
var trade = NewSwapTrade(sameFlowClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
var trade = NewSwapTrade(sameFlowClone, client, asset, underlying, floatRate, clearingAgency);
// 平仓
new SwapDealService(UserInfo).AuotoSwapUnwind(trade.id,
negaFlowClone.TradingAmountAvg,
@@ -799,11 +782,10 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var swapTradeService = new SwapTradeService(UserInfo);
var trade = swapTradeService.NewSwapTrade(flowMergeFirst, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, LongShortStructType);
var trade = swapTradeService.NewSwapTrade(flowMergeFirst, client, asset, underlying, floatRate, clearingAgency, LongShortStructType);
flowMergeFirst.SwapTradeNo = trade.TradeNumber;
flowMergeFirst.SwapTradeId = trade.id;
DbContext.SaveChanges();
@@ -889,17 +871,16 @@ namespace YLErp.Modules.SwapModule
SwapFloatRate floatRate,
List<swap_position> clientSwapPositionList,
List<trade> clientSwapTrades,
client_marginrate clientMarginTemplate,
string clearingAgency,
bool cashNeedAfter)
{
if (mergeList.Count == 1)//只有一条流水情况
{
DealSingleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
DealSingleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate,clearingAgency);
}
else
{
DealDoubleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, cashNeedAfter);
DealDoubleFlow(mergeList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency, cashNeedAfter);
}
}
/// <summary>
@@ -920,17 +901,16 @@ namespace YLErp.Modules.SwapModule
SwapFloatRate floatRate,
List<swap_position> clientSwapPositionList,
List<trade> clientSwapTrades,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var firstFlow = flowList.First();
if (flowList.Count==1)//只有一条流水情况
{
AvgDealSingleFlow(firstFlow, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
AvgDealSingleFlow(firstFlow, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency);
}
else
{
AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate,clearingAgency);
}
}
/// <summary>
@@ -951,7 +931,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var swapTradeService = new SwapTradeService(UserInfo);
@@ -978,13 +957,13 @@ namespace YLErp.Modules.SwapModule
{
SetNewOpenData(flowMergeMax, flowMergeClone, dealResult.Item4);
}
var trade = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
var trade = swapTradeService.NewSwapTrade(flowMergeClone, client, asset, underlying, floatRate, clearingAgency);
flowMergeMax.SwapTradeNo = trade.TradeNumber;
}
}
else //只存在同向交易
{
var trade = swapTradeService.NewSwapTrade(flowMergeMax, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
var trade = swapTradeService.NewSwapTrade(flowMergeMax, client, asset, underlying, floatRate, clearingAgency);
flowMergeMax.SwapTradeNo = trade.TradeNumber;
}
}
@@ -1027,7 +1006,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency,
bool cashNeedAfter)
{
@@ -1049,22 +1027,22 @@ namespace YLErp.Modules.SwapModule
var negTrades = clientSwapTrades.Where(x => negTradeIds.Contains(x.id)).ToList();//取出与第一条流水方向相反的交易
//先处理第一条流水的反向持仓
var firstTrade = DealDoubleFlowDetial(negTrades, negDirectionPositions, flowMergeFirstClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, true, cashNeedAfter);
var firstTrade = DealDoubleFlowDetial(negTrades, negDirectionPositions, flowMergeFirstClone, client, asset, underlying, floatRate, clearingAgency, true, cashNeedAfter);
flowMergeFirst.SwapTradeNo = flowMergeFirstClone.SwapTradeNo;
//再处理第二条流水的反向持仓
var lastTrade = DealDoubleFlowDetial(sameTrades, sameDirectionPositions, flowMergeLastClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, false,false);
var lastTrade = DealDoubleFlowDetial(sameTrades, sameDirectionPositions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, false,false);
flowMergeLast.SwapTradeNo = flowMergeLastClone.SwapTradeNo;
if (flowMergeFirstClone.BsType != flowMergeLastClone.BsType && firstTrade != null)
{
var trades = new List<trade> { firstTrade };
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == firstTrade.id && x.PosiDirection > 0 && !x.IsInitial && !x.Invalid).ToList();
DealDoubleFlowDetial(trades, positions, flowMergeLastClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, true,false);
DealDoubleFlowDetial(trades, positions, flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency, true,false);
flowMergeLast.SwapTradeNo = flowMergeLastClone.SwapTradeNo;
}
else if (lastTrade==null)
{
swapTradeService.NewSwapTrade(flowMergeLastClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
swapTradeService.NewSwapTrade(flowMergeLastClone, client, asset, underlying, floatRate, clearingAgency);
}
}
/// <summary>
@@ -1085,7 +1063,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var swapTradeService = new SwapTradeService(UserInfo);
@@ -1097,11 +1074,11 @@ namespace YLErp.Modules.SwapModule
// 同向新开
if (flow.BsType== firstPosi.PositionType)
{
NewSwapTrade(flowClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
NewSwapTrade(flowClone, client, asset, underlying, floatRate, clearingAgency);
}
else //反向先平仓,有剩余开仓
{
AvgDealUnwind(flowClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
AvgDealUnwind(flowClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency);
}
}
/// <summary>
@@ -1122,7 +1099,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var swapTradeService = new SwapTradeService(UserInfo);
@@ -1137,7 +1113,7 @@ namespace YLErp.Modules.SwapModule
var flowSameClone = DataHelper.DeepCopyObject(flowSame);
var flowNegClone = DataHelper.DeepCopyObject(flowNeg);
//先平反向
var trade= AvgDealUnwind(flowNegClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
var trade= AvgDealUnwind(flowNegClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency);
var newFlowList = new List<swap_flow>();
if (trade!=null)
{
@@ -1162,12 +1138,12 @@ namespace YLErp.Modules.SwapModule
{
flowSameClone.TradingQty = flowQty;
flowSameClone.TradingAmount = flowSameClone.TradingQty;
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clearingAgency);
}
}
else
{
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clearingAgency);
}
}
/// <summary>
@@ -1190,7 +1166,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency)
{
var swapTradeService = new SwapTradeService(UserInfo);
@@ -1227,7 +1202,7 @@ namespace YLErp.Modules.SwapModule
{
swapFlow.TradingQty = flowQty;
swapFlow.TradingAmount = swapFlow.TradingQty* swapFlow.TradingAmountAvg;
return NewSwapTrade(swapFlow, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
return NewSwapTrade(swapFlow, client, asset, underlying, floatRate, clearingAgency);
}
return null;
}
@@ -1251,7 +1226,6 @@ namespace YLErp.Modules.SwapModule
AssetUnit asset,
underlying_manager underlying,
SwapFloatRate floatRate,
client_marginrate clientMarginTemplate,
string clearingAgency,
bool needOpen,
bool cashNeedAfter
@@ -1269,7 +1243,7 @@ namespace YLErp.Modules.SwapModule
{
SetNewOpenData(flowMergeMax, flowMergeSameClone, dealResult.Item4);
}
return swapTradeService.NewSwapTrade(flowMergeSameClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
return swapTradeService.NewSwapTrade(flowMergeSameClone, client, asset, underlying, floatRate, clearingAgency);
}
return null;