fix: 手动平仓分红收益计算

This commit is contained in:
gongpei
2025-10-23 15:25:47 +08:00
parent 936bed21f8
commit 866f13d85e
7 changed files with 34 additions and 9 deletions
@@ -183,5 +183,8 @@ namespace YLErp.DBModels
/// 支付日
/// </summary>
public DateTime? PayDate { get; set; }
[NotMapped]
public DateTime? TradeStartDate { get; set; }
}
}
@@ -326,6 +326,7 @@ namespace YLErp.DBModels
/// 债券增值税
/// </summary>
[Column("value_added_tax")]
[DisplayName("增值税率")]
public decimal? ValueAddedTax { get; set; }
public override string ToString()
@@ -96,11 +96,19 @@ namespace YLErp.Modules.EodModule
/// <param name="startDate"></param>
/// <param name="endDate"></param>
/// <returns></returns>
public List<BondPayment> GetBondPayments(string underylingCode, DateTime startDate, DateTime endDate)
public List<BondPayment> GetBondPayments(string underlyingCode, DateTime startDate, DateTime endDate)
{
var result = DbContext.bondPayment.Where(x => x.underlyingCode == underylingCode && x.payment_date > startDate && x.payment_date <= endDate).AsNoTracking().ToList();
var result = DbContext.bondPayment.Where(x => x.underlyingCode == underlyingCode && x.payment_date > startDate && x.payment_date <= endDate).AsNoTracking().ToList();
return result;
}
public List<BondPayment> GetTargetDatePayments(string underlyingCode, DateTime targetDate)
{
var startDate = targetDate.Date;
var endDate = startDate.AddDays(1);
return DbContext.bondPayment.AsNoTracking().Where(x => x.underlyingCode == underlyingCode && x.payment_date >= startDate && x.payment_date < endDate).ToList();
}
/// <summary>
/// 计算某债券某段时间的期间付息
/// </summary>
@@ -111,9 +119,9 @@ namespace YLErp.Modules.EodModule
/// <param name="longRatio">多空方向</param>
/// <param name="payDirection">收支方向</param>
/// <returns></returns>
public decimal CalcPayment(string underylingCode, DateTime startDate, DateTime endDate, decimal qty, decimal longRatio, decimal payDirection)
public decimal CalcPayment(string underlyingCode, DateTime startDate, DateTime endDate, decimal qty, decimal longRatio, decimal payDirection)
{
var payments = GetBondPayments(underylingCode, startDate, endDate);
var payments = GetBondPayments(underlyingCode, startDate, endDate);
return CalcPayment(payments, qty, longRatio, payDirection);
}
/// <summary>
@@ -71,6 +71,7 @@ namespace YLErp.Modules.SwapModule
}
else
{
unwindData.TradeStartDate = td.StartDate;
unwindData.CloseType = commodity ? 1 : 2;
unwindData.StartDate = td.TradeDate.Value;
if (preDealDate.HasValue)
@@ -880,13 +881,15 @@ namespace YLErp.Modules.SwapModule
floatEvent.TradingFeePending = position.PosiTradingFeePending * unwindData.ClosePercent;
floatEvent.TradingFeePending = Math.Round(floatEvent.TradingFeePending, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
floatEvent.TradingFee = closeFee;
BondPaymentService bondPaymentService = new BondPaymentService(UserInfo);
var tax = GetUnderlyingTax(floatEvent.UnderlyingCode);
var payments = bondPaymentService.GetBondPayments(floatEvent.UnderlyingCode, td.StartDate.Value, floatEvent.UnwindDate.Value);
var payment = bondPaymentService.CalcPayment(payments, unwindQty, longRatio, floatRatio);
floatEvent.DividendIn = payment / (1 + tax) * (1 - tax);
// 只计算事件日期当天的分红收益
var payments = bondPaymentService.GetTargetDatePayments(floatEvent.UnderlyingCode, floatEvent.EventDate);
floatEvent.DividendIn = bondPaymentService.CalcPayment(payments, unwindQty, longRatio, floatRatio) / (1 + tax) * (1 - tax);
floatEvent.DividendIn = Math.Round(floatEvent.DividendIn, 2, MidpointRounding.AwayFromZero);
floatEvent.DividendPending = bondPaymentService.CalcPayment(payments, floatEvent.PositionQty ?? 0, longRatio, floatRatio);
floatEvent.DividendPending = bondPaymentService.CalcPayment(payments, floatEvent.PositionQty ?? 0, longRatio, floatRatio) / (1 + tax) * (1 - tax);
floatEvent.MarkClosePnl = (unwindPrice - position.PosiGrossPrice) * unwindQty * floatRatio * longRatio;
floatEvent.MarkClosePnl = Math.Round(floatEvent.MarkClosePnl + ((floatEvent.TradingFeePending+ closeFee) * floatRatio * -1) + floatEvent.DividendIn, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
@@ -308,6 +308,10 @@
<label class='formlabel'>描述</label>
<input id='Desc' class='text-box' type='text' value='@(underlying.UnderlyingDesc)' name='Desc' />
</div>
<div class='form-group col-6'>
<label class='formlabel'>增值税率</label>
<input id='ValueAddedTax' class='text-box' type='number' value='@(underlying.ValueAddedTax)' name='ValueAddedTax' />
</div>
</div>
<div class="Stock" style="padding-left:130px;">
@@ -170,6 +170,11 @@
@Html.MyDisplayFor(m => m.Price)
</tr>
}
<tr>
<th class="tdRight">增值税率</th>
<td>@(Model.ValueAddedTax.OtcFormatPercent())</td>
</tr>
</tbody>
</table>
</div>
@@ -51,6 +51,7 @@ const vue = new Vue({
});
this.ratio = this.floatPosition.PayDirection == 1 ? -1 : 1;
this.shortRatio = this.floatPosition.PositionType == 1 ? 1 : -1;
this.TradeStartDate = model.TradeStartDate;
},
IsBond(instType) {
return tradeHelper.IsBond(instType);
@@ -269,7 +270,7 @@ const vue = new Vue({
var thisObj = this;
let ratio = this.floatPosition.PositionType == 1 ? 1 : -1;
let floatRatio = this.floatPosition.PayDirection == 1 ? 1 : -1;
var postData = { startDate: thisObj.floatPosition.PosiStartDate, endDate: thisObj.deal.UnwindDate, underlyingCode: thisObj.floatPosition.UnderlyingCode }
var postData = { startDate: thisObj.TradeStartDate, endDate: thisObj.deal.UnwindDate, underlyingCode: thisObj.floatPosition.UnderlyingCode }
main.post("/BondPayment/GetBondPayMentInterest", postData, { async: false }).done(function (resp) {
thisObj.floatPosition.DividendIn = parseFloat(thisObj.deal.CloseQty) * resp.obj * ratio * floatRatio;
var posiQty = parseFloat(thisObj.floatPosition.Quantity) - parseFloat(thisObj.deal.CloseQty);