保证金算法&资金计算

This commit is contained in:
吴方海
2025-04-16 15:15:59 +08:00
parent 6e644083df
commit 8e61f23e18
47 changed files with 695 additions and 1194 deletions
@@ -100,7 +100,6 @@ namespace YLErp.Modules.SwapModule
var tradePositionList = allTradePositionList.Where(t => t.IsInitial).ToList();
var tradeRealPositionList = allTradePositionList.Where(t => !t.IsInitial).ToList();
var tradeExtendList = DbContext.trade_extend.Where(x => tradeIds.Contains(x.TradeId)).ToList();
var eodSwapPositionList = DbContext.eod_swap_position.Where(x => x.ValueDate >= preSettleDate && x.ValueDate <= settleDate && tradeIds.Contains(x.SwapTradeId) && !x.Invalid).ToList();
var eodSwapList = DbContext.eod_swap.Where(x => x.ValueDate == preSettleDate).ToList();
List<int> eventTyps = new List<int>() { (int)SwapEventTypeEnum., (int)SwapEventTypeEnum., (int)SwapEventTypeEnum. };
foreach (var td in tradeQueryList)
@@ -123,7 +122,7 @@ namespace YLErp.Modules.SwapModule
{
throw new Exception($"交易{td.TradeNumber}在上一交易日【{preSettleDate:yyyy-MM-dd}】未收盘");
}
var allEodPositions = eodSwapPositionList.Where(x => x.ValueDate >= preSettleDate && x.SwapTradeId == td.id && !x.Invalid);
var allEodPositions = DbContext.eod_swap_position.Where(x => x.ValueDate >= preSettleDate && x.SwapTradeId == td.id && !x.Invalid);
var eodPositions = allEodPositions.Where(x => x.ValueDate == preSettleDate).ToList();//上一日终持仓信息
@@ -828,17 +827,18 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.InterestDirection = position.InterestDirection;
newEodPayPosition.InterestMode = position.InterestMode;
newEodPayPosition.InterestPrincipalFix = position.InterestPrincipalFix;
newEodPayPosition.InterestPrincipalFix *= (1 - closePercent);
newEodPayPosition.InterestRateDefault = position.InterestRateDefault;
newEodPayPosition.InterestSwapInterval = position.InterestSwapInterval;
newEodPayPosition.IsAnnualized = position.IsAnnualized;
newEodPayPosition.HappenDate = position.HappenDate;
newEodPayPosition.Currency = position.Currency;
newEodPayPosition.InterestType = position.InterestType;
newEodPayPosition.interest_rest_days = position.interest_rest_days;
newEodPayPosition.interest_rule = position.interest_rule;
newEodPayPosition.FloatRate = interests.Count > 0 ? interests.First().FloatRate ?? 0 : 0;
newEodPayPosition.FloatRateUnderlyingCode = position.FloatRateUnderlyingCode;
newEodPayPosition.InterestFeePending = 0;
newEodPayPosition.interest_rest_days = position.interest_rest_days;
newEodPayPosition.interest_rule = position.interest_rule;
//利息端估值用信息
newEodPayPosition.TdInterestPrincipal = interests.Count > 0 ? interests.First().InterestPrincipal : 0;
newEodPayPosition.TdInterestPrincipal *= (1 - closePercent);
@@ -850,19 +850,17 @@ namespace YLErp.Modules.SwapModule
{
newEodPayPosition.TdInterestRate = flowEvents.FirstOrDefault()?.InterestRate ?? 0;
}
//当日已实现,平仓时已处理
newEodPayPosition.TdInterestFee = flowEvents.Sum(s => s.InterestFee);
newEodPayPosition.TdCloseInterestFee = newEodPayPosition.TdInterestFee;
newEodPayPosition.TdCloseInterest = flowEvents.Sum(s => s.InterestClosePnL);
if (closePercent == 1)
{
newEodPayPosition.TdCloseInterest = eodPayPosition.InterestIncomeSum;
newEodPayPosition.InterestIncomeSum = 0;
}
else
{
newEodPayPosition.TdCloseInterest = (eodPayPosition.InterestIncomeSum + TdInterestAmount) * closePercent;
newEodPayPosition.InterestIncomeSum = eodPayPosition.InterestIncomeSum + TdInterestAmount - newEodPayPosition.TdCloseInterest;
newEodPayPosition.InterestIncomeSum = eodPayPosition.InterestIncomeSum + TdInterestAmount - Math.Abs(newEodPayPosition.TdCloseInterest);
}
//持仓内容-利息腿-损益统计(本方视角)
newEodPayPosition.TdInterestIncome = TdInterestAmount * (1 - closePercent);
@@ -872,7 +870,7 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.SwapPositionValue = newEodPayPosition.InterestProfitSum + newEodPayPosition.PosiProfitSum;
//累计已实现
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest * ratio;
newEodPayPosition.RealizedInterest = eodPayPosition.RealizedInterest + newEodPayPosition.TdCloseInterest;
newEodPayPosition.RealizedInterestFee = eodPayPosition.RealizedInterestFee + newEodPayPosition.TdCloseInterestFee;
newEodPayPosition.RealizedPnl = newEodPayPosition.RealizedInterest + newEodPayPosition.RealizedInterestFee;
var currencyRate = new EodCurrencyRateService(UserInfo).GetCurrencyRate(td.QuoteCurrency, td.SettlementCurrency, valueDate
@@ -1461,19 +1459,9 @@ namespace YLErp.Modules.SwapModule
interestPnL += x.InterestProfitSum * ratio;
});
eod_Swap.InterestPnL = interestPnL;
decimal tdRealizedPnL = 0;
eodSwapPositions.ForEach(x =>
{
decimal ratio = x.InterestDirection == (int)SwapDirectionEnum. ? 1 : -1;//收取为正,支付为负
if (marginTypes.Contains(x.InterestMode))
{
ratio = -ratio;
}
tdRealizedPnL += x.TdCloseMtmPnl + x.TdCloseDividend + x.TdCloseFee + x.TdCloseInterest * ratio + x.TdCloseInterestFee;
});
eod_Swap.TdRealizedPnL = tdRealizedPnL;
eod_Swap.PostionValue = eodSwapPositions.Sum(s => s.SwapPositionValue);
eod_Swap.RealizedPnL = eodSwapPositions.Sum(s => s.RealizedMtmPnL + s.RealizedDividend + s.RealizedFee + s.RealizedInterest + s.RealizedInterestFee);
eod_Swap.RealizedPnL = eodSwapPositions.Sum(s => s.RealizedPnl);
eod_Swap.TdRealizedPnL = eod_Swap.RealizedPnL - (preEodSwap?.RealizedPnL ?? 0);
eod_Swap.TdCloseQty = positions.Sum(s => s.TdCloseQty);
var initMargin = Convert.ToDecimal(tradeSpan?.InitialMargin ?? 0);
var maintainMargin = Convert.ToDecimal(tradeSpan?.WorstCastClientPayable ?? 0);