流水簿记修改为先进先出逻辑
This commit is contained in:
@@ -417,7 +417,7 @@ 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.Type == "品种" && x.ValueDate <= valueDate).OrderByDescending(o => o.ValueDate).ToList();
|
||||
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)
|
||||
{
|
||||
@@ -442,9 +442,9 @@ namespace YLErp.Modules.SwapModule
|
||||
/// </summary>
|
||||
/// <param name="mergeList"></param>
|
||||
/// <param name="valueDate"></param>
|
||||
public void MergeAvgModeCompose(List<swap_flow> swapFlows, DateTime valueDate, Action<int>? action)
|
||||
public void MergeAvgModeCompose(List<swap_flow_merge> mergeList, DateTime valueDate, Action<int>? action)
|
||||
{
|
||||
var flowquery = swapFlows.GroupBy(g => g.ClientId);
|
||||
var flowquery = mergeList.GroupBy(g => g.ClientId);
|
||||
var flowCount = flowquery.Count();
|
||||
if (flowCount == 0)
|
||||
{
|
||||
@@ -456,13 +456,14 @@ 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, ref dealCount, action);
|
||||
MergeAvgModelItem(groupItem, swaptrades, swapPositions, floatRateQuery, clientMarginTemplates, ref dealCount, action);
|
||||
}
|
||||
}
|
||||
public void UpdateSwapFlowState(List<swap_flow> swapFlows)
|
||||
@@ -583,10 +584,11 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="direction"></param>
|
||||
/// <param name="matuirityDate"></param>
|
||||
/// <exception cref="ServiceException"></exception>
|
||||
private void MergeAvgModelItem(IGrouping<int?, swap_flow> groupItem,
|
||||
private void MergeAvgModelItem(IGrouping<int?, swap_flow_merge> groupItem,
|
||||
List<trade> swaptrades,
|
||||
List<swap_position> swapPositions,
|
||||
IQueryable<SwapFloatRate> floatRateQuery, ref int dealCount, Action<int>? action)
|
||||
IQueryable<SwapFloatRate> floatRateQuery,
|
||||
List<client_marginrate> client_Marginrates, ref int dealCount, Action<int>? action)
|
||||
{
|
||||
var clientId = groupItem.Key;
|
||||
var client = DataCacheProvider.GetClientDataSource().GetData(clientId ?? 0);
|
||||
@@ -597,7 +599,11 @@ 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)
|
||||
@@ -617,11 +623,11 @@ namespace YLErp.Modules.SwapModule
|
||||
if (!hasPayPosition)//没有持仓
|
||||
{
|
||||
var bsType = mergeList.OrderBy(o => o.OptTime).First().BsType;
|
||||
AvgDealNoPosition(mergeList, client, asset, underlying, floatRate, clearingAgency, bsType);
|
||||
AvgDealNoPosition(mergeList, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, bsType);
|
||||
}
|
||||
else
|
||||
{
|
||||
AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clearingAgency);
|
||||
AvgDealHasPosition(mergeList, client, asset, underlying, floatRate, clientSwapPositionList, clientSwapTrades, clientMarginTemplate, clearingAgency);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -697,178 +703,90 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
private trade AvgDealNoPosition(List<swap_flow> swapFlows,
|
||||
private trade AvgDealNoPosition(List<swap_flow_merge> swapFlows,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency,
|
||||
int byType)
|
||||
{
|
||||
var negativeFlows = swapFlows.Where(x => x.BsType != byType).OrderBy(o => o.OptTime).ToList();
|
||||
var sameFlows = swapFlows.Where(x => x.BsType == byType).OrderBy(o => o.OptTime).ToList();
|
||||
if (negativeFlows.Count == 0)
|
||||
var negativeFlow = swapFlows.Where(x => x.BsType != byType).FirstOrDefault();
|
||||
var sameFlow = swapFlows.Where(x => x.BsType == byType).FirstOrDefault();
|
||||
if (negativeFlow==null)
|
||||
{
|
||||
return DealOneDirectionFlows(sameFlows, client, asset, underlying, floatRate, clearingAgency);
|
||||
return NewSwapTrade(sameFlow, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
|
||||
}
|
||||
return DealTwoDirectionFlows(sameFlows, negativeFlows, client, asset, underlying, floatRate, clearingAgency);
|
||||
}
|
||||
/// <summary>
|
||||
/// 当前无持仓,且只有一个方向的流水合成簿记
|
||||
/// </summary>
|
||||
/// <param name="sameFlows"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
/// <param name="clearingAgency"></param>
|
||||
private trade DealOneDirectionFlows(List<swap_flow> sameFlows,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
string clearingAgency)
|
||||
{
|
||||
List<SwapFlowDeal> swapFlowDeals = new List<SwapFlowDeal>();
|
||||
foreach (var flow in sameFlows)
|
||||
{
|
||||
SwapFlowDeal swapFlowDeal = GetSwapFlowDeal(flow, flow.TradingQty, (int)OpenCloseEnum.开仓, flow.TradingFee, null);
|
||||
swapFlowDeals.Add(swapFlowDeal);
|
||||
}
|
||||
return NewSwapTrade(swapFlowDeals, client, asset, underlying, floatRate, clearingAgency);
|
||||
return DealTwoDirectionFlows(sameFlow, negativeFlow, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
}
|
||||
/// <summary>
|
||||
/// 当前无持仓,且有2个方向流水合成簿记
|
||||
/// </summary>
|
||||
/// <param name="sameFlows"></param>
|
||||
/// <param name="negativeFlows"></param>
|
||||
/// <param name="sameFlow"></param>
|
||||
/// <param name="negativeFlow"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
/// <param name="clientMarginTemplate"></param>
|
||||
/// <param name="clearingAgency"></param>
|
||||
private trade DealTwoDirectionFlows(List<swap_flow> sameFlows,
|
||||
List<swap_flow> negativeFlows,
|
||||
/// <returns></returns>
|
||||
private trade DealTwoDirectionFlows(swap_flow_merge sameFlow,
|
||||
swap_flow_merge negativeFlow,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency)
|
||||
{
|
||||
var swapTradeService = new SwapTradeService(UserInfo);
|
||||
var sameQty = sameFlows.Sum(s => s.TradingQty);
|
||||
var negaQty = negativeFlows.Sum(s => s.TradingQty);
|
||||
//第一次开仓流水拆分明细
|
||||
List<SwapFlowDeal> openFirstFlows = new List<SwapFlowDeal>();
|
||||
//第一次平仓流水拆分明细
|
||||
List<SwapFlowDeal> unwindFirstFlows = new List<SwapFlowDeal>();
|
||||
//第二次开仓流水拆分明细,最多可能存在第二次开仓
|
||||
List<SwapFlowDeal> openLastFlows = new List<SwapFlowDeal>();
|
||||
List<swap_flow> negaFlowClones = DataHelper.DeepCopyObject(negativeFlows);
|
||||
List<swap_flow> sameFlowClones = DataHelper.DeepCopyObject(sameFlows);
|
||||
unwindFirstFlows = GetRemainderFlows(negaFlowClones, sameQty, null);
|
||||
var unwindQty = unwindFirstFlows.Sum(s => s.TradingQty);
|
||||
//日内轧差全开全平
|
||||
//同向总数量>=反向总数量,同向新开仓,反向流水全部平仓,同向剩余新开仓
|
||||
if (sameQty >= negaQty)
|
||||
var sameQty = sameFlow.TradingQty;
|
||||
var negaQty = negativeFlow.TradingQty;
|
||||
swap_flow_merge negaFlowClone = DataHelper.DeepCopyObject(negativeFlow);
|
||||
swap_flow_merge sameFlowClone = DataHelper.DeepCopyObject(sameFlow);
|
||||
//先开数量大的,再用小的平仓
|
||||
if (sameQty < negaQty)
|
||||
{
|
||||
openFirstFlows = GetRemainderFlows(sameFlowClones, negaQty, null);
|
||||
openFirstFlows.ForEach(x => { x.OpenFlag = (int)OpenCloseEnum.开仓; });
|
||||
var openQty = openFirstFlows.Sum(s => s.TradingQty);
|
||||
if (openQty < negaQty)
|
||||
{
|
||||
var sameFlow = sameFlowClones.First();
|
||||
var unwindFirstQty = negaQty - openQty;
|
||||
var unwindFee = sameFlow.TradingFee * unwindFirstQty / sameFlow.TradingQty;
|
||||
SwapFlowDeal firstOpenFlowDeal = GetSwapFlowDeal(sameFlow, unwindFirstQty, (int)OpenCloseEnum.开仓, unwindFee, null);
|
||||
openFirstFlows.Add(firstOpenFlowDeal);
|
||||
sameFlow.TradingQty = sameFlow.TradingQty - unwindFirstQty;
|
||||
sameFlow.TradingFee = sameFlow.TradingFee - unwindFee;
|
||||
sameFlow.TradingAmount = sameFlow.TradingQty;
|
||||
}
|
||||
//反向流水全部平仓
|
||||
foreach (var negaFlow in negaFlowClones)
|
||||
{
|
||||
SwapFlowDeal swapFlowDeal = GetSwapFlowDeal(negaFlow, negaFlow.TradingQty, (int)OpenCloseEnum.平仓, negaFlow.TradingFee, null);
|
||||
unwindFirstFlows.Add(swapFlowDeal);
|
||||
}
|
||||
foreach (var sameFlow in sameFlowClones)
|
||||
{
|
||||
SwapFlowDeal swapFlowDeal = GetSwapFlowDeal(sameFlow, sameFlow.TradingQty, (int)OpenCloseEnum.开仓, sameFlow.TradingFee, null);
|
||||
openLastFlows.Add(swapFlowDeal);
|
||||
}
|
||||
sameFlowClone= DataHelper.DeepCopyObject(negativeFlow);
|
||||
negaFlowClone = DataHelper.DeepCopyObject(sameFlow);
|
||||
}
|
||||
else //同向总数量 < 反向总数量,同向先开仓,反向流水部分平仓,反向剩余新开仓
|
||||
{
|
||||
if (unwindQty < sameQty)
|
||||
{
|
||||
var negaFlow = negaFlowClones.First();
|
||||
var unwindFirstQty = sameQty - unwindQty;
|
||||
var unwindFee = negaFlow.TradingFee * unwindFirstQty / negaFlow.TradingQty;
|
||||
SwapFlowDeal swapFirstFlowDeal = GetSwapFlowDeal(negaFlow, unwindFirstQty, (int)OpenCloseEnum.平仓, unwindFee, null);
|
||||
unwindFirstFlows.Add(swapFirstFlowDeal);
|
||||
negaFlow.TradingQty = negaFlow.TradingQty - unwindFirstQty;
|
||||
negaFlow.TradingFee = negaFlow.TradingFee - unwindFee;
|
||||
negaFlow.TradingAmount = negaFlow.TradingQty;
|
||||
}
|
||||
foreach (var flow in sameFlowClones)
|
||||
{
|
||||
SwapFlowDeal swapFlowDeal = GetSwapFlowDeal(flow, flow.TradingQty, (int)OpenCloseEnum.开仓, flow.TradingFee, null);
|
||||
openFirstFlows.Add(swapFlowDeal);
|
||||
}
|
||||
foreach (var minFlow in negaFlowClones)
|
||||
{
|
||||
SwapFlowDeal swapFlowDeal = GetSwapFlowDeal(minFlow, minFlow.TradingQty, (int)OpenCloseEnum.开仓, minFlow.TradingFee, null);
|
||||
openLastFlows.Add(swapFlowDeal);
|
||||
}
|
||||
}
|
||||
|
||||
var trade = NewSwapTrade(openFirstFlows, client, asset, underlying, floatRate, clearingAgency);
|
||||
unwindFirstFlows.ForEach(x => { x.SwapTradeId = trade.id; x.SwapTradeNo = trade.TradeNumber; });
|
||||
DbContext.swap_flow_deal.AddRange(unwindFirstFlows);
|
||||
var mergeUnwindFlows = SummaryFlow(unwindFirstFlows);
|
||||
var unwindMergeFlow = mergeUnwindFlows.First();
|
||||
var trade = NewSwapTrade(sameFlowClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
// 平仓
|
||||
new SwapDealService(UserInfo).AuotoSwapUnwind(trade.id,
|
||||
unwindMergeFlow.TradingAmountAvg,
|
||||
unwindMergeFlow.TradingAmountFeeAvg,
|
||||
unwindMergeFlow.TradingAmountNetFeeAvg ?? 0,
|
||||
unwindMergeFlow.TradingAmountNetAvg ?? 0,
|
||||
unwindMergeFlow.OccurTime,
|
||||
unwindMergeFlow.TradingQty,
|
||||
unwindMergeFlow.TradingQty,
|
||||
unwindMergeFlow.TradingFeePending);
|
||||
if (openLastFlows.Count > 0)
|
||||
{
|
||||
return NewSwapTrade(openLastFlows, client, asset, underlying, floatRate, clearingAgency);
|
||||
}
|
||||
negaFlowClone.TradingAmountAvg,
|
||||
negaFlowClone.TradingAmountFeeAvg,
|
||||
negaFlowClone.TradingAmountNetFeeAvg ?? 0,
|
||||
negaFlowClone.TradingAmountNetAvg ?? 0,
|
||||
negaFlowClone.OccurTime,
|
||||
negaFlowClone.TradingQty,
|
||||
negaFlowClone.TradingQty,
|
||||
negaFlowClone.TradingFeePending);
|
||||
return trade;
|
||||
}
|
||||
/// <summary>
|
||||
/// 流水拆分后新开仓
|
||||
/// 流水新开仓
|
||||
/// </summary>
|
||||
/// <param name="openFlows"></param>
|
||||
/// <param name="flowMergeFirst"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
/// <param name="clientMarginTemplate"></param>
|
||||
/// <param name="clearingAgency"></param>
|
||||
/// <returns></returns>
|
||||
private trade NewSwapTrade(List<SwapFlowDeal> openFlows,
|
||||
private trade NewSwapTrade(swap_flow_merge flowMergeFirst,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency)
|
||||
{
|
||||
var swapTradeService = new SwapTradeService(UserInfo);
|
||||
var mergeFlows = SummaryFlow(openFlows);
|
||||
swap_flow_merge flowMergeFirst = mergeFlows.First();
|
||||
var trade = swapTradeService.NewSwapTrade(flowMergeFirst, client, asset, underlying, floatRate, null, clearingAgency, LongShortStructType);
|
||||
var trade = swapTradeService.NewSwapTrade(flowMergeFirst, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency, LongShortStructType);
|
||||
flowMergeFirst.SwapTradeNo = trade.TradeNumber;
|
||||
flowMergeFirst.SwapTradeId = trade.id;
|
||||
openFlows.ForEach(x => { x.SwapTradeId = trade.id; x.SwapTradeNo = trade.TradeNumber; });
|
||||
DbContext.swap_flow_deal.AddRange(openFlows);
|
||||
DbContext.SaveChanges();
|
||||
return trade;
|
||||
}
|
||||
@@ -976,24 +894,25 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="floatRate"></param>
|
||||
/// <param name="clientSwapPositionList"></param>
|
||||
/// <param name="clientSwapTrades"></param>
|
||||
private void AvgDealHasPosition(List<swap_flow> flowList,
|
||||
private void AvgDealHasPosition(List<swap_flow_merge> flowList,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
List<swap_position> clientSwapPositionList,
|
||||
List<trade> clientSwapTrades,
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency)
|
||||
{
|
||||
var firstFlow = flowList.First();
|
||||
var negaFlowExist = flowList.Any(x => x.BsType != firstFlow.BsType);
|
||||
if (!negaFlowExist)//只有同向流水情况
|
||||
var negativeFlow = flowList.Where(x => x.BsType != firstFlow.BsType).FirstOrDefault();
|
||||
if (negativeFlow==null)//只有同向流水情况
|
||||
{
|
||||
AvgDealSingleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency);
|
||||
NewSwapTrade(firstFlow, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
}
|
||||
else
|
||||
{
|
||||
AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clearingAgency);
|
||||
AvgDealDoubleFlow(flowList, clientSwapPositionList, clientSwapTrades, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
@@ -1073,38 +992,6 @@ namespace YLErp.Modules.SwapModule
|
||||
flowMergeClone.TradingAmountNetFeeAvg = flowMergeClone.TradingAmountNetAvg + ratio * flowMergeClone.TradingFeePending / flowMergeClone.TradingQty;
|
||||
}
|
||||
/// <summary>
|
||||
/// 加权平均处理单条流水情况
|
||||
/// </summary>
|
||||
/// <param name="flowList"></param>
|
||||
/// <param name="clientSwapPositionList"></param>
|
||||
/// <param name="clientSwapTrades"></param>
|
||||
/// <param name="matuirityDate"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
private void AvgDealSingleFlow(List<swap_flow> flowList,
|
||||
List<swap_position> clientSwapPositionList,
|
||||
List<trade> clientSwapTrades,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
string clearingAgency)
|
||||
{
|
||||
swap_flow flowMergeMax = flowList.First();
|
||||
var negaSwapPositions = clientSwapPositionList.Where(x => x.PositionType != flowMergeMax.BsType).ToList();
|
||||
List<swap_flow> flowClones = DataHelper.DeepCopyObject(flowList);
|
||||
if (negaSwapPositions.Count > 0)//流水与持仓反向
|
||||
{
|
||||
AvgDealUnwind(flowClones, clientSwapTrades, negaSwapPositions, client, asset, underlying, floatRate, clearingAgency,true);
|
||||
}
|
||||
else //只存在同向交易,同向流水合并新开仓
|
||||
{
|
||||
DealOneDirectionFlows(flowClones, client, asset, underlying, floatRate, clearingAgency);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 处理多条流水情况
|
||||
/// </summary>
|
||||
/// <param name="mergeList"></param>
|
||||
@@ -1174,64 +1061,92 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
public void AvgDealDoubleFlow(List<swap_flow> flowList,
|
||||
public void AvgDealDoubleFlow(List<swap_flow_merge> flowList,
|
||||
List<swap_position> clientSwapPositionList,
|
||||
List<trade> clientSwapTrades,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency)
|
||||
{
|
||||
var swapTradeService = new SwapTradeService(UserInfo);
|
||||
var firstPosi = clientSwapPositionList.First();
|
||||
var swapPositions = clientSwapPositionList.Where(x => x.PositionType == firstPosi.PositionType).ToList();
|
||||
var posiQty = swapPositions.Sum(s => s.PosiQuantity);
|
||||
var flowSames = flowList.Where(x => x.BsType == firstPosi.PositionType).ToList();
|
||||
var flowNegs = flowList.Where(x => x.BsType != firstPosi.PositionType).ToList();
|
||||
var negaBsType= flowNegs.First().BsType;
|
||||
var flowSame = flowList.Where(x => x.BsType == firstPosi.PositionType).First();
|
||||
var flowNeg = flowList.Where(x => x.BsType != firstPosi.PositionType).First();
|
||||
var negaBsType= flowNeg.BsType;
|
||||
|
||||
var sameQty = posiQty + flowSames.Sum(s => s.TradingQty);
|
||||
var flowSameClones = DataHelper.DeepCopyObject(flowSames);
|
||||
var flowNegClones = DataHelper.DeepCopyObject(flowNegs);
|
||||
var sameQty = posiQty + flowSame.TradingQty;
|
||||
var flowSameClone = DataHelper.DeepCopyObject(flowSame);
|
||||
var flowNegClone = DataHelper.DeepCopyObject(flowNeg);
|
||||
//先平反向
|
||||
AvgDealUnwind(flowNegClones, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clearingAgency,false);
|
||||
var trade= AvgDealUnwind(flowNegClone, clientSwapTrades, swapPositions, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
var newFlowList = new List<swap_flow>();
|
||||
var openBystype = firstPosi.PositionType;
|
||||
if (flowNegClones.Count > 0)
|
||||
if (trade!=null)
|
||||
{
|
||||
newFlowList.AddRange(flowNegClones);
|
||||
openBystype = negaBsType;
|
||||
var flowQty = flowSameClone.TradingQty;
|
||||
var currentPosiQty = flowNegClone.TradingQty;
|
||||
var newOpenQty = currentPosiQty - flowQty;
|
||||
var unwindQty = newOpenQty > 0 ? flowQty : currentPosiQty;
|
||||
var unwindFee = flowSameClone.TradingFeePending * unwindQty / currentPosiQty;
|
||||
|
||||
flowQty = flowQty - unwindQty;
|
||||
// 平仓
|
||||
new SwapDealService(UserInfo).AuotoSwapUnwind(trade.id,
|
||||
flowSameClone.TradingAmountAvg,
|
||||
flowSameClone.TradingAmountFeeAvg,
|
||||
flowSameClone.TradingAmountNetFeeAvg ?? 0,
|
||||
flowSameClone.TradingAmountNetAvg ?? 0,
|
||||
flowSameClone.OccurTime,
|
||||
flowSameClone.TradingQty,
|
||||
unwindQty,
|
||||
unwindFee);
|
||||
if (flowQty>0)
|
||||
{
|
||||
var unwindPercent = 1 - (flowQty / flowSameClone.TradingQty);
|
||||
var fee = (1 - unwindPercent) * flowSameClone.TradingFeePending;
|
||||
flowSameClone.TradingQty = flowQty;
|
||||
flowSameClone.TradingAmount = flowSameClone.TradingQty;
|
||||
flowSameClone.TradingFeePending = fee;
|
||||
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NewSwapTrade(flowSameClone, client, asset, underlying, floatRate, clientMarginTemplate, clearingAgency);
|
||||
}
|
||||
newFlowList.AddRange(flowSameClones);
|
||||
//有历史持仓按反方向先开仓
|
||||
AvgDealNoPosition(newFlowList, client, asset, underlying, floatRate, clearingAgency, openBystype);
|
||||
}
|
||||
/// <summary>
|
||||
/// 有持仓流水
|
||||
/// 有持仓流水反向平仓
|
||||
/// </summary>
|
||||
/// <param name="swapFlows"></param>
|
||||
/// <param name="swapFlow"></param>
|
||||
/// <param name="trades"></param>
|
||||
/// <param name="swapPositions"></param>
|
||||
/// <param name="client"></param>
|
||||
/// <param name="asset"></param>
|
||||
/// <param name="underlying"></param>
|
||||
/// <param name="floatRate"></param>
|
||||
/// <param name="clientMarginTemplate"></param>
|
||||
/// <param name="clearingAgency"></param>
|
||||
private void AvgDealUnwind(List<swap_flow> swapFlows,
|
||||
/// <returns></returns>
|
||||
private trade AvgDealUnwind(swap_flow_merge swapFlow,
|
||||
List<trade> trades,
|
||||
List<swap_position> swapPositions,
|
||||
Client client,
|
||||
AssetUnit asset,
|
||||
underlying_manager underlying,
|
||||
SwapFloatRate floatRate,
|
||||
string clearingAgency,
|
||||
bool needAdd)
|
||||
client_marginrate clientMarginTemplate,
|
||||
string clearingAgency)
|
||||
{
|
||||
var swapTradeService = new SwapTradeService(UserInfo);
|
||||
var flowQty = swapFlow.TradingQty;
|
||||
foreach (var posi in swapPositions)
|
||||
{
|
||||
if (swapFlows.Count == 0)
|
||||
if (swapFlow==null|| flowQty == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -1239,40 +1154,34 @@ namespace YLErp.Modules.SwapModule
|
||||
if (td != null)
|
||||
{
|
||||
var posiQty = posi.PosiQuantity;
|
||||
var flowQty = swapFlows.Sum(s => s.TradingQty);
|
||||
var unwindSwapFlowDeals = GetRemainderFlows(swapFlows, posiQty, td);
|
||||
var unwindQty = unwindSwapFlowDeals.Sum(x => x.TradingQty);
|
||||
if (unwindQty < posiQty && swapFlows.Count > 0)
|
||||
{
|
||||
var unwindSwapFlow = swapFlows.First();
|
||||
var flowUnindQty = posiQty - unwindQty;
|
||||
var unwindFee = unwindSwapFlow.TradingQty == 0 ? 0 : unwindSwapFlow.TradingFee * flowUnindQty / unwindSwapFlow.TradingQty;
|
||||
unwindSwapFlow.TradingQty = unwindSwapFlow.TradingQty - flowUnindQty;
|
||||
unwindSwapFlow.TradingFee = unwindSwapFlow.TradingFee - unwindFee;
|
||||
unwindSwapFlow.TradingAmount = unwindSwapFlow.TradingQty;
|
||||
var unwindFlowDeal = GetSwapFlowDeal(unwindSwapFlow, flowUnindQty, (int)OpenCloseEnum.平仓, unwindFee, td);
|
||||
unwindSwapFlowDeals.Add(unwindFlowDeal);
|
||||
}
|
||||
DbContext.swap_flow_deal.AddRange(unwindSwapFlowDeals);
|
||||
var unwindMergeFlow = SummaryFlow(unwindSwapFlowDeals).First();
|
||||
var newOpenQty = posiQty - flowQty;
|
||||
var unwindQty = newOpenQty > 0 ? flowQty : posiQty;
|
||||
var unwindFee = swapFlow.TradingFeePending* unwindQty / flowQty;
|
||||
|
||||
flowQty = flowQty - unwindQty;
|
||||
// 平仓
|
||||
new SwapDealService(UserInfo).AuotoSwapUnwind(td.id,
|
||||
unwindMergeFlow.TradingAmountAvg,
|
||||
unwindMergeFlow.TradingAmountFeeAvg,
|
||||
swapFlow.TradingAmountAvg,
|
||||
swapFlow.TradingAmountFeeAvg,
|
||||
|
||||
unwindMergeFlow.TradingAmountNetFeeAvg ?? 0,
|
||||
unwindMergeFlow.TradingAmountNetAvg ?? 0,
|
||||
unwindMergeFlow.OccurTime,
|
||||
unwindMergeFlow.TradingQty,
|
||||
posiQty,
|
||||
unwindMergeFlow.TradingFeePending);
|
||||
swapFlow.TradingAmountNetFeeAvg ?? 0,
|
||||
swapFlow.TradingAmountNetAvg ?? 0,
|
||||
swapFlow.OccurTime,
|
||||
swapFlow.TradingQty,
|
||||
unwindQty,
|
||||
unwindFee);
|
||||
}
|
||||
}
|
||||
if (swapFlows.Count > 0 && needAdd)
|
||||
if (flowQty > 0) //平仓完有剩余流水,
|
||||
{
|
||||
var bsType = swapFlows.First().BsType;
|
||||
AvgDealNoPosition(swapFlows, client, asset, underlying, floatRate, clearingAgency, bsType);
|
||||
var unwindPercent =1- (flowQty / swapFlow.TradingQty);
|
||||
var fee = (1 - unwindPercent) * swapFlow.TradingFeePending;
|
||||
swapFlow.TradingQty = flowQty;
|
||||
swapFlow.TradingAmount = swapFlow.TradingQty;
|
||||
swapFlow.TradingFeePending = fee;
|
||||
return NewSwapTrade(swapFlow, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/// <summary>
|
||||
/// 2条流水处理明细
|
||||
@@ -1422,95 +1331,5 @@ namespace YLErp.Modules.SwapModule
|
||||
}
|
||||
return (0, 0, false, null);
|
||||
}
|
||||
/// <summary>
|
||||
/// 定时任务合成持仓
|
||||
/// </summary>
|
||||
/// <param name="flowList"></param>
|
||||
/// <param name="swapPositions"></param>
|
||||
/// <param name="clientPosition"></param>
|
||||
/// <param name="multiplier"></param>
|
||||
/// <param name="positionType"></param>
|
||||
|
||||
public void MergeSwapPositionAvg(List<swap_flow> flowList, List<swap_position> swapPositions, ClientPosition clientPosition, decimal multiplier, int positionType)
|
||||
{
|
||||
var hasPayPosition = swapPositions != null && swapPositions.Count > 0;
|
||||
var posiQty = swapPositions == null ? 0 : swapPositions.Sum(x => x.PosiQuantity);
|
||||
var flowSames = flowList.Where(x => x.BsType == positionType).OrderBy(o => o.OptTime).ToList();
|
||||
var flowNegatives = flowList.Where(x => x.BsType != positionType).OrderBy(o => o.OptTime).ToList();
|
||||
var sameQty = flowSames.Sum(s => s.TradingQty);
|
||||
var negaQty = flowNegatives.Sum(s => s.TradingQty);
|
||||
|
||||
if (sameQty + posiQty < negaQty)
|
||||
{
|
||||
var negaPosiType = flowNegatives.First().BsType;
|
||||
clientPosition.side = negaPosiType - 1;
|
||||
}
|
||||
var posiType = clientPosition.id == 0 ? 0 : clientPosition.side;
|
||||
List<swap_flow> maxFlowClones = new List<swap_flow>(flowSames);
|
||||
var mergeFlow = new swap_flow_merge();
|
||||
if (hasPayPosition)//有日终持仓
|
||||
{
|
||||
var posiFlows = ConvertToSwapFlow(swapPositions, (int)clientPosition.client_id);
|
||||
maxFlowClones.AddRange(posiFlows);
|
||||
maxFlowClones = maxFlowClones.OrderBy(o => o.id).ToList();
|
||||
sameQty = maxFlowClones.Sum(s => s.TradingQty);
|
||||
}
|
||||
var maxQty = sameQty;
|
||||
var minQty = negaQty;
|
||||
if (clientPosition.side + 1 != positionType)
|
||||
{
|
||||
maxQty = negaQty;
|
||||
minQty = sameQty;
|
||||
maxFlowClones = new List<swap_flow>(flowNegatives);
|
||||
}
|
||||
maxFlowClones.ForEach(x => { x.OccurTime = DateTime.Now.Date; });
|
||||
var unwindDeals = GetRemainderFlows(maxFlowClones, minQty, null);
|
||||
var unwindQty = unwindDeals.Sum(s => s.TradingQty);
|
||||
if (minQty != 0 && unwindQty < maxQty)
|
||||
{
|
||||
var firstFlow = maxFlowClones.First();
|
||||
var unwindFlowQty = minQty - unwindQty;
|
||||
var unwindFee = firstFlow.TradingFee * unwindFlowQty / firstFlow.TradingQty;
|
||||
firstFlow.TradingQty = firstFlow.TradingQty - unwindFlowQty;
|
||||
firstFlow.TradingFee = firstFlow.TradingFee - unwindFee;
|
||||
firstFlow.TradingAmount = firstFlow.TradingQty;
|
||||
}
|
||||
var mergeList = SummaryFlow(maxFlowClones, false);
|
||||
mergeFlow = mergeList.Count>0? mergeList.First():new swap_flow_merge();
|
||||
clientPosition.commission = mergeFlow.TradingFee;
|
||||
clientPosition.position_qty = mergeFlow.TradingQty / 10000;
|
||||
clientPosition.position_notional_principal = mergeFlow.TradingQty;
|
||||
clientPosition.deal_full_price_avg = mergeFlow.TradingAmountAvg * multiplier;
|
||||
clientPosition.deal_price_avg = mergeFlow.TradingAmountNetAvg * multiplier;
|
||||
}
|
||||
/// <summary>
|
||||
/// 将持仓转换为流水
|
||||
/// </summary>
|
||||
/// <param name="positions"></param>
|
||||
/// <param name="clientId"></param>
|
||||
/// <returns></returns>
|
||||
private List<swap_flow> ConvertToSwapFlow(List<swap_position> positions, int clientId)
|
||||
{
|
||||
List<swap_flow> flows = new List<swap_flow>();
|
||||
foreach (var item in positions)
|
||||
{
|
||||
swap_flow flow = new swap_flow();
|
||||
flow.TradingAmount = item.PosiNotionalValue;
|
||||
flow.TradingAmountAvg = item.PosiGrossPrice;
|
||||
flow.TradingAmountFeeAvg = item.PosiNetPrice;
|
||||
flow.TradingAmountNet = item.PosiNetNoFeePrice;
|
||||
flow.TradingAmountNetFee = item.PosiNetFeePrice;
|
||||
flow.TradingFee = item.PosiTradingFeePending;
|
||||
flow.TradingQty = item.PosiQuantity;
|
||||
flow.UnderlyingCode = item.UnderlyingCode;
|
||||
flow.OccurTime = DateTime.Now.Date;
|
||||
flow.ContractSize = item.ContractSize;
|
||||
flow.ClientId = clientId;
|
||||
flow.BsType = item.PositionType;
|
||||
flow.SettleDate = item.PosiStartDate;
|
||||
flows.Add(flow);
|
||||
}
|
||||
return flows;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,14 +70,14 @@ namespace YLErp.Web.Hubs
|
||||
//var dmaFlows = swapFlows.Where(x => dmaClientIds.Contains(x.ClientId)).ToList();
|
||||
|
||||
#region DMA合成持仓
|
||||
if (swapFlows.Count > 0)
|
||||
if (mergeList.Count > 0)
|
||||
{
|
||||
currentStep = $"正在合成簿记:共{swapFlows.Count}条流水";
|
||||
currentStep = $"正在合成簿记:共{mergeList.Count}条合成流水";
|
||||
await client.SendAsync("ReceiveMessage", currentStep);
|
||||
|
||||
service.MergeAvgModeCompose(swapFlows, req.tradeDate, (dealCount) =>
|
||||
service.MergeAvgModeCompose(mergeList, req.tradeDate, (dealCount) =>
|
||||
{
|
||||
currentStep = $"正在合成簿记:{dealCount}/{swapFlows.Count}";
|
||||
currentStep = $"正在合成簿记:{dealCount}/{mergeList.Count}";
|
||||
client.SendAsync("ReceiveMessage", currentStep);
|
||||
});
|
||||
currentStep = "簿记合成完毕";
|
||||
|
||||
Reference in New Issue
Block a user