diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
index 9fea70ca..23a7a908 100644
--- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
@@ -657,11 +657,11 @@ namespace YLErp.Modules.SwapModule
var floateRate = preEodPosition.FloatRate;
if (position.InterestType == (int)InterestTypeEnum.复利)
{
- CalcDailyCompoundInterest(preEodPosition, endDate, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, calcFirst, calcLast, ref InterestAmount, ref TdInterestAmount);
+ CalcDailyCompoundInterest( endDate, position, closePosiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, calcFirst, calcLast, ref InterestAmount, ref TdInterestAmount);
}
else
{
- CalcDailySimpleInterest(preEodPosition, endDate, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, calcFirst, calcLast, ref InterestAmount, ref TdInterestAmount);
+ CalcDailySimpleInterest(preEodPosition, endDate, position, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, calcFirst, calcLast, ref InterestAmount, ref TdInterestAmount);
}
interest.InterestAmount = Math.Round(InterestAmount, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
@@ -685,26 +685,73 @@ namespace YLErp.Modules.SwapModule
/// 是否年化
/// 年化天数
///
- public void CalcDailyCompoundInterest(eod_swap_position preEodPosition, DateTime endDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, bool calcFirst, bool calcLast, ref decimal InterestAmount, ref decimal TdInterestAmount)
+ public void CalcDailyCompoundInterest( DateTime endDate, swap_position position, decimal principal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, bool calcFirst, bool calcLast, ref decimal InterestAmount, ref decimal TdInterestAmount)
{
- // 复利:利息并入本金
- CalcDailyInterest(preEodPosition, endDate, position, principal, posiPrincipal, flowEvent, annualDays, needPrice, floateRate, closePercent, orginPv, compoundInterest: true, calcFirst, calcLast, ref InterestAmount, ref TdInterestAmount);
+ var startDate = position.PosiStartDate;
+ decimal interestProfitSum = 0;
+ decimal TdInterestPrincipal = 0;
+ decimal interest = interestProfitSum * closePercent;
+ decimal tdinterest = interestProfitSum * closePercent;
+ int interestPeriod = position.interest_rest_days ?? 1;
+ // 复利:只能用要平仓的名义本金从头开始算
+ decimal dynomicPrincipal = principal;
+ decimal tdDynomicPrincipal = dynomicPrincipal;
+ var calcDays = (endDate - startDate).Days;
+ double floatRate = Convert.ToDouble(floateRate);
+ for (int i = 0; i <= calcDays; i++)
+ {
+ var accrueDate = startDate.AddDays(i);
+ if (!calcFirst && accrueDate == startDate) continue; // 首日不算头
+ if (!calcLast && accrueDate == endDate) continue; // 到期日不算尾
+ if (accrueDate >= startDate)
+ {
+ if (i % interestPeriod == 0)
+ {
+ // 复利时:利息并入本金
+ dynomicPrincipal = principal + interest;
+ tdDynomicPrincipal = principal + interest;
+ // 获取新的浮动利率
+ if (!string.IsNullOrEmpty(position.FloatRateUnderlyingCode))
+ {
+ var fr007RateDate = QdpCalendarHelper.GetNonHolidayDefore(accrueDate.AddDays(position.interest_rule ?? 0));
+ if (TryGetFloatRate(fr007RateDate, position.FloatRateUnderlyingCode, out double floatRate1))
+ {
+ if (floatRate1 != 0) floatRate = floatRate1;
+ }
+ else
+ {
+ throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fr007RateDate:yyyy年MM月dd日}的价格");
+ }
+ }
+ flowEvent.InterestPrincipal = tdDynomicPrincipal;
+ TdInterestPrincipal = tdDynomicPrincipal;
+ }
+ else
+ {
+ // 复利非重置日:利息不并入本金,不用closePercent缩放(principal已反映平仓比例)
+ flowEvent.InterestPrincipal = tdDynomicPrincipal;
+ TdInterestPrincipal = tdDynomicPrincipal;
+ }
+ flowEvent.FloatRate = Convert.ToDecimal(floatRate);
+ var interest1 = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
+ var tdinterest1 = TdInterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
+ if (position.IsAnnualized)
+ {
+ interest1 /= annualDays;
+ tdinterest1 /= annualDays;
+ }
+ interest += interest1;
+ tdinterest += tdinterest1;
+ }
+ }
+ InterestAmount = Math.Round(interest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
+ TdInterestAmount = Math.Round(tdinterest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
}
///
/// 计算单利 盘中(按重置天数分段,每段使用对应浮动利率)
///
- public void CalcDailySimpleInterest(eod_swap_position preEodPosition, DateTime endDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, bool calcFirst, bool calcLast, ref decimal InterestAmount, ref decimal TdInterestAmount)
- {
- // 单利:利息不并入本金
- CalcDailyInterest(preEodPosition, endDate, position, principal, posiPrincipal, flowEvent, annualDays, needPrice, floateRate, closePercent, orginPv, compoundInterest: false,calcFirst,calcLast, ref InterestAmount, ref TdInterestAmount);
- }
-
- ///
- /// 通用日度利息计算方法(单利/复利共用)
- ///
- /// 是否复利:true=利息并入本金,false=单利
- private void CalcDailyInterest(eod_swap_position preEodPosition, DateTime endDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, bool compoundInterest, bool calcFirst, bool calcLast, ref decimal InterestAmount, ref decimal TdInterestAmount)
+ public void CalcDailySimpleInterest(eod_swap_position preEodPosition, DateTime endDate, swap_position position, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, bool calcFirst, bool calcLast, ref decimal InterestAmount, ref decimal TdInterestAmount)
{
var startDate = position.PosiStartDate;
decimal interestProfitSum = preEodPosition.InterestProfitSum;
@@ -712,35 +759,27 @@ namespace YLErp.Modules.SwapModule
decimal interest = interestProfitSum * closePercent;
decimal tdinterest = interestProfitSum * closePercent;
int interestPeriod = position.interest_rest_days ?? 1;
- decimal dynomicPrincipal = (preEodPosition.TdInterestPrincipal + posiPrincipal - orginPv);
+ // 单利:可用上一日计息基数
+ decimal dynomicPrincipal = preEodPosition.TdInterestPrincipal + posiPrincipal - orginPv;
decimal tdDynomicPrincipal = dynomicPrincipal;
var calcDays = (endDate - startDate).Days;
double floatRate = Convert.ToDouble(floateRate);
for (int i = 0; i <= calcDays; i++)
{
var accrueDate = startDate.AddDays(i);
- if (!calcFirst && accrueDate == startDate) continue; // 首日不算头
- if (!calcLast && accrueDate == endDate) continue; // 到期日不算尾
+ if (!calcFirst && accrueDate == startDate) continue; // 首日不算头
+ if (!calcLast && accrueDate == endDate) continue; // 到期日不算尾
if (accrueDate > preEodPosition.ValueDate)
{
if (i % interestPeriod == 0)
{
- // 复利时:利息并入本金
- if (compoundInterest)
- {
- dynomicPrincipal = principal + interest;
- tdDynomicPrincipal = principal + interest;
- }
// 获取新的浮动利率
if (!string.IsNullOrEmpty(position.FloatRateUnderlyingCode))
{
var fr007RateDate = QdpCalendarHelper.GetNonHolidayDefore(accrueDate.AddDays(position.interest_rule ?? 0));
if (TryGetFloatRate(fr007RateDate, position.FloatRateUnderlyingCode, out double floatRate1))
{
- if (floatRate1 != 0)
- {
- floatRate = floatRate1;
- }
+ if (floatRate1 != 0) floatRate = floatRate1;
}
else
{