diff --git a/Framework/YLErp.Core/ConsGlobal.cs b/Framework/YLErp.Core/ConsGlobal.cs
index 22ca70d5..f1bbb324 100644
--- a/Framework/YLErp.Core/ConsGlobal.cs
+++ b/Framework/YLErp.Core/ConsGlobal.cs
@@ -58,6 +58,16 @@ namespace YLErp
/// 互换计算岗邮件配置key
///
public const string SwapSettlementConfigEmail = "SettlementEmail";
+ ///
+ /// 价格四舍五入保留位数
+ ///
+
+ public const int PriceRound = 4;
+ ///
+ /// 金额四舍五入保留位数
+ ///
+
+ public const int MoneyRound = 4;
#region----有效Valid/无效InValid----
diff --git a/YLErpDAL/BLL/EodSettlement/RealtimePnlCalc.cs b/YLErpDAL/BLL/EodSettlement/RealtimePnlCalc.cs
index df7b4f86..a6b18619 100644
--- a/YLErpDAL/BLL/EodSettlement/RealtimePnlCalc.cs
+++ b/YLErpDAL/BLL/EodSettlement/RealtimePnlCalc.cs
@@ -587,11 +587,11 @@ namespace YLErp.BLL.Eod
bondDb.SaveChanges();
SetClientPositionPrice(clientPosition);
clientPosition.today_profit_loss = clientPosition.swap_market_value - lastPv;
- bondDb.SaveChanges();
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)//发kafka 获取成交收益率
{
- CalcBandPrice(clientPosition);
+ BondCalcApi(clientPosition);
}
+ bondDb.SaveChanges();
}
var sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
bondDb.BulkDelete(sql);
@@ -630,7 +630,7 @@ namespace YLErp.BLL.Eod
bondDb.SaveChanges();
SetClientPositionPrice(clientPosition);
clientPosition.today_profit_loss = clientPosition.swap_market_value;
- bondDb.SaveChanges();
+
//发kafka 获取成交收益率
if (clientPosition.deal_full_price_avg > 0 && enableCalcBongd)
{
@@ -640,6 +640,7 @@ namespace YLErp.BLL.Eod
{
clientPosition.update_time = DateTime.Now;
}
+ bondDb.SaveChanges();
}
}
#endregion
diff --git a/YLErpDAL/Modules/SwapModule/SwapDealService.cs b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
index 9e30f482..bb640927 100644
--- a/YLErpDAL/Modules/SwapModule/SwapDealService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapDealService.cs
@@ -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 eventTypes = new List() { (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 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;
}
///
@@ -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
/// 是否年化
/// 年化天数
///
- 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);
}
///
@@ -661,7 +670,7 @@ namespace YLErp.Modules.SwapModule
/// 是否年化
/// 年化天数
///
- 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);
}
///
@@ -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);
}
diff --git a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
index ff92f889..460aa950 100644
--- a/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
+++ b/YLErpDAL/Modules/SwapModule/SwapEodPositionService.cs
@@ -131,6 +131,7 @@ namespace YLErp.Modules.SwapModule
td.trade_extend = tradeExtend;
var todyEodPositions = allEodPositions.Where(x => x.ValueDate == settleDate).ToList();
var allPositionQty = realPositions.Sum(x => x.PosiQuantity);//总剩余持仓数量
+ var orginPv = eodPositions.Sum(s => s.PosiNotionalValue);
if (longShort && td.ExerciseDate.Value == settleDate && allPositionQty != 0)//多空组合判断是否已到到期日且无持仓信息
{
throw new Exception($"交易【{td.TradeNumber}】到期扔有持仓信息");
@@ -162,7 +163,7 @@ namespace YLErp.Modules.SwapModule
}
var grossPrice = curEodPosis.Where(x => x.PosiDirection > 0).FirstOrDefault()?.PosiGrossPrice ?? 0;
//处理利息腿
- DealInterests(interestList, eodPositions, todyEodPositions, settleDate, td, flowEvents, autoInterests, lastEodSwap, posiLongNotional, posiShortNotional, closePosiNotional, grossPrice);
+ DealInterests(interestList, eodPositions, todyEodPositions, settleDate, td, flowEvents, autoInterests, lastEodSwap, posiLongNotional, posiShortNotional, closePosiNotional, grossPrice, orginPv);
DealAutoInterests(autoInterests, td, settleDate, preDealDate, posiLongNotional + posiShortNotional);
//多空组合判断是否已到到期日且无持仓信息
if (longShort && td.ExerciseDate.Value == settleDate && allPositionQty == 0)
@@ -211,50 +212,6 @@ namespace YLErp.Modules.SwapModule
DbContext.SaveChanges();
}
///
- /// 追加预付金腿归档
- ///
- ///
- ///
- public void SwapEodMarginCompose(DateTime settleDate, IEnumerable ClientIds)
- {
- var tradePredicate = PredicateBuilder.Create(n => n.ValidState != ConsGlobal.InValid
- && n.TradeType == "收益互换"
- && n.TradeDate <= settleDate
- && n.ExerciseDate >= settleDate
- && (n.TradeStatus == ConsTrade.确认成交 || n.UnWindDate >= settleDate)
- );
- if (ClientIds != null && ClientIds.Any())
- {
- tradePredicate = tradePredicate.And(x => ClientIds.Contains(x.ClientId));
- }
- var marginPredicate = PredicateBuilder.Create(n => n.IsInitial && n.HappenDate == settleDate && n.InterestMode == (int)InterestModeEnum.追加预付金 && !n.Invalid);
- var query = from p in DbContext.swap_position.Where(marginPredicate)
- join t in DbContext.trade.Where(tradePredicate) on p.SwapTradeId equals t.id
- select new
- {
- t,
- p
- };
- var result = query.ToList();
- var posiIds = result.Select(x => x.p.id).ToList();
- var eodSwapPositions = DbContext.eod_swap_position.Where(x => posiIds.Contains(x.SwapTradeId) && x.ValueDate == settleDate).ToList();
- foreach (var item in result)
- {
- List interestList = new List() { item.p };
- var td = item.t;
- var eodPosi = eodSwapPositions.FirstOrDefault(x => x.PositionId == item.p.id);
- var posiLongNotional = eodSwapPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Long).Sum(s => s.PosiNotionalValue);
- var posiShortNotional = eodSwapPositions.Where(s => s.PositionType == (int)PositionTypeFlag.Short).Sum(s => s.PosiNotionalValue);
- var grossPrice = eodSwapPositions.Where(x => x.PosiDirection > 0).FirstOrDefault()?.PosiGrossPrice ?? 0;
- //处理利息腿
- DealInterest(item.p, eodPosi, settleDate, td, posiLongNotional, posiShortNotional, grossPrice);
- }
- if (result.Count > 0)
- {
- DbContext.SaveChanges();
- }
- }
- ///
/// 处理利息腿归档
///
/// 利息腿持仓信息
@@ -277,7 +234,8 @@ namespace YLErp.Modules.SwapModule
decimal posiLongNational,
decimal posiShortNational,
decimal closeNational,
- decimal grossPrice)
+ decimal grossPrice,
+ decimal orginPv)
{
var hasClose = flowEvents.Any(x => x.EventType == (int)SwapEventTypeEnum.平仓);
var hasSwap = flowEvents.Any(x => x.EventType == (int)SwapEventTypeEnum.互换);
@@ -299,7 +257,7 @@ namespace YLErp.Modules.SwapModule
{
if (!hasClose)//当日无平仓
{
- var _autoInterests = SaveAutoEodInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, lastEodSwap, posiLongNational, posiShortNational, grossPrice);
+ var _autoInterests = SaveAutoEodInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, lastEodSwap, posiLongNational, posiShortNational, grossPrice, orginPv);
if (_autoInterests.Count > 0)
{
autoInterests.AddRange(_autoInterests);
@@ -307,7 +265,7 @@ namespace YLErp.Modules.SwapModule
}
else
{
- var _autoInterests = SaveAutoEodWithCloseInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, posiLongNational, posiShortNational, swapEvents, closeNational, true, grossPrice);
+ var _autoInterests = SaveAutoEodWithCloseInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, posiLongNational, posiShortNational, swapEvents, closeNational, true, grossPrice, orginPv);
if (_autoInterests.Count > 0)
{
autoInterests.AddRange(_autoInterests);
@@ -320,38 +278,14 @@ namespace YLErp.Modules.SwapModule
}
else if (hasClose)
{
- SaveAutoEodWithCloseInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, posiLongNational, posiShortNational, swapEvents, closeNational, false, grossPrice);
+ SaveAutoEodWithCloseInterestPosition(eodPosition, tdEodPosition, interest, td, settleDate, insterval, posiLongNational, posiShortNational, swapEvents, closeNational, false, grossPrice, orginPv);
}
else//无自动互换、互换/平仓,复制上一日终信息,并计算当日新增利息
{
- SaveEodInterestPositionCopy(eodPosition, tdEodPosition, settleDate, td, interest, lastEodSwap, true, posiLongNational, posiShortNational, grossPrice);
+ SaveEodInterestPositionCopy(eodPosition, tdEodPosition, settleDate, td, interest, lastEodSwap, true, posiLongNational, posiShortNational, grossPrice, orginPv);
}
}
}
-
- ///
- /// 处理利息腿归档
- ///
- /// 利息腿持仓信息
- /// 上一日终归档持仓信息
- /// 当日归档持仓信息
- /// 当前结算日期
- /// 互换交易主信息
- /// 当日平仓/互换信息
- /// 自动互换集合
- /// 多空组合平仓利息腿信息
- /// 上一日终框架合约
- private void DealInterest(swap_position interest,
- eod_swap_position tdEodPosition,
- DateTime settleDate,
- trade td,
- decimal posiLongNational,
- decimal posiShortNational,
- decimal grossPrice)
- {
- var insterval = interest.SwapIntervalList.FirstOrDefault(x => x.Date == settleDate && x.Settlement == 1);//自动互换观察日信息
- SaveAutoEodInterestPosition(null, tdEodPosition, interest, td, settleDate, insterval, null, posiLongNational, posiShortNational, grossPrice);
- }
///
/// 处理浮动腿归档
///
@@ -758,7 +692,7 @@ namespace YLErp.Modules.SwapModule
/// 上一平仓/互换日期
/// 当日平仓金额
/// 上一日终框架合约估值
- private List SaveAutoEodInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, eod_swap lastEodSwap, decimal posiLongNotional, decimal posiShortNational, decimal grossPrice)
+ private List SaveAutoEodInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, eod_swap lastEodSwap, decimal posiLongNotional, decimal posiShortNational, decimal grossPrice, decimal orginPv)
{
var tradeExtend = td.trade_extend.ExtendObj;
@@ -792,7 +726,11 @@ namespace YLErp.Modules.SwapModule
positions.Add(position);
List preEodPositions = new List();
preEodPositions.Add(eodPayPosition);
- var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, posiNotionalValue, closePercent, (int)SwapEventTypeEnum.自动互换, false, true, grossPrice, true);
+ if (position.InterestMode == (int)InterestModeEnum.固定值)
+ {
+ orginPv = eodPayPosition.InterestPrincipalFix;
+ }
+ var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, posiNotionalValue, closePercent, (int)SwapEventTypeEnum.自动互换, false, true, grossPrice, orginPv, true);
decimal InterestAmount = interests.Sum(x => x.InterestAmount);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
@@ -855,7 +793,7 @@ namespace YLErp.Modules.SwapModule
/// 当日平仓金额
/// 上一日终框架合约估值
/// 平仓主信息
- private List SaveAutoEodWithCloseInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, decimal posiLongNotional, decimal posiShortNational, List flowEvents, decimal closeNational, bool autoSwap, decimal grossPrice)
+ private List SaveAutoEodWithCloseInterestPosition(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, swap_position position, trade td, DateTime valueDate, IntervalModel interval, decimal posiLongNotional, decimal posiShortNational, List flowEvents, decimal closeNational, bool autoSwap, decimal grossPrice, decimal orginPv)
{
var tradeExtend = td.trade_extend.ExtendObj;
@@ -879,6 +817,10 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition = eodPayPosition.Clone();
newEodPayPosition.id = 0;
}
+ if (position.InterestMode == (int)InterestModeEnum.固定值)
+ {
+ orginPv = eodPayPosition.InterestPrincipalFix;
+ }
decimal closePercent = oriPosiNotionalValue == 0 ? 0 : closeNational / oriPosiNotionalValue;
var eventType = autoSwap ? (int)SwapEventTypeEnum.自动互换 : (int)SwapEventTypeEnum.平仓;
bool longShort = td.StructureType == ClientMarginTypeEnum.多空组合.ToString();
@@ -894,7 +836,7 @@ namespace YLErp.Modules.SwapModule
positions.Add(position);
List preEodPositions = new List();
preEodPositions.Add(eodPayPosition);
- var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, closeNational, 1, eventType, false, true, grossPrice, true);
+ var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNotional, posiShortNational, closeNational, 1, eventType, false, true, grossPrice, orginPv, true);
decimal TdInterestAmount = interests.Sum(x => x.TdInterestAmount);
newEodPayPosition.ValueDate = valueDate;
@@ -968,7 +910,7 @@ namespace YLErp.Modules.SwapModule
/// 上一交易日
/// 当前结算日
/// 互换交易主干
- private void SaveEodInterestPositionCopy(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, DateTime valueDate, trade td, swap_position position, eod_swap lastEodSwap, bool needPrice, decimal posiLongNational, decimal posiShortNational, decimal grossPrice)
+ private void SaveEodInterestPositionCopy(eod_swap_position eodPayPosition, eod_swap_position newEodPayPosition, DateTime valueDate, trade td, swap_position position, eod_swap lastEodSwap, bool needPrice, decimal posiLongNational, decimal posiShortNational, decimal grossPrice, decimal orginPv)
{
List intervals = position.SwapIntervalList;
var tradeExtend = td.trade_extend.ExtendObj;
@@ -1003,7 +945,10 @@ namespace YLErp.Modules.SwapModule
newEodPayPosition.id = 0;
newEodPayPosition.PositionId = position.id;
}
-
+ if (position.InterestMode == (int)InterestModeEnum.固定值)
+ {
+ orginPv = eodPayPosition.InterestPrincipalFix;
+ }
bool longShort = td.StructureType == ClientMarginTypeEnum.多空组合.ToString();
decimal oriPosiNotionalValue = posiLongNational + posiShortNational;
decimal posiNotionalValue = oriPosiNotionalValue;
@@ -1034,7 +979,7 @@ namespace YLErp.Modules.SwapModule
{
preEodPositions.Add(eodPayPosition);
}
- var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNational, posiShortNational, posiNotionalValue, closePercent, 0, false, needPrice, grossPrice);
+ var interests = new SwapDealService(this).GetInterests(td, td.trade_extend, valueDate, valueDate, preEodPositions, positions, posiNotionalValue, posiLongNational, posiShortNational, posiNotionalValue, closePercent, 0, false, needPrice, grossPrice, orginPv);
UpdateDbOption(newEodPayPosition);
newEodPayPosition.PosiStatus = 0;
@@ -2039,43 +1984,7 @@ namespace YLErp.Modules.SwapModule
return;
}
}
- ///
- /// 确认交易后,生成eod数据
- ///
- ///
- public void InitSaveEodSwapPosition(trade td)
- {
- //if (td.StartDate > td.TradeDate)
- //{
- // return;
- //}
- var positions = DbContext.swap_position.Where(x => x.SwapTradeId == td.id && x.IsInitial && !x.Invalid).ToList();
- var posiList = positions.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)).ToList();
- var interestList = positions.Where(x => string.IsNullOrEmpty(x.UnderlyingCode)).ToList();
- var eodSwapPostions = DbContext.eod_swap_position.Where(x => x.SwapTradeId == td.id);
- var eodSwaps = DbContext.eod_swap.Where(x => x.SwapTradeId == td.id);
- td.trade_extend = DbContext.trade_extend.FirstOrDefault(x => x.TradeId == td.id);
- List eventTypes = new List() { (int)SwapFlowEventTypeEnum.平仓, (int)SwapFlowEventTypeEnum.互换, (int)SwapFlowEventTypeEnum.自动互换, (int)SwapFlowEventTypeEnum.开仓 };
- var flowEvents = GetSwapFlowEvents(td.id, td.StartDate.Value, eventTypes);//当日平仓/互换/自动互换信息
- DbContext.eod_swap_position.RemoveRange(eodSwapPostions);
- DbContext.eod_swap.RemoveRange(eodSwaps);
- var preday = QdpCalendarHelper.GetNonHolidayDefore(td.StartDate.Value.AddDays(-1));
- var preSettleDate= QdpCalendarHelper.GetNonHolidayDefore(td.TradeDate.Value.AddDays(-1));
- var posiLongNotional = positions.Where(s => s.PositionType == (int)PositionTypeFlag.Long).Sum(s => s.PosiNotionalValue);
- var posiShortNotional = positions.Where(s => s.PositionType == (int)PositionTypeFlag.Short).Sum(s => s.PosiNotionalValue);
- var grossPrice = posiList.FirstOrDefault()?.PosiGrossPrice ?? 0;
- foreach (var item in interestList)
- {
- SaveEodInterestPositionCopy(null, null, td.StartDate.Value, td, item, null, false, posiLongNotional, posiShortNotional, grossPrice);
- }
- foreach (var item in posiList)
- {
- SaveCurrentEodInitalPosi(item, td, td.StartDate.Value, preday, flowEvents);
- }
- DbContext.SaveChanges();
- SaveEodSwap(td, td.StartDate.Value, preSettleDate);
- DbContext.SaveChanges();
- }
+
///
/// 获取客户互换持仓信息
///
@@ -2093,25 +2002,6 @@ namespace YLErp.Modules.SwapModule
var tradeExtends = DbContext.trade_extend.Where(x => tradeIds.Contains(x.TradeId)).ToList();
return ConvertEodPnl(eodSwaps, trades, tradeExtends);
}
- ///
- /// 获取客户互换历史持仓信息
- ///
- ///
- ///
- ///
- public List GetSwapHistoryPositions(int clientId, DateTime valueDate)
- {
- var trades = DbContext.trade.Where(x => x.TradeType == "收益互换"
- && x.ClientId == clientId
- && x.ExerciseDate <= valueDate
- && ConsTrade.TradeCompleteStatus.Contains(x.TradeStatus)
- && x.ValidState != "InValid").ToList();
- var tradeIds = trades.Select(s => s.id).ToList();
- var eodSwaps = DbContext.eod_swap_position.Where(x => tradeIds.Contains(x.SwapTradeId) && x.ValueDate == valueDate).ToList();
- var tradeExtends = DbContext.trade_extend.Where(x => tradeIds.Contains(x.TradeId)).ToList();
- return ConvertEodPnl(eodSwaps, trades, tradeExtends);
-
- }
private List ConvertEodPnl(List eodSwaps, List trades, List tradeExtends)
{
diff --git a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
index fc4c4f82..9d5f79d8 100644
--- a/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
+++ b/YLErpWeb/wwwroot/Scripts/app/swaptrade/unwindSwapTrade.js
@@ -119,7 +119,7 @@ const vue = new Vue({
this.deal.CloseNotionalValue = otcformat.trading.StockEqvNotional(parseFloat(this.deal.PosiNotionalValue));
this.deal.CloseQty = this.deal.PositionQty;
} else {
- this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.NotionalQty) * parseFloat(this.deal.ClosePercent));
+ this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.PositionQty) * parseFloat(this.deal.ClosePercent));
}
this.calcTradingFeePending();
this.getInterestList();
@@ -133,7 +133,7 @@ const vue = new Vue({
main.message("平仓数量不能超过持仓数量");
return;
}
- this.deal.ClosePercent = otcformat.fixed6(parseFloat(this.deal.CloseQty) / parseFloat(this.deal.NotionalQty));
+ this.deal.ClosePercent = otcformat.fixed6(parseFloat(this.deal.CloseQty) / parseFloat(this.deal.PositionQty));
if (parseFloat(this.deal.CloseQty) == parseFloat(this.deal.PositionQty)) {
this.deal.CloseMethod = 1;
} else {
@@ -150,7 +150,7 @@ const vue = new Vue({
this.deal.ClosePercent = this.oriClosePercent;
return;
}
- this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.NotionalQty) * parseFloat(this.deal.ClosePercent));
+ this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.PositionQty) * parseFloat(this.deal.ClosePercent));
this.deal.CloseNotionalValue = otcformat.trading.StockEqvNotional(parseFloat(this.deal.ClosePercent) * parseFloat(this.deal.NotionalValue));
if (parseFloat(this.deal.CloseNotionalValue) == parseFloat(this.deal.PosiNotionalValue)) {
this.floatPosition.CloseMethod = 1;
@@ -168,7 +168,7 @@ const vue = new Vue({
return;
}
this.deal.ClosePercent = otcformat.fixed6(parseFloat(this.deal.CloseNotionalValue) / parseFloat(this.deal.NotionalValue));
- this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.NotionalQty) * parseFloat(this.deal.ClosePercent));
+ this.deal.CloseQty = otcformat.trading.notional(parseFloat(this.deal.PositionQty) * parseFloat(this.deal.ClosePercent));
this.calcTradingFeePending();
this.getInterestList();
this.calcFloatClosePnl();
@@ -194,7 +194,7 @@ const vue = new Vue({
let longRatio = thisObj.floatPosition.PositionType == 1 ? 1 : -1;
let TradingFee = thisObj.floatPosition.TradingFee == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFee);
let TradingFeePending = thisObj.floatPosition.TradingFeePending == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFeePending);
- thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseNotionalValue * (thisObj.floatPosition.TradingAmountAvg - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
+ thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
thisObj.floatPosition.MarkClosePnl = Number(thisObj.floatPosition.MarkClosePnl.toFixed(2));
thisObj.floatPosition.MarkClosePnl = thisObj.floatPosition.MarkClosePnl + (TradingFee + TradingFeePending) * floatRatio * -1 + parseFloat(thisObj.floatPosition.DividendIn);
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);