名义本金算价格

This commit is contained in:
吴方海
2025-04-11 16:25:46 +08:00
parent ad0a8fa0d9
commit cbe8b2dc91
10 changed files with 214 additions and 388 deletions
@@ -954,13 +954,13 @@ namespace YLErp.BLL.Eod
};
var todayPostionList = todayPositionQuery.ToArray();
//using var bondDb = new BondOmsDBContext();
//var clientLongIds = new List<long>();
//clientIds.ForEach(item =>
//{
// clientLongIds.Add(Convert.ToInt64(item));
//});
//var swapPositionQuery = bondDb.client_position.Where(x => clientLongIds.Contains(x.client_id ?? 0)).ToList().GroupBy(g => g.client_id);
using var bondDb = new BondOmsDBContext();
var clientLongIds = new List<long>();
clientIds.ForEach(item =>
{
clientLongIds.Add(Convert.ToInt64(item));
});
var swapPositionQuery = bondDb.client_position.Where(x => clientLongIds.Contains(x.client_id ?? 0)).ToList().GroupBy(g => g.client_id);
//持仓合计
var pQuerySum = from t in todayPostionList
group t by t.ClientId into g
@@ -1048,101 +1048,19 @@ namespace YLErp.BLL.Eod
balance.ClientSellPositionPnl = (parentPositionPnlTotal.FirstOrDefault(x => x.clientId == data.clientId)?.ClientSellPositionPnl ?? 0) + (singlePositionPnlTotal.FirstOrDefault(x => x.clientId == data.clientId)?.ClientSellPositionPnl ?? 0);
}
//foreach (var data in swapPositionQuery)
//{
// var clientId = Convert.ToInt32(data.Key);
// var balance = _clientBalanceDic[clientId];
// var pvSum = data.Sum(s => s.swap_market_value ?? 0);
// var pnlSum = data.Sum(s => s.position_profit_loss ?? 0);
// var preminumSum = data.Sum(s => s.commission ?? 0);
// var dayPnlSum = data.Sum(s => s.today_profit_loss ?? 0);
// balance.PotentialSurpluses += -Convert.ToDouble(pvSum);
// balance.PositionPv += Convert.ToDouble(pvSum);
// balance.RoundedPositionPv += Convert.ToDouble(pvSum);
// balance.PositionPnl += Convert.ToDouble(pnlSum);
// balance.RoundedPositionPnl += Convert.ToDouble(pnlSum);
// balance.PositionPremiumNetCash += Convert.ToDouble(preminumSum);
// //balance.DaliyPnl += Convert.ToDouble(dayPnlSum);
// //balance.RoundedDaliyPnl += Convert.ToDouble(dayPnlSum);
//}
//专业版雪球预付金
if (PS.Config.ErpElement.SuppotSnowballSpecialist)
foreach (var data in swapPositionQuery)
{
//DbContext.SetDebugLog();
var query = from p in DbContext.intraday_trade_position
join sn in DbContext.trade_snowball on p.TradeId equals sn.TradeId
join t in DbContext.trade on p.TradeId equals t.id
where p.ValueDate == _valueDate && clientIds.Contains(p.ClientId)
&& ConsTrade.NeedMarginTradeStatusList.Contains(p.TradeStatus)
&& sn.PrepaymentUsed
select new
{
p.ClientId,
Prepayment = (sn.PrepaymentRatio ?? 0) * t.Notional * (t.SpotPrice ?? 0)
* (t.BuySell == "卖出" ? 1 : -1)
};
var querySum = from q in query
group q by q.ClientId into g
select new
{
ClientId = g.Key,
Prepayment = g.Sum(t => t.Prepayment)
};
var sumPrepayments = querySum.ToArray();
foreach (var item in sumPrepayments)
{
if (_clientBalanceDic.TryGetValue(item.ClientId, out var balance))
{
balance.PrepaymentAmount = item.Prepayment;
}
}
var clientId = Convert.ToInt32(data.Key);
var balance = _clientBalanceDic[clientId];
var pvSum = data.Sum(s => s.swap_market_value ?? 0);
var pnlSum = data.Sum(s => s.position_profit_loss ?? 0);
var posiSum = data.Sum(s => s.position_notional_principal ?? 0);
balance.PotentialSurpluses += Convert.ToDouble(pvSum);
balance.PositionPv += Convert.ToDouble(pvSum);
balance.RoundedPositionPv += Convert.ToDouble(pvSum);
balance.PositionNotionalPrincipal += Convert.ToDouble(posiSum);
}
}
/// <summary>
/// 获取国君互换实时持仓
/// </summary>
private void ProcessClientSwapPosition_GuoJun(DateTime startDate, DateTime lastSettletDate)
{
var underlyDataSource = DataCacheProvider.GetUnderlyingDataSource();
var varietyDataSource = DataCacheProvider.GetVarietyDataSource();
var clientIds = _clientBalanceDic.Keys;
var swap_mannualQuery = DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate <= startDate && x.ValueDate >= lastSettletDate);//取收盘日后的最大日期
if (!swap_mannualQuery.Any())
{
return;
}
var maxValueDate = swap_mannualQuery.Max(x => x.ValueDate);
var eodPositionSwapMannuals = DbContext.eod_trade_position_swap_mannual.Where(x => x.ValueDate == maxValueDate && clientIds.Contains(x.ClientId)).ToLookup(n => n.ClientId);
foreach (var item in eodPositionSwapMannuals)
{
double swapMargin = 0.0;
double swappv = 0.0;
double swappnl = 0.0;
var eodPostionsSwaps = item.ToList();
var clientBalance = _clientBalanceDic[item.Key];
foreach (var x in eodPostionsSwaps)
{
var underly = underlyDataSource.GetData(x.UnderlyingCode);
var variety = varietyDataSource.GetData(underly.UnderlyingTypeId);
_currencyProvider.TryGetCurrencyRate(variety.QuoteCurrency, clientBalance.SettlementCurrency, out var rateObj);
//预付金导入是客户方向,其他值是交易员方向
swapMargin += (x.Margin) * rateObj.Rate;
swappv += (x.PositionPnl - x.TotalFee) * rateObj.Rate;
swappnl += (x.PositionPnl * rateObj.Rate);
}
clientBalance.PositionPnl += swappnl;
clientBalance.PositionPv += swappv;
clientBalance.RoundedPositionPv += swappv;
clientBalance.RoundedPositionPnl += swappnl;
clientBalance.PayableMargin -= swapMargin;
}
}
//获取当日所有出入金记录
private void ProcessClientCash(DateTime lastSettletDate)
{
@@ -1328,7 +1246,7 @@ namespace YLErp.BLL.Eod
var marginList = clientPositions.Where(x =>ConsTrade.InterestMarginModels.Contains(x.InterestMode)).Sum(s=>s.InterestPrincipalFix * (s.InterestDirection == 1 ? -1 : 1));
balance.SwapMargin =Convert.ToDouble(marginList);
balance.PositionCount= clientTradeIds.Count();
balance.PositionNotionalPrincipal = Convert.ToDouble(positions.Sum(s=>s.PosiNotionalValue));//实时
// balance.PositionNotionalPrincipal = Convert.ToDouble(positions.Sum(s=>s.PosiNotionalValue));//实时
}
var eodSwapQuery = DbContext.eod_swap.Where(x => clientIds.Contains(x.ClientId) && x.ValueDate >= lastSettletDate && x.ValueDate <= startDate).AsEnumerable().GroupBy(x => x.SwapTradeId)
.Select(g => g.OrderByDescending(x => x.ValueDate).FirstOrDefault()).ToList();
@@ -1337,6 +1255,8 @@ namespace YLErp.BLL.Eod
eodTradeIds = eodTrades.Select(s => s.id).ToList();
eodSwapQuery = eodSwapQuery.Where(x => eodTradeIds.Contains(x.SwapTradeId)).ToList();
var eodSwapPositions = DbContext.eod_swap_position.Where(x => eodTradeIds.Contains(x.SwapTradeId) && x.ValueDate >= lastSettletDate && x.ValueDate <= startDate && x.PosiDirection > 0);
var swapFlowEvents = DbContext.swap_flow_event.Where(x => x.DataState == (int)SwapFlowDateStateEnum. && x.EventType == (int)SwapFlowEventTypeEnum. && x.EventDate > lastSettletDate && tradeIds.Contains(x.SwapTradeId)).AsNoTracking().ToList();
var swapPositions = DbContext.swap_position.Where(x => tradeIds.Contains(x.SwapTradeId) && x.IsInitial && !x.Invalid && x.PosiDirection > 0).AsNoTracking().ToList();
var eodSwaps = eodSwapQuery.GroupBy(g => g.ClientId).ToList();
foreach (var data in eodSwaps)
{
@@ -1344,33 +1264,46 @@ namespace YLErp.BLL.Eod
var clientEodSwaps = data.GroupBy(g => g.SwapTradeId).ToList();
foreach (var item in clientEodSwaps)
{
var eodSwapList = item.OrderBy(o => o.ValueDate).ToList();
var eodSwap = eodSwapList[eodSwapList.Count - 1];
var lastEodSwap = eodSwapList.Count <= 1 ? null : eodSwapList[eodSwapList.Count - 2];
//潜在行权收益等于实值额
balance.PotentialSurpluses += -Convert.ToDouble(eodSwap.PostionValue);
//持仓市值
balance.PositionPv += Convert.ToDouble(eodSwap.PostionValue);
balance.RoundedPositionPv += Math.Round(Convert.ToDouble(eodSwap.PostionValue), 2);
balance.SellPv += -Convert.ToDouble(eodSwap.MarketValueShort);
//持仓盈亏
var pnl = eodSwap.PostionValue;
var lastPnl = lastEodSwap?.PostionValue;
//当日盈亏
if (eodSwap.ValueDate == startDate)
var lastEodSwap = item.First();
var eodPosi = eodSwapPositions.FirstOrDefault(x => x.ValueDate == lastEodSwap.ValueDate && x.SwapTradeId == lastEodSwap.SwapTradeId);
var posiQty = eodPosi?.PosiQuantity ?? 0;
var flowEvents = swapFlowEvents.Where(x => x.SwapTradeId == item.Key).ToList();
var unwindQty = flowEvents.Sum(s => s.Quantity);
var pnl = lastEodSwap.PostionValue;
decimal unwindPercent = 0;
if (unwindQty != 0)
{
balance.DaliyPnl += Convert.ToDouble(pnl - lastPnl + eodSwap.TdRealizedPnL);
balance.RoundedDaliyPnl += Math.Round(Convert.ToDouble(pnl - lastPnl), 2);
balance.UpdateDate = balance.UpdateDate > eodSwap.OptTime ? balance.UpdateDate : eodSwap.OptTime;
if (posiQty == 0 || unwindQty >= posiQty)
{
pnl = 0;
}
else
{
pnl = pnl - (pnl * unwindQty / posiQty);
}
unwindPercent = posiQty == 0 ? 0 : unwindQty / posiQty;
}
balance.WinLoss += Convert.ToDouble(eodSwap.TdRealizedPnL);
var tdRealizedPnL = flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.InterestClosePnL + s.MarkClosePnl);
var tdRealizedInterestPnL = flowEvents.Where(x => x.EventDate > lastSettletDate).ToList().Sum(s => s.InterestClosePnL * unwindPercent);
var currentEvents = flowEvents.Where(x => x.EventDate == startDate).ToList();
var currentRealizedPnl = currentEvents.Sum(s => s.InterestClosePnL + s.MarkClosePnl);
//潜在行权收益等于实值额
balance.PotentialSurpluses += -Convert.ToDouble(pnl);
//持仓市值
balance.SellPv += -Convert.ToDouble(lastEodSwap.MarketValueShort) * -1;
//当日盈亏
balance.DaliyPnl += Convert.ToDouble(currentRealizedPnl) * -1;
balance.RoundedDaliyPnl += Math.Round(Convert.ToDouble(currentRealizedPnl), 2) * -1;
if (lastEodSwap.ValueDate == startDate)
{
balance.UpdateDate = balance.UpdateDate > lastEodSwap.OptTime ? balance.UpdateDate : lastEodSwap.OptTime;
}
balance.WinLoss += Convert.ToDouble(tdRealizedPnL) * -1;
balance.PositionPnl += Convert.ToDouble(pnl);
balance.RoundedPositionPnl += Math.Round(Convert.ToDouble(pnl), 2);
//期权空头浮动盈利=∑max(期权空头持仓*(期权合约成本价-期权合约现价), 0) 从客户角度看的
balance.ClientSellPositionPnl += Convert.ToDouble(eodSwap.FloatingPnL);
balance.ClientSellPositionPnl += Convert.ToDouble(lastEodSwap.FloatingPnL) * -1;
}
}
}
/// <summary>
@@ -1397,7 +1330,10 @@ namespace YLErp.BLL.Eod
UnderlyingCode = item.security_id,
ClientId = item.client_id ?? 0,
ClientName = item.client_name,
TradingQty = (item.order_qty ?? 0) - (item.last_shares ?? 0)
TradingQty = (item.order_qty ?? 0) - (item.last_shares ?? 0),
TradingAmountAvg = item.full_price ?? 0,
TradingAmountFeeAvg = item.full_price ?? 0,
TradingFee = 0
};
// clientOrder中数量单位为万
flow.TradingQty *= 10000;
@@ -1408,25 +1344,27 @@ namespace YLErp.BLL.Eod
var positionQuery = from t in DbContext.trade.Where(x => clientIds.Contains(x.ClientId) && x.TradeType == "收益互换" && x.ValidState != ConsGlobal.InValid && ConsTrade.PositionTradeStatusList.Contains(x.TradeStatus))
join p in DbContext.swap_position on t.id equals p.SwapTradeId
where !p.IsInitial && !p.Invalid
select new
select new swap_flow
{
t.ClientId,
p.PosiDirection,
p.PosiQuantity,
p.UnderlyingCode,
p.PositionType
ClientId = t.ClientId,
TradingQty = p.PosiQuantity,
UnderlyingCode = p.UnderlyingCode,
BsType = p.PositionType,
TradingAmountAvg = p.PosiGrossPrice,
TradingAmountFeeAvg = p.PosiNetPrice,
TradingFee = 0
};
var positions = positionQuery.ToList();
// step4 将未簿记持仓与已有持仓分别 按客户,标的分组计算各自轧差名义本金
// 取设置的预付金比例
var clientMarginTemplates = DbContext.client_marginrate.Where(x => x.ValueDate <= startDate).OrderByDescending(o => o.ValueDate).AsNoTracking().ToList();
var flowGroup = flows.GroupBy(s => new { s.ClientId, s.UnderlyingCode });
var flowGroup = flows.GroupBy(s => s.ClientId);
foreach (var itemGroup in flowGroup)
{
var balance = clientBalanceDic[itemGroup.Key.ClientId ?? 0];
var balance = clientBalanceDic[itemGroup.Key ?? 0];
//string marginType = balance.ClientType == 1 ? "多空组合" : "品种";
// 获取客户预付金比例设置
var clientMarginTemplate = clientMarginTemplates.FirstOrDefault(x => x.ClientId == itemGroup.Key.ClientId );
var clientMarginTemplate = clientMarginTemplates.FirstOrDefault(x => x.ClientId == itemGroup.Key );
if (clientMarginTemplate == null)
{
clientMarginTemplate = clientMarginTemplates.FirstOrDefault(x => x.ClientId == 0 );
@@ -1436,84 +1374,89 @@ namespace YLErp.BLL.Eod
{
continue;
}
// 获取当前客户当前标的持仓数据,合并后的名义本金数量
var positionLsit = positions.Where(x => x.UnderlyingCode == itemGroup.Key.UnderlyingCode && x.ClientId == itemGroup.Key.ClientId).ToList();
var positionNotional = positionLsit.Sum(s => s.PosiQuantity * (s.PositionType == (int)PositionTypeFlag.Long ? 1 : -1));
//获取虚拟持仓合并后的名义本金数量
var virtualNotional = itemGroup.Sum(s => s.TradingQty * (s.BsType == (int)PositionTypeFlag.Long ? 1 : -1));
decimal money = CalcFrozanMarginMoney(positionNotional, virtualNotional, balance.ClientType == 1, clientMarginTemplate);
balance.FrozenMarginMoney += Convert.ToDouble(money);
var clientPositions = positions.Where(x => x.ClientId == itemGroup.Key).ToList();
foreach (var item in itemGroup.GroupBy(s => s.UnderlyingCode))
{
// 获取当前客户当前标的持仓数据,合并后的名义本金数量
var positionLsit = clientPositions.Where(x => x.UnderlyingCode == item.Key).ToList();
decimal money = CalcDmaMoney(positionLsit, item.ToList(), clientMarginTemplate);
balance.FrozenMarginMoney += Convert.ToDouble(money);
}
}
}
/// <summary>
/// 计算冻结的预付金变化
/// 计算流水带来的资金变化
/// </summary>
/// <param name="positionNotional">持仓名义本金</param>
/// <param name="virtualNotional">虚拟持仓名义本金</param>
/// <param name="dma">是否定义文件类型客户</param>
/// <param name="clientMarginTemplate">预付金设置信息</param>
/// <returns></returns>
private decimal CalcFrozanMarginMoney(decimal positionNotional, decimal virtualNotional, bool dma, client_marginrate clientMarginTemplate)
/// <param name="positions">持仓列表</param>
/// <param name="flows">流水列表</param>
/// <param name="clientMarginTemplate">客户保证金模板</param>
/// <returns>资金变化金额</returns>
public decimal CalcDmaMoney(List<swap_flow> positions, List<swap_flow> flows, client_marginrate clientMarginTemplate)
{
decimal money = 0;
var virtualPosi = positionNotional + virtualNotional;
var posiType = positionNotional >= 0 ? (int)PositionTypeFlag.Long : (int)PositionTypeFlag.Short;
var virtualPosiType = virtualPosi >= 0 ? (int)PositionTypeFlag.Long : (int)PositionTypeFlag.Short;
var positionNotionalAbs = Math.Abs(positionNotional);
var virtualNotionalAbs = Math.Abs(virtualNotional);
decimal longMarginRate = 0;
decimal shortMarginRate = 0;
//普通客户
if (!dma)
var marginRate = (decimal)clientMarginTemplate.InitMarginRate;
// 处理持仓与流水的平仓逻辑
foreach (var position in positions.ToList()) // 使用 ToList() 避免修改集合时的问题
{
longMarginRate = Convert.ToDecimal(clientMarginTemplate.InitMarginRate);
shortMarginRate = longMarginRate;
}
else //定义文件类型客户
{
longMarginRate = Convert.ToDecimal(clientMarginTemplate.LongInitMarginRate);
shortMarginRate = Convert.ToDecimal(clientMarginTemplate.ShortInitMarginRate);
}
// 当前持仓多头
if (posiType == (int)PositionTypeFlag.Long)
{
if (virtualPosiType == (int)PositionTypeFlag.Long)
var oppositeFlows = flows.Where(x => x.BsType != position.BsType && x.TradingQty > 0).ToList();
foreach (var flow in oppositeFlows)
{
money = virtualNotional * longMarginRate;
}
else //虚拟持仓空头
{
if (virtualNotionalAbs <= positionNotionalAbs)
{
money = virtualNotional * longMarginRate;
}
else
{
money = (-virtualNotional * shortMarginRate) - positionNotional * (longMarginRate + shortMarginRate);
}
if (position.TradingQty <= 0) break; // 持仓已处理完毕
decimal tradedQty = Math.Min(position.TradingQty, flow.TradingQty);
money += CalculateClosePositionProfit(position, flow, tradedQty, marginRate, isPositionFlow: true);
// 更新持仓和流水的数量
position.TradingQty -= tradedQty;
flow.TradingQty -= tradedQty;
}
}
// 当前持仓空头
else
// 处理流水之间的轧差逻辑
foreach (var flow in flows.Where(x => x.TradingQty > 0).ToList())
{
if (virtualPosiType == (int)PositionTypeFlag.Short)
var oppositeFlows = flows.Where(x => x.BsType != flow.BsType && x.TradingQty > 0).ToList();
foreach (var oppositeFlow in oppositeFlows)
{
money = (-virtualNotional) * shortMarginRate;
}
else //虚拟持仓多头
{
if (virtualNotionalAbs <= positionNotionalAbs)
{
money = (-virtualNotional) * shortMarginRate;
}
else
{
money = (virtualNotional + positionNotional) * longMarginRate + positionNotional * shortMarginRate;
}
if (flow.TradingQty <= 0) break; // 当前流水已处理完毕
decimal tradedQty = Math.Min(flow.TradingQty, oppositeFlow.TradingQty);
money += CalculateClosePositionProfit(flow, oppositeFlow, tradedQty, marginRate, isPositionFlow: false);
// 更新流水的数量
flow.TradingQty -= tradedQty;
oppositeFlow.TradingQty -= tradedQty;
}
}
return money;
// 处理剩余流水的新开仓逻辑
foreach (var flow in flows.Where(x => x.TradingQty > 0))
{
// 新开仓保证金
money += marginRate * flow.TradingQty * flow.TradingAmountAvg;
}
return Math.Round(money, 2, MidpointRounding.AwayFromZero);
}
/// <summary>
/// 计算平仓损益和保证金释放
/// </summary>
private decimal CalculateClosePositionProfit(swap_flow position, swap_flow flow, decimal tradedQty, decimal marginRate, bool isPositionFlow)
{
decimal floatRatio = -1m; // 默认支付
decimal longRatio = position.BsType == 1 ? 1m : -1m;
// 平仓损益
decimal profit = (flow.TradingAmountAvg - position.TradingAmountAvg) * tradedQty * floatRatio * longRatio;
// 如果是持仓与流水平仓,计算保证金释放;否则不计算
decimal releasedMargin = isPositionFlow ? marginRate * tradedQty * position.TradingAmountAvg : 0;
return profit - releasedMargin;
}
public class ClientBalanceEx : ClientSettleBalance
{
public double InFundOther { get; set; }
+11 -8
View File
@@ -586,6 +586,9 @@ namespace YLErp.BLL.Eod
}
bondDb.SaveChanges();
SetClientPositionPrice(clientPosition);
clientPosition.swap_market_value = clientPosition.full_price_now * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1);
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1) - clientPosition.commission;
clientPosition.position_profit_loss = Math.Round(clientPosition.position_profit_loss ?? 0, 2, MidpointRounding.AwayFromZero);
clientPosition.today_profit_loss = clientPosition.swap_market_value - lastPv;
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)//发kafka 获取成交收益率
{
@@ -629,8 +632,10 @@ namespace YLErp.BLL.Eod
}
bondDb.SaveChanges();
SetClientPositionPrice(clientPosition);
clientPosition.swap_market_value = clientPosition.full_price_now * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1);
clientPosition.position_profit_loss = (clientPosition.full_price_now - clientPosition.deal_full_price_avg) * clientPosition.position_qty * (clientPosition.side == 0 ? 1 : -1);
clientPosition.position_profit_loss = Math.Round(clientPosition.position_profit_loss ?? 0, 2, MidpointRounding.AwayFromZero);
clientPosition.today_profit_loss = clientPosition.swap_market_value;
//发kafka 获取成交收益率
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)
{
@@ -781,23 +786,21 @@ namespace YLErp.BLL.Eod
UnderlyingCode = swapflow.UnderlyingCode,
BsType = swapflow.BsType,
TradingQty = gourpItem.Sum(s => s.TradingQty),
TradingFeePending = gourpItem.Sum(s => s.TradingFee),
TradingFee = gourpItem.Sum(s => s.TradingFee),
DataState = (int)SwapFlowDateStateEnum.,
ContractSize = swapflow.ContractSize,
ClientId = swapflow.ClientId,
TradingAmount = gourpItem.Sum(s => s.TradingAmount)
};
int tradeSide = swap_flow_summary.BsType == (int)EnumDirection.Long ? 1 : -1;
swap_flow_summary.FirstFlowTime = swapflow.OptTime;
swap_flow_summary.SettleDate = gourpItem.Max(s => s.SettleDate);
swap_flow_summary.TradingAmount = swap_flow_summary.TradingQty * swap_flow_summary.ContractSize;
swap_flow_summary.TradingAmountAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountAvg * s.TradingQty) / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountNetAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountNet * s.TradingQty) / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountNetFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountNetAvg : swap_flow_summary.TradingAmountNetAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountAvg = Math.Round(swap_flow_summary.TradingAmountAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFee * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountFeeAvg = Math.Round(swap_flow_summary.TradingAmountFeeAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
swap_flow_summary.TradingAmountAvg *= multiplier;
swap_flow_summary.TradingAmountFeeAvg *= multiplier;
swap_flow_summary.TradingAmountNetAvg *= multiplier;
swap_flow_summary.TradingAmountNetFeeAvg *= multiplier;
list.Add(swap_flow_summary);
}
return list.OrderByDescending(o => o.TradingQty).ToList();
+4
View File
@@ -27,5 +27,9 @@ namespace YLErp.Model
/// 买卖方向
/// </summary>
public int side { get; set; }
/// <summary>
/// 含费全价
/// </summary>
public decimal price { get; set; }
}
}
+10 -83
View File
@@ -837,7 +837,7 @@ namespace YLErp.Modules.SwapModule
unwindData.AnnualDays = tradeExtend == null ? 365 : tradeExtend.ExtendObj.AnnualDays;
unwindData.CloseMethod = unwindQty == unwindData.PositionQty ? (int)CloseMethodEnum. : (int)CloseMethodEnum.;
unwindData.ClosePercent = unwindData.PositionQty == 0 ? 0 : unwindPercent;
unwindData.CloseNotionalValue = unwindData.PosiNotionalValue* unwindPercent;
unwindData.CloseNotionalValue = position == null ? 0 : unwindQty * position.PosiGrossPrice * position.ContractSize;
unwindData.CloseQty = unwindQty;
if (position != null)
{
@@ -867,9 +867,9 @@ namespace YLErp.Modules.SwapModule
floatEvent.TradingFeePending = position.PosiTradingFeePending * unwindData.ClosePercent;
var mergeClosePercent = mergeQty == 0 ? 0 : unwindQty / mergeQty;
floatEvent.TradingFee = penddingFee * mergeClosePercent;
floatEvent.MarkClosePnl = (unwindPriceFee - position.PosiNetPrice) * unwindQty * floatRatio * longRatio;
floatEvent.MarkClosePnl = decimal.Parse(floatEvent.MarkClosePnl.ToString("0.00"));
floatEvent.TradingAmount = floatEvent.Quantity * floatEvent.ContractSize;
floatEvent.MarkClosePnl = (unwindPrice - position.PosiGrossPrice) * unwindQty * floatRatio * longRatio;
floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + (floatEvent.TradingFee * floatRatio * -1), ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.TradingAmount = unwindPrice * floatEvent.Quantity * floatEvent.ContractSize;
floatEvent.OptLog = "流水自动";
floatEvent.ClientId = td.ClientId;
floatEvent.SetOpt(UserInfo);
@@ -1038,10 +1038,10 @@ namespace YLErp.Modules.SwapModule
{
AddClientCashInCashOut(td, Convert.ToDouble(unwindData.SwapMarginAmount), ClientCashInCashOut._应付预付金, unwindData.ValueDate);
}
if (unwindData.SwapMarginRebatePnl != 0)
{
AddClientCashInCashOut(td, Convert.ToDouble(-unwindData.SwapMarginRebatePnl), ClientCashInCashOut._预付金返息, unwindData.ValueDate);
}
//if (unwindData.SwapMarginRebatePnl != 0)
//{
// AddClientCashInCashOut(td, Convert.ToDouble(-unwindData.SwapMarginRebatePnl), ClientCashInCashOut.系统操作_预付金返息, unwindData.ValueDate);
//}
var flowList = new List<swap_flow_event>(unwindData.FlowEvents);
var eventId = SaveSwapDeal(unwindData, (int)SwapEventTypeEnum., clientCashId, actionMsg);
if (unwindData.CloseMethod == (int)CloseMethodEnum.)
@@ -1376,15 +1376,9 @@ namespace YLErp.Modules.SwapModule
{
if (!string.IsNullOrEmpty(position.UnderlyingCode))
{
var dealFloat = flowList.FirstOrDefault(x => !string.IsNullOrEmpty(x.UnderlyingCode));
if (dealFloat != null)
{
decimal ratio = dealFloat.EventType == (int)SwapFlowEventTypeEnum. ? -1m : 1m;
position.PosiTradingFeePending += dealFloat.TradingFeePending * ratio;
position.PosiDividendIncome += dealFloat.DividendPending;
}
position.PosiQuantity -= unwindData.CloseQty;
position.PosiNotionalValue = position.PosiQuantity * position.ContractSize;
position.PosiNotionalValue = position.PosiGrossPrice * position.PosiQuantity * position.ContractSize;
position.PosiTradingFee -= position.PosiTradingFee * unwindData.ClosePercent;
}
else
{
@@ -1401,73 +1395,6 @@ namespace YLErp.Modules.SwapModule
}
}
}
/// <summary>
/// 单标的互换更新实时持仓信息
/// </summary>
/// <param name="deal_Floats"></param>
/// <param name="deal_Interests"></param>
/// <param name="positions"></param>
public void UpdateInitalPosition(DateTime valueDate, trade td, List<swap_position> positions, List<swap_flow_event> swpFlowEvents)
{
var preSettleDate = GetPreValueDate(valueDate);//上一交易日期
var realPositions = positions.Where(x => !x.IsInitial);
var originalPositions = positions.Where(x => x.IsInitial);
var unwindFlowEvents = swpFlowEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum. || x.EventType == (int)SwapFlowEventTypeEnum.).ToList();
List<eod_swap_position> preEodSwapPositions = DbContext.eod_swap_position.Where(x => !x.Invalid && x.SwapTradeId == td.id && valueDate == preSettleDate).ToList();
foreach (var position in realPositions)
{
var currEod = new eod_swap_position() { ContractSize = position.ContractSize };
var eod = preEodSwapPositions.FirstOrDefault(x => x.PositionId == position.PositionId);
if (eod == null)
{
eod = new eod_swap_position()
{
ContractSize = position.ContractSize,
PositionType = position.PositionType,
PosiDirection = position.PosiDirection,
PosiFeePending = 0,
PosiNetPrice = position.PosiNetPrice,
PosiGrossPrice = position.PosiGrossPrice,
PosiNetFeePrice = position.PosiNetFeePrice,
PosiNetNoFeePrice = position.PosiNetNoFeePrice,
};
}
new SwapEodPositionService(UserInfo).SetPriceInfoByFlowEvent(eod, currEod, unwindFlowEvents, position);
var oriPosition = originalPositions.FirstOrDefault(x => x.id == position.PositionId);
position.InterestAmount = currEod.RealizedInterest;
position.InterestFeePending = currEod.InterestFeePending;
position.PosiTradingFeePending = currEod.PosiFeePending;
position.PosiDividendIncome = currEod.PosiDividendSum;
position.PosiQuantity = currEod.PosiQuantity;
position.PosiNetPrice = currEod.PosiNetPrice;
position.PosiGrossPrice = currEod.PosiGrossPrice;
position.PosiNetFeePrice = currEod.PosiNetFeePrice;
position.PosiNetNoFeePrice = currEod.PosiNetNoFeePrice;
position.PosiNotionalValue = currEod.PosiNotionalValue;
td.StockEqvNotional = Convert.ToDouble(position.PosiNotionalValue);
td.TradeAmount = Convert.ToDouble(position.PosiQuantity);
}
}
/// <summary>
/// 获取标的平仓比例
/// </summary>
/// <param name="tradeId"></param>
/// <returns></returns>
private decimal GetUnwindPercent(int tradeId)
{
var swapEvents = DbContext.swap_event.Where(x => x.SwapTradeId == tradeId && !x.Invalid && x.EventType == (int)SwapEventTypeEnum.).ToList();
decimal unwindPercent = 0;
foreach (var swapEvent in swapEvents)
{
if (!string.IsNullOrEmpty(swapEvent.EventData))
{
swapEvent.unwindData = JsonConvert.DeserializeObject<UnwindData>(swapEvent.EventData);
unwindPercent += swapEvent.unwindData.ClosePercent;
}
}
return unwindPercent;
}
}
}
@@ -156,11 +156,7 @@ namespace YLErp.Modules.SwapModule
var curEodPosis = DealFloatPositions(posiList, realPosiList, eodPositions, todyEodPositions, settleDate, td, preSettleDate, flowEvents);
var posiLongNotional = curEodPosis.Where(s => s.PositionType == (int)PositionTypeFlag.Long).Sum(s => s.PosiNotionalValue);
var posiShortNotional = curEodPosis.Where(s => s.PositionType == (int)PositionTypeFlag.Short).Sum(s => s.PosiNotionalValue);
var closePosiNotional = curEodPosis.Where(s => s.TdCloseQty > 0).Sum(s => s.TdCloseQty * s.ContractSize);
if (longShort)
{
closePosiNotional = curEodPosis.Where(s => s.TdCloseQty > 0).Sum(s => s.TdCloseQty * s.ContractSize * s.PosiNetPrice);
}
var closePosiNotional = curEodPosis.Where(s => s.TdCloseQty > 0).Sum(s => s.TdCloseQty * s.ContractSize * s.PosiNetPrice);
var grossPrice = curEodPosis.Where(x => x.PosiDirection > 0).FirstOrDefault()?.PosiGrossPrice ?? 0;
//处理利息腿
DealInterests(interestList, eodPositions, todyEodPositions, settleDate, td, flowEvents, autoInterests, lastEodSwap, posiLongNotional, posiShortNotional, closePosiNotional, grossPrice, orginPv);
@@ -314,20 +310,9 @@ namespace YLErp.Modules.SwapModule
var unwindEvents = flowEvents.Where(x => x.PositionId == posi.id).ToList();//当前日平仓信息
var realPosition = realPosiList.FirstOrDefault(s => s.PositionId == posi.id);
eod_swap_position eodPosi = new eod_swap_position();
if (eodPosition == null || td.StartDate == settleDate)
if (eodPosition == null || td.TradeDate == settleDate)
{
if (tdEodPosition == null)//第一次生成归档信息
{
eodPosi = SaveCurrentEodInitalPosi(posi, td, settleDate, preSettleDate, unwindEvents);
}
else
{
tdEodPosition.PosiFeePending = posi.PosiTradingFeePending;
tdEodPosition.PosiNotionalValue = tdEodPosition.PosiQuantity * tdEodPosition.ContractSize;
tdEodPosition.PosiNetFeePrice = posi.PosiNetFeePrice;
tdEodPosition.PosiNetNoFeePrice = posi.PosiNetNoFeePrice;
}
eodPosi = SaveCurrentEodInitalPosi(posi, td, settleDate, preSettleDate, unwindEvents);
}
else if (unwindEvents.Count() == 0)
{
@@ -1276,12 +1261,12 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiNetFeePrice = position.PosiNetFeePrice;
curretEod.PosiNetNoFeePrice = position.PosiNetNoFeePrice;
curretEod.PosiQuantity = position.PosiQuantity;
curretEod.PosiTradingFee = position.PosiTradingFee;
curretEod.PosiTradingFee = -position.PosiTradingFee * directionRatio;
}
else
{
var eventTradingFee = unwindEvents.Where(x => x.EventType == (int)SwapFlowEventTypeEnum. || x.EventType == (int)SwapFlowEventTypeEnum.).Sum(s => s.TradingFeePending * (s.EventType == (int)SwapFlowEventTypeEnum. ? 1 : -1));
curretEod.PosiFeePending = eod.PosiFeePending + eventTradingFee;
var eventTradingFee = openFlowEvents.Sum(s => s.TradingFee);
curretEod.PosiTradingFee = eod.PosiTradingFee - eventTradingFee * directionRatio;
if (openFlowEvents.Count() == 0)
{
curretEod.PosiNetPrice = eod.PosiNetPrice;
@@ -1297,12 +1282,16 @@ namespace YLErp.Modules.SwapModule
{
posiQty = 0;
}
curretEod.PosiGrossPrice = (eod.PosiGrossPrice * posiQty + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiNetNoFeePrice = (eod.PosiNetNoFeePrice * posiQty + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountNetAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiNetFeePrice = curretEod.PosiQuantity == 0 ? eod.PosiNetFeePrice : curretEod.PosiNetNoFeePrice + curretEod.PosiFeePending / curretEod.PosiQuantity * shortRatio;
curretEod.PosiNetPrice = curretEod.PosiQuantity == 0 ? eod.PosiNetPrice : curretEod.PosiGrossPrice + curretEod.PosiFeePending / curretEod.PosiQuantity * shortRatio;
curretEod.PosiGrossPrice = (eod.PosiGrossPrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiGrossPrice = Math.Round(curretEod.PosiGrossPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
curretEod.PosiNetPrice = (eod.PosiNetPrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountFeeAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiNetPrice = Math.Round(curretEod.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
curretEod.PosiNetNoFeePrice = (eod.PosiNetNoFeePrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountNetAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiNetNoFeePrice = Math.Round(curretEod.PosiNetNoFeePrice ?? 0, 10, MidpointRounding.AwayFromZero);
curretEod.PosiNetFeePrice = (eod.PosiNetFeePrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountNetFeeAvg)) / (eod.PosiQuantity + openQty);
curretEod.PosiNetFeePrice = Math.Round(curretEod.PosiNetFeePrice ?? 0, 10, MidpointRounding.AwayFromZero);
}
curretEod.PosiNotionalValue = curretEod.PosiQuantity * curretEod.ContractSize;
curretEod.PosiNotionalValue = curretEod.PosiGrossPrice * curretEod.PosiQuantity * curretEod.ContractSize;
curretEod.TdPosiDividend = unwindEvents.Sum(x => x.DividendIn) * directionRatio;
//curretEod.TdCloseFee = unwindEvents.Sum(x => x.TradingFee);
curretEod.TdCloseQty = unwindQty;
@@ -341,15 +341,19 @@ namespace YLErp.Modules.SwapModule
DataState = (int)SwapFlowDateStateEnum.,
ContractSize = swapflow.ContractSize,
ClientId = swapflow.ClientId,
TradingAmount = gourpItem.Sum(s => s.TradingAmount),
};
int tradeSide = swap_flow_summary.BsType == (int)EnumDirection.Long ? 1 : -1;
swap_flow_summary.FirstFlowTime = swapflow.OptTime;
swap_flow_summary.SettleDate = gourpItem.Max(s => s.SettleDate);
swap_flow_summary.TradingAmount = swap_flow_summary.TradingQty * swap_flow_summary.ContractSize;
swap_flow_summary.TradingAmountAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountAvg * s.TradingQty) / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountAvg = Math.Round(swap_flow_summary.TradingAmountAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFee * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountFeeAvg = Math.Round(swap_flow_summary.TradingAmountFeeAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
swap_flow_summary.TradingAmountNetAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountNet * s.TradingQty) / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountNetFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountNetAvg : swap_flow_summary.TradingAmountNetAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountNetAvg = Math.Round(swap_flow_summary.TradingAmountNetAvg ?? 0, 10);
swap_flow_summary.TradingAmountNetFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountNetAvg : swap_flow_summary.TradingAmountNetAvg + swap_flow_summary.TradingFee * tradeSide / swap_flow_summary.TradingQty;
swap_flow_summary.TradingAmountNetFeeAvg = Math.Round(swap_flow_summary.TradingAmountNetFeeAvg ?? 0, 10);
swap_flow_summary.SetOpt(UserInfo);
if (save)
{
@@ -114,32 +114,6 @@ namespace YLErp.Modules.SwapModule
return dbTrade;
}
/// <summary>
/// 生成推送记录给衡泰
/// </summary>
/// <param name="add"></param>
/// <param name="td"></param>
public void AddPushLog(trade td)
{
bool longShort = td.StructureType == "多空组合";
if (!longShort)
{
AddSinglePushLog(td);
}
}
/// <summary>
/// 生成非多空组合记录
/// </summary>
/// <param name="add"></param>
/// <param name="td"></param>
/// <param name="posiPositions"></param>
public void AddSinglePushLog(trade td)
{
var marginModes = new int[] { (int)InterestModeEnum., (int)InterestModeEnum. };
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == td.id && x.IsInitial && !x.Invalid).ToList();
td.swap_positions = positions.Where(x => marginModes.Contains(x.InterestMode)).ToList();
var posiPositions = positions.Where(x => x.PosiDirection > 0).ToList();
}
/// <summary>
/// 单标的生成开仓事件
/// </summary>
/// <param name="td"></param>
@@ -254,20 +228,6 @@ namespace YLErp.Modules.SwapModule
{
var dbTrade = req.Clone();
DbContext.trade.Add(dbTrade);
//申万交易编号特殊处理(如果交易编号是用户手动输入时)
if (!tradeNumberGenerated && PS.Config.Is申万)
{
var client = DataCacheProvider.GetClientDataSource().GetData(dbTrade.ClientId);
if (client?.Code != null && dbTrade.TradeNumber.StartsWith(client.Code))
{
var canParseInt = int.TryParse(dbTrade.TradeNumber.Substring(client.Code.Length), out var contractNo);
if (canParseInt && contractNo > (client.CurrentContractNo ?? 0))
{
client.CurrentContractNo = contractNo;
}
}
}
InnerSaveTrade(true, dbTrade, "");
return dbTrade;
@@ -413,10 +373,8 @@ namespace YLErp.Modules.SwapModule
PosiNetFeePrice = flowMerge.TradingAmountNetFeeAvg ?? 0,
PosiNetNoFeePrice = flowMerge.TradingAmountNetAvg ?? 0,
PosiQuantity = flowMerge.TradingQtyAbs,
PosiNotionalValue = flowMerge.TradingQtyAbs * flowMerge.ContractSize,
PosiNotionalValue = flowMerge.TradingAmountAvg * flowMerge.TradingQtyAbs * flowMerge.ContractSize,
PosiTradingFeePending = flowMerge.TradingFeePending,
//PosiTradingFee = flowMerge.TradingFee,
//PosiTradingFeeUnit = flowMerge.TradingQtyAbs == 0 ? 0 : flowMerge.TradingFee * flowMerge.ContractSize / flowMerge.TradingQtyAbs,
PosiTradingFee = 0,
PosiTradingFeeUnit = 0,
SwapTradeId = td.id,
@@ -700,10 +658,6 @@ namespace YLErp.Modules.SwapModule
new TradeDocumentDataService(this).DeleteBooksAfterEditTrade(dbTrade);
}
int eventType = isAddNew ? (int)SwapEventTypeEnum. : (int)SwapEventTypeEnum.;
if (!string.IsNullOrEmpty(changsStr))
{
changsStr = new DatatraceQueryService(UserInfo).ReplaceDataChanges(new trade(), changsStr);
}
new SwapEventService(UserInfo).AddSwapEventDate(dbTrade.TradeDate.Value, dbTrade.id, eventType, "", 0, true, "", true);
DbContext.SaveChanges();
}
@@ -1435,10 +1389,9 @@ namespace YLErp.Modules.SwapModule
position.UnderlyingInstrumentType = swap.UnderlyingInstrumentType;
position.PosiDirection = swap.PosiDirection;
position.PosiGrossPrice = swap.PosiGrossPrice;
position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
position.PosiNetNoFeePrice = swap.PosiNetNoFeePrice;
position.PosiNetFeePrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiNetNoFeePrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
position.PosiNotionalValue = swap.PosiQuantity * swap.ContractSize;
position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFee / swap.PosiQuantity) * ratio);
position.PosiNetPrice = Math.Round(position.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
position.PosiNotionalValue = position.PosiGrossPrice * swap.PosiQuantity * swap.ContractSize;
position.PosiQuantity = swap.PosiQuantity;
position.InterestDirection = swap.InterestDirection;
position.InterestMode = swap.InterestMode;
@@ -1570,7 +1523,6 @@ namespace YLErp.Modules.SwapModule
InvalidTradeOptionDatasByDate(tradeId, valueDate, backToBegin);
swapEventService.AddSwapEventDate(valueDate, tradeId, (int)SwapEventTypeEnum.退, string.Empty, 0, false, $"交易回退至{valueDate:yyyy年MM月dd日}");
DbContext.SaveChanges();
AddPushLog(td);
if (del)
{
new TradeRiskCheckLogService(UserInfo).DeleteLog(td.TradeNumber, valueDate);//重置风控记录
@@ -1708,6 +1660,7 @@ namespace YLErp.Modules.SwapModule
{
posi.InterestAmount = eodPosi.RealizedInterest;
posi.InterestFeePending = eodPosi.InterestFeePending;
posi.InterestPrincipalFix= eodPosi.InterestPrincipalFix;
posi.PosiTradingFeePending = eodPosi.PosiFeePending;
posi.PosiDividendIncome = eodPosi.PosiDividendSum;
posi.PosiQuantity = eodPosi.PosiQuantity;
@@ -1731,8 +1684,6 @@ namespace YLErp.Modules.SwapModule
var clientCashs = DbContext.ClientCashInCashOut.Where(x => x.TradeId == td.id && x.HappenDate >= valueDate).ToList();
DbContext.ClientCashInCashOut.RemoveRange(clientCashs);
DbContext.SaveChanges();
var marginPosis = swapPositions.Where(x => x.HappenDate <= valueDate || x.InterestMode == (int)InterestModeEnum.).ToList();
ResetMarginAmount(td, valueDate, marginPosis);
}
/// <summary>
/// 多空组合回到初始
+1 -2
View File
@@ -337,8 +337,7 @@ namespace YLErp.Web.Controllers
try
{
bool edit = req.id != 0;
var r = swapTradeService.SaveTrade(req);
swapTradeService.AddPushLog(r);
var r= swapTradeService.SaveTrade(req);
Task.Run(() =>
{
RealtimePnlCalc.RealtimeSwapPosition(new OptUserInfo(0, "互换实时持仓服务", OptUserFrom.Service));
+6 -2
View File
@@ -191,7 +191,9 @@ namespace YLErp.Web.Controllers
BsType = item.side + 1,
UnderlyingCode = item.underlyingCode,
ClientId = item.clientId,
TradingQty = item.tradingQty
TradingQty = item.tradingQty,
TradingAmountAvg = item.price,
TradingAmountFeeAvg = item.price
};
bondFlows.Add(flow);
}
@@ -205,7 +207,9 @@ namespace YLErp.Web.Controllers
clientId = item.Key
};
var clientBalanceCache = _yLCache.StringGet<ClientBalanceForTrsResponse>("ClientBalance:" + item.Key);
tradeClientCashCalc.availableAmount = (clientBalanceCache?.AvailableMoney ?? 0) - item.Value.FrozenMarginMoney;
var availableMoney = clientBalanceCache?.AvailableMoney ?? 0;
tradeClientCashCalc.availableAmount = availableMoney - item.Value.FrozenMarginMoney;
tradeClientCashCalc.availableAmount = Math.Round(tradeClientCashCalc.availableAmount, 2, MidpointRounding.AwayFromZero);
list.Add(tradeClientCashCalc);
}
return JsonSuccess("", list);
@@ -205,20 +205,15 @@ const vue = new Vue({
},
//变更数量
changeQuantity(item) {
this.changeSpotPrice(item);
this.changeTradingFeeUnit(item);
this.changeSpotPrice();
},
//变更标的单价
changeSpotPrice(item) {
var notional = item.PosiQuantity * item.ContractSize;
var stockEqvNotional = this.trade.StructureType != '普通收益互换' ? notional : item.PosiGrossPrice * notional;
this.trade.StockEqvNotional = otcformat.trading.stockEqvNotional(stockEqvNotional);
this.StockEqvNotional = item.PosiGrossPrice * notional;
this.changeSpotPrice();
},
//变更标的合约乘数
changeContractSize(item) {
this.changeSpotPrice(item);
this.changeTradingFeeUnit(item);
this.calcNotional();
},
//变更名义本金
changeStockEqvNotional() {
@@ -226,10 +221,9 @@ const vue = new Vue({
//计算数量
if (this.paySwapList.length > 0) {
var item = this.paySwapList[0];
var notional = this.trade.StructureType != '普通收益互换' ? item.ContractSize : item.PosiGrossPrice * item.ContractSize;
var notional = item.PosiGrossPrice * item.ContractSize;
item.PosiQuantity = notional == 0 ? 0 : this.trade.StockEqvNotional / notional;
this.StockEqvNotional = item.PosiGrossPrice * item.ContractSize * item.PosiQuantity;
this.changeTradingFeeUnit(item);
this.calcNotional();
}
},
@@ -250,15 +244,23 @@ const vue = new Vue({
if (this.Obervation) {
this.Obervation.ObservationStart = this.trade.StartDate;
}
var payItem = this.paySwapList[0];
this.getSpotPrice(payItem.UnderlyingCode, this.trade.StartDate, payItem);
var national = payItem.PosiQuantity * payItem.ContractSize;
var stockEqvNotional = this.trade.StructureType != '普通收益互换' ? national : payItem.PosiGrossPrice * national;//名义本金=期初价格*数量*乘数
this.trade.StockEqvNotional = otcformat.trading.stockEqvNotional(stockEqvNotional);
this.calcNotional();
this.refreshDatepicker();
this.changeMarginDate();
//this.initMarginRate();
},
calcNotional(calcPrice) {
if (this.paySwapList.length > 0) {
var payItem = this.paySwapList[0];
if (calcPrice) {
this.getSpotPrice(payItem.UnderlyingCode, this.trade.StartDate, payItem);
}
var national = payItem.PosiQuantity * payItem.ContractSize;
var stockEqvNotional = payItem.PosiGrossPrice * national;//名义本金=期初价格*数量*乘数
this.trade.StockEqvNotional = otcformat.trading.stockEqvNotional(stockEqvNotional);
payItem.PosiNotionalValue = this.StockEqvNotional;
}
},
//变更到期日
changeExerciseDate() {
this.refreshDatepicker();