利息计算参考申万poc
This commit is contained in:
@@ -93,8 +93,7 @@ namespace YLErp.Modules.SwapModule
|
||||
unwindData.PositionQty = position != null ? position.PosiQuantity : Convert.ToDecimal(td.TradeAmount);
|
||||
unwindData.AnnualDays = tradeExtend == null ? 365 : tradeExtend.ExtendObj.AnnualDays;
|
||||
unwindData.CloseMethod = (int)CloseMethodEnum.全部平仓;
|
||||
var closePercent = GetUnwindPercent(tradeId);
|
||||
unwindData.ClosePercent = 1 - closePercent;
|
||||
unwindData.ClosePercent = 1;
|
||||
unwindData.CloseNotionalValue = unwindData.PosiNotionalValue;
|
||||
unwindData.CloseQty = unwindData.PositionQty;
|
||||
if (position != null)
|
||||
@@ -311,6 +310,7 @@ namespace YLErp.Modules.SwapModule
|
||||
var tradeExtend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == tradeId);
|
||||
List<int> eventTypes = new List<int>() { (int)SwapEventTypeEnum.平仓, (int)SwapEventTypeEnum.互换, (int)SwapEventTypeEnum.自动互换 };
|
||||
var lastEod = DbContext.eod_swap.Where(x => x.ValueDate < unwindDate && x.SwapTradeId == tradeId).OrderByDescending(o => o.ValueDate).FirstOrDefault();
|
||||
var orginPv = lastEod != null ? lastEod.NotionalValue : 0;
|
||||
var _preSetteDate = lastEod == null ? unwindDate.AddDays(-1) : lastEod.ValueDate;
|
||||
List<eod_swap_position> lastEodPositions = new SwapEodPositionService(this).GetPreEodPositions(tradeId, _preSetteDate);//上一交易数据
|
||||
var posiLongNotionalValue = longPositions.Sum(s => s.PosiNotionalValue);// 剩余名义本金
|
||||
@@ -319,7 +319,7 @@ namespace YLErp.Modules.SwapModule
|
||||
var posiNotionalValue = stockEqvNotional * closePercent;//剩余名义本金
|
||||
var grossPrice = realPostitions.Where(x => x.PosiDirection > 0).FirstOrDefault()?.PosiGrossPrice;
|
||||
bool tdClose = DbContext.swap_flow_event.Any(x => x.SwapTradeId == tradeId && x.UnwindDate == unwindDate && eventTypes.Contains(x.EventType) && x.DataState == (int)SwapFlowDateStateEnum.完成);
|
||||
interests = GetInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions, stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue, closePercent, eventType, tdClose, false, grossPrice ?? 0, true, false, false);
|
||||
interests = GetInterests(td, tradeExtend, valueDate, unwindDate, lastEodPositions, positions, stockEqvNotional, posiLongNotionalValue, posiShortNotionalValue, posiNotionalValue, closePercent, eventType, tdClose, false, grossPrice ?? 0, orginPv, true, false, false);
|
||||
return interests;
|
||||
}
|
||||
/// <summary>
|
||||
@@ -355,6 +355,7 @@ namespace YLErp.Modules.SwapModule
|
||||
bool tdClose,
|
||||
bool needPrice,
|
||||
decimal grossPrice,
|
||||
decimal orginPv,
|
||||
bool add = false,
|
||||
bool calcLast = true,
|
||||
bool settment = true)
|
||||
@@ -377,8 +378,8 @@ namespace YLErp.Modules.SwapModule
|
||||
if (!preDealDate.HasValue)
|
||||
{
|
||||
preEodPosition = new eod_swap_position();
|
||||
preEodPosition.PosiStartDate = startDate;
|
||||
preEodPosition.ValueDate = startDate;
|
||||
preEodPosition.PosiStartDate = position.PosiStartDate;
|
||||
preEodPosition.ValueDate = position.PosiStartDate;
|
||||
}
|
||||
var swapIntervalToday = position.SwapIntervalList.Where(x => x.Date <= startDate).OrderByDescending(o => o.Date).FirstOrDefault();
|
||||
if (position.InterestMode == (int)InterestModeEnum.固定值)
|
||||
@@ -440,7 +441,13 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
rate = swapIntervalToday.Rate;
|
||||
}
|
||||
swap_flow_event interest = InitSwapDealInterest(td, valueDate, endDate, rate, positionClone, add, swap, _posiNotionalValue, _closePosiNotionalValue, newClosePercent, annualDays, eventType, preEodPosition, needPrice, settment);
|
||||
if (preEodPosition.id == 0)
|
||||
{
|
||||
preEodPosition.FloatRate = positionClone.FloatRate;
|
||||
preEodPosition.TdInterestPrincipal = _posiNotionalValue;
|
||||
preEodPosition.PosiNotionalValue = _posiNotionalValue;
|
||||
}
|
||||
swap_flow_event interest = InitSwapDealInterest(td, valueDate, endDate, rate, positionClone, add, swap, _posiNotionalValue, _closePosiNotionalValue, newClosePercent, annualDays, eventType, preEodPosition, needPrice, settment, orginPv);
|
||||
interests.Add(interest);
|
||||
}
|
||||
return interests;
|
||||
@@ -474,7 +481,8 @@ namespace YLErp.Modules.SwapModule
|
||||
int eventType,
|
||||
eod_swap_position preEodPosition,
|
||||
bool needPrice,
|
||||
bool settment
|
||||
bool settment,
|
||||
decimal orginPv
|
||||
)
|
||||
{
|
||||
DateTime lastSwapDate = preEodPosition.ValueDate;
|
||||
@@ -514,11 +522,11 @@ namespace YLErp.Modules.SwapModule
|
||||
var floateRate = preEodPosition.FloatRate;
|
||||
if (settment)//收盘利息计算
|
||||
{
|
||||
CalcDailyCompoundInterestByEod(preEodPosition, endDate, td.StartDate.Value, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, ref InterestAmount, ref TdInterestAmount);
|
||||
CalcDailyCompoundInterestByEod(preEodPosition, endDate, td.StartDate.Value, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, ref InterestAmount, ref TdInterestAmount);
|
||||
}
|
||||
else
|
||||
{
|
||||
CalcDailyCompoundInterest(preEodPosition, endDate, td.StartDate.Value, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, ref InterestAmount, ref TdInterestAmount);
|
||||
CalcDailyCompoundInterest(preEodPosition, endDate, td.StartDate.Value, position, closePosiNotionalValue, posiNotionalValue, interest, annualDays, needPrice, floateRate, closePrecent, orginPv, ref InterestAmount, ref TdInterestAmount);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -554,8 +562,8 @@ namespace YLErp.Modules.SwapModule
|
||||
|
||||
}
|
||||
|
||||
interest.InterestAmount = decimal.Parse(InterestAmount.ToString("0.0000"));
|
||||
interest.TdInterestAmount = decimal.Parse(TdInterestAmount.ToString("0.0000"));
|
||||
interest.InterestAmount = Math.Round(InterestAmount, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
interest.TdInterestAmount = Math.Round(TdInterestAmount, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
interest.InterestClosePnL = interest.InterestAmount * interestRatio;
|
||||
}
|
||||
if (add)
|
||||
@@ -576,7 +584,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="isAnnualized">是否年化</param>
|
||||
/// <param name="annualDays">年化天数</param>
|
||||
/// <returns></returns>
|
||||
public void CalcDailyCompoundInterest(eod_swap_position preEodPosition, DateTime endDate, DateTime tradeDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, ref decimal InterestAmount, ref decimal TdInterestAmount)
|
||||
public void CalcDailyCompoundInterest(eod_swap_position preEodPosition, DateTime endDate, DateTime tradeDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, ref decimal InterestAmount, ref decimal TdInterestAmount)
|
||||
{
|
||||
DateTime lastSwapDate = preEodPosition.ValueDate;
|
||||
decimal interestProfitSum = preEodPosition.InterestProfitSum;
|
||||
@@ -618,35 +626,36 @@ namespace YLErp.Modules.SwapModule
|
||||
}
|
||||
|
||||
}
|
||||
flowEvent.InterestPrincipal = tdDynomicPrincipal;
|
||||
flowEvent.InterestPrincipal = tdDynomicPrincipal * closePercent;
|
||||
TdInterestPrincipal = tdDynomicPrincipal;
|
||||
}
|
||||
else
|
||||
{
|
||||
flowEvent.InterestPrincipal = TdInterestPrincipal * closePercent;
|
||||
flowEvent.InterestPrincipal = (preEodPosition.TdInterestPrincipal + posiPrincipal - orginPv) * closePercent;
|
||||
tdDynomicPrincipal = flowEvent.InterestPrincipal;
|
||||
TdInterestPrincipal = (preEodPosition.TdInterestPrincipal + posiPrincipal - orginPv);
|
||||
}
|
||||
flowEvent.FloatRate = Convert.ToDecimal(floatRate);
|
||||
var interest1 = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
var tdinterest1 = tdDynomicPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
var tdinterest1 = TdInterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
if (position.IsAnnualized)
|
||||
{
|
||||
interest1 /= annualDays;
|
||||
tdinterest1 /= annualDays;
|
||||
}
|
||||
interest += decimal.Parse(interest1.ToString("0.0000"));
|
||||
tdinterest += decimal.Parse(tdinterest1.ToString("0.0000"));
|
||||
interest += interest1;
|
||||
tdinterest += tdinterest1;
|
||||
|
||||
}
|
||||
else
|
||||
else if (lastSwapDate >= rateDate)
|
||||
{
|
||||
interest = interestProfitSum * closePercent;
|
||||
tdinterest = interestProfitSum * closePercent;
|
||||
}
|
||||
|
||||
}
|
||||
InterestAmount = interest;
|
||||
TdInterestAmount = tdinterest;
|
||||
InterestAmount = Math.Round(interest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
TdInterestAmount = Math.Round(tdinterest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -661,7 +670,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="isAnnualized">是否年化</param>
|
||||
/// <param name="annualDays">年化天数</param>
|
||||
/// <returns></returns>
|
||||
public void CalcDailyCompoundInterestByEod(eod_swap_position preEodPosition, DateTime endDate, DateTime tradeDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, ref decimal InterestAmount, ref decimal TdInterestAmount)
|
||||
public void CalcDailyCompoundInterestByEod(eod_swap_position preEodPosition, DateTime endDate, DateTime tradeDate, swap_position position, decimal principal, decimal posiPrincipal, swap_flow_event flowEvent, int annualDays, bool needPrice, decimal floateRate, decimal closePercent, decimal orginPv, ref decimal InterestAmount, ref decimal TdInterestAmount)
|
||||
{
|
||||
decimal interestProfitSum = preEodPosition.InterestProfitSum;
|
||||
decimal interest = preEodPosition.TdInterestIncome;
|
||||
@@ -687,19 +696,27 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{fr007RateDate:yyyy年MM月dd日}的价格");
|
||||
}
|
||||
flowEvent.InterestPrincipal = tdDynomicPrincipal;
|
||||
flowEvent.InterestPrincipal = tdDynomicPrincipal * closePercent;
|
||||
interest = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
tdinterest = tdDynomicPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
if (position.IsAnnualized)
|
||||
{
|
||||
interest /= annualDays;
|
||||
tdinterest /= annualDays;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
flowEvent.InterestPrincipal = preEodPosition.TdInterestPrincipal * closePercent;
|
||||
tdDynomicPrincipal = flowEvent.InterestPrincipal;
|
||||
}
|
||||
interest = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
tdinterest = tdDynomicPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
if (position.IsAnnualized)
|
||||
{
|
||||
interest /= annualDays;
|
||||
tdinterest /= annualDays;
|
||||
flowEvent.InterestPrincipal = (preEodPosition.TdInterestPrincipal + tdDynomicPrincipal - orginPv) * closePercent;
|
||||
var interest1 = flowEvent.InterestPrincipal * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
var tdinterest1 = (preEodPosition.TdInterestPrincipal + tdDynomicPrincipal - orginPv) * (flowEvent.InterestRate + Convert.ToDecimal(floatRate));
|
||||
if (position.IsAnnualized)
|
||||
{
|
||||
interest1 /= annualDays;
|
||||
tdinterest1 /= annualDays;
|
||||
}
|
||||
interest = interest1;
|
||||
tdinterest = tdinterest1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -707,8 +724,8 @@ namespace YLErp.Modules.SwapModule
|
||||
flowEvent.InterestPrincipal = preEodPosition.TdInterestPrincipal * closePercent;
|
||||
}
|
||||
flowEvent.FloatRate = Convert.ToDecimal(floatRate);
|
||||
InterestAmount = interest;
|
||||
TdInterestAmount = tdinterest;
|
||||
InterestAmount = Math.Round(interest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
TdInterestAmount = Math.Round(tdinterest, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1320,6 +1337,7 @@ namespace YLErp.Modules.SwapModule
|
||||
}
|
||||
item.PayDate = unwindData.PayDate;
|
||||
item.UnwindDate = unwindData.UnwindDate;
|
||||
item.EventDate = unwindData.ValueDate;
|
||||
item.EventId = swapEvent.id;
|
||||
DbContext.swap_flow_event.Add(item);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user