盘中单复利计算分开,复利不取上一次收盘,直接从新算
This commit is contained in:
@@ -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
|
||||
/// <param name="isAnnualized">是否年化</param>
|
||||
/// <param name="annualDays">年化天数</param>
|
||||
/// <returns></returns>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算单利 盘中(按重置天数分段,每段使用对应浮动利率)
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通用日度利息计算方法(单利/复利共用)
|
||||
/// </summary>
|
||||
/// <param name="compoundInterest">是否复利:true=利息并入本金,false=单利</param>
|
||||
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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user