bug修复

This commit is contained in:
吴方海
2025-04-18 17:00:25 +08:00
parent a33d5a6ff2
commit 4b9bcfb2dc
10 changed files with 42 additions and 34 deletions
@@ -667,6 +667,9 @@ namespace YLErp.BLL.Eod
bondDb.SaveChanges();
}
}
sql = $"{nameof(ClientPosition.create_time)}<'{datenow.AddSeconds(-1):yyyy-MM-dd HH:mm:ss}' or {nameof(ClientPosition.position_qty)}=0";
bondDb.BulkDelete<ClientPosition>(sql);
bondDb.SaveChanges();
#endregion
return realtimePositionList;
}
@@ -4312,11 +4312,12 @@ namespace YLErp.Modules.RiskModule
{
var um = ums.FirstOrDefault(x => x.UnderlyingCode == item.security_id);
var bondPrice = EodPriceQueryService.GetBondPrice(dealDate, item.security_id);
double lastPrice = bondPrice != null ? bondPrice.ClosePrice : (um.Price ?? 0) * Convert.ToDouble(ConsGlobal.bondPriceMultiple);
double lastPrice = bondPrice != null ? bondPrice.ClosePrice : (um?.Price ?? 0) * Convert.ToDouble(ConsGlobal.bondPriceMultiple);
var bond = new UnderlyingBond();
if (um.IsBond()&&string.IsNullOrEmpty(um.ExJson)) {
if (um!=null&& um.IsBond()&&string.IsNullOrEmpty(um.ExJson)) {
bond = JsonHelper.Deserialize<UnderlyingBond>(um.ExJson);
}
bond.IssueSize = bond.IssueSize ?? 0;
return new CheckQuotaMoitorModel
{
Qty = item.position_qty ?? 0,
@@ -4333,7 +4334,7 @@ namespace YLErp.Modules.RiskModule
Delta = (decimal)((item.side == 0 ? item.deal_full_price_avg : -item.deal_full_price_avg) * (item.position_qty ?? 0) * ConsGlobal.bondPriceMultiple),
UnderlyingId = um?.id ?? 0,
LastPrice = (decimal)lastPrice,
Circulation = (bond.IssueSize * 100000000m) ?? 0,
Circulation = (bond.IssueSize * 100000000) ?? 0,
Pnl = (decimal)((item.full_price_now - item.deal_full_price_avg) * (item.position_qty ?? 0) * ConsGlobal.bondPriceMultiple),
Current = item.Current,
};
@@ -409,7 +409,6 @@ namespace YLErp.Modules.SwapModule
_posiNotionalValue = position.InterestPrincipalFix * closePrecent;
positionClone.InterestDirection = position.InterestDirection == (int)SwapDirectionEnum. ? (int)SwapDirectionEnum. : (int)SwapDirectionEnum.;
}
var calendar = "chn";
if (!string.IsNullOrEmpty(position.FloatRateUnderlyingCode))
{
// 获取重置频率,如果为空则默认为1
@@ -418,7 +417,7 @@ namespace YLErp.Modules.SwapModule
// 计算从 td.StartDate 到 endDate 的天数
var days = (endDate - td.StartDate.Value).Days;
// 获取合适的 rateDate
DateTime rateDate = GetRateDate(position.interest_rule, td.StartDate.Value, endDate, days, interestPeriod, calendar);
DateTime rateDate = GetRateDate(position.interest_rule, td.StartDate.Value, endDate, days, interestPeriod);
// 如果不需要重置,并且上一日已有 FloatRate,则不再查找
if (preEodPosition.id != 0 && days % interestPeriod != 0)
@@ -434,7 +433,7 @@ namespace YLErp.Modules.SwapModule
position.FloatRate = Convert.ToDecimal(floatRate);
positionClone.FloatRate = position.FloatRate;
}
else
else if(!swap)
{
throw new Exception($"获取不到{position.FloatRateUnderlyingCode}在{rateDate:yyyy年MM月dd日}的价格");
}
@@ -467,16 +466,16 @@ namespace YLErp.Modules.SwapModule
/// <summary>
/// 根据给定条件获取 rateDate
/// </summary>
private DateTime GetRateDate(int? interest_rule, DateTime startDate, DateTime endDate, int days, int interestPeriod, string calendar)
private DateTime GetRateDate(int? interest_rule, DateTime startDate, DateTime endDate, int days, int interestPeriod)
{
// 判断是否达到重置周期
if (days % interestPeriod == 0)
{
return QdpCalendarHelper.GetNonHolidayDefore(endDate.AddDays(interest_rule ?? 0), calendar);
return QdpCalendarHelper.GetNonHolidayDefore(endDate.AddDays(interest_rule ?? 0));
}
// 如果不在重置周期内,使用 td.StartDate 来获取 rateDate
return QdpCalendarHelper.GetNonHolidayDefore(startDate.AddDays(interest_rule ?? 0), calendar);
return QdpCalendarHelper.GetNonHolidayDefore(startDate.AddDays(interest_rule ?? 0));
}
/// <summary>
/// 初始化利息腿信息
@@ -139,7 +139,15 @@ namespace YLErp.Modules.SwapModule
var longEventTypes = eventTyps;
longEventTypes.Add((int)SwapFlowEventTypeEnum.);
var flowEvents = new List<swap_flow_event>();
Expression<Func<swap_flow_event, bool>> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum. && longEventTypes.Contains(x.EventType)&& x.EventDate == settleDate;
Expression<Func<swap_flow_event, bool>> eventExpression = x => x.SwapTradeId == td.id && x.DataState == (int)SwapFlowDateStateEnum. && longEventTypes.Contains(x.EventType);
if (settleDate == td.TradeDate)
{
eventExpression = eventExpression.And(x => x.EventDate == settleDate);
}
else
{
eventExpression = eventExpression.And(x => x.UnwindDate == settleDate);
}
flowEvents = DbContext.swap_flow_event.Where(eventExpression).ToList();
var preDealDate = GetPreDealDate(td.id, settleDate, eventTyps);//上一次平仓/互换/自动互换处理日期
List<swap_flow_event> autoInterests = new List<swap_flow_event>();//自动互换利息腿信息
@@ -1341,15 +1349,15 @@ namespace YLErp.Modules.SwapModule
curretEod.PosiTradingFee = position.PosiTradingFee;
curretEod.UnderlyingPrice = UnderlyingCodePrice(position.UnderlyingCode, dealDate, out decimal vobp);
SetPriceInfoByFlowEvent(eod, curretEod, unwindEvents, position);
if (settleDate == td.TradeDate)
{
curretEod.UnderlyingPrice = curretEod.PosiGrossPrice;
//curretEod.TdCloseMtmPnl = 0;
//curretEod.TdCloseFee = 0;
}
curretEod.TdCloseDividend = curretEod.TdPosiDividend;
curretEod.UnderlyingMarketValue = curretEod.UnderlyingPrice * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio;
curretEod.PosiMtmPnL = (curretEod.UnderlyingPrice - curretEod.PosiGrossPrice) * curretEod.PosiQuantity * curretEod.ContractSize * shortRatio * directionRatio;
if (settleDate == td.TradeDate)
{
curretEod.PosiMtmPnL = 0;
//curretEod.TdCloseMtmPnl = 0;
//curretEod.TdCloseFee = 0;
}
curretEod.PosiDividendSum = curretEod.TdPosiDividend;
curretEod.PosiProfitSum = curretEod.PosiMtmPnL + curretEod.PosiDividendSum + curretEod.VTradingFee;
curretEod.RealizedMtmPnL = curretEod.TdCloseMtmPnl;
@@ -1208,7 +1208,7 @@ namespace YLErp.Modules.SwapModule
var unwindPercent =1- (flowQty / swapFlow.TradingQty);
var fee = (1 - unwindPercent) * swapFlow.TradingFeePending;
swapFlow.TradingQty = flowQty;
swapFlow.TradingAmount = swapFlow.TradingQty;
swapFlow.TradingAmount = swapFlow.TradingQty* swapFlow.TradingAmountAvg;
swapFlow.TradingFeePending = fee;
return NewSwapTrade(swapFlow, client, asset, underlying, floatRate, clientMarginTemplate,clearingAgency);
}
+1 -1
View File
@@ -146,7 +146,7 @@
<td>{{priceFormat(floatPosition.PosiGrossPrice)}}</td>
<td>{{priceFormat(floatPosition.TradingAmountNetAvg)}}</td>
<td>
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatMarginRateNoPercent" v-on:input="changeUnderlyingPrice" v-show="deal.StructureType != '普通收益互换'"></vue-number-input>
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatEqvNotional" v-on:input="changeUnderlyingPrice"></vue-number-input>
<input class="text-box" v-model="floatPosition.TradingAmountAvg" v-on:blur="changeUnderlyingPrice" type="number" min="0" v-else />
<a href="javascript:void(0)" v-on:click="refreshUnderlyingPrice()">
<span title="使用系统标的价格" class="glyphicon glyphicon-refresh"></span>
+1 -2
View File
@@ -197,8 +197,7 @@
</td>
<td>{{priceFormat(floatPosition.PosiGrossPrice)}}</td>
<td>
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatMarginRateNoPercent" v-on:input="changeUnderlyingPrice" v-show="deal.StructureType != '普通收益互换'"></vue-number-input>
<input class="text-box" v-model="floatPosition.TradingAmountAvg" v-on:blur="changeUnderlyingPrice" type="number" min="0" v-else />
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatEqvNotional" v-on:input="changeUnderlyingPrice"></vue-number-input>
<a href="javascript:void(0)" v-on:click="refreshUnderlyingPrice()">
<span title="使用系统标的价格" class="glyphicon glyphicon-refresh"></span>
</a>
@@ -185,9 +185,9 @@ function colModelGridEodPosition() {
align: 'center',
formatter: StockEqvNotionalFormat
}, {
name: 'eodPosition.PosiTradingFee',
name: 'eodPosition.PosiFeePending',
label: '交易费用佣金',
index: 'eodPosition.PosiTradingFee',
index: 'eodPosition.PosiFeePending',
width: 90,
align: 'center',
formatter: StockEqvNotionalFormat
@@ -104,9 +104,7 @@ const vue = new Vue({
main.post("/underlying_manager/GetUnderlyingPriceByCode",
{ code: thisObj.floatPosition.UnderlyingCode, ValueDate: thisObj.deal.ValueDate })
.done(function (res) {
if (thisObj.deal.StructureType != '普通收益互换') {
res.obj = res.obj * 1;
}
res.obj = res.obj * 100;
thisObj.floatPosition.TradingAmountAvg = otcformat.trading.umprice(res.obj);
thisObj.calcFloatClosePnl();
});
@@ -125,7 +123,7 @@ const vue = new Vue({
let floatRatio = thisObj.floatPosition.PayDirection == 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 = thisObj.deal.CloseNotionalValue * (thisObj.floatPosition.TradingAmountAvg - thisObj.initPosiNetPrice) * floatRatio;
thisObj.floatPosition.MarkClosePnl = thisObj.deal.CloseNotionalValue * (thisObj.floatPosition.TradingAmountAvg*0.01 - thisObj.initPosiNetPrice) * floatRatio;
thisObj.floatPosition.MarkClosePnl = thisObj.floatPosition.MarkClosePnl + TradingFee + TradingFeePending + parseFloat(thisObj.floatPosition.DividendIn);
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);
thisObj.calcCloseAmount();
@@ -144,12 +142,12 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue);
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * 0.01;
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.PositionQty == 0) {
thisObj.floatPosition.TradingAmountFeeAvg = 0;
} else {
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) + (TradingFee / thisObj.deal.CloseQty) * ratio;
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * 0.01 + (TradingFee / thisObj.deal.CloseQty) * ratio;
}
this.interestList.forEach(x => {
//let interestRatio = x.InterestDirection == 1 ? 1 : -1;
@@ -196,6 +194,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = 0;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * 0.01;
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交收益结算?";
@@ -181,9 +181,7 @@ const vue = new Vue({
main.post("/underlying_manager/GetUnderlyingPriceByCode",
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
.done(function (res) {
if (thisObj.deal.StructureType != '普通收益互换') {
res.obj = res.obj * 1;
}
res.obj = res.obj * 100;
thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
thisObj.calcFloatClosePnl();
});
@@ -194,7 +192,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.CloseQty * (thisObj.floatPosition.TradingAmountAvg - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg*0.01 - 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);
@@ -224,12 +222,12 @@ const vue = new Vue({
thisObj.deal.SwapRealizedPnL = pnl;
thisObj.deal.SwapMarginRebatePnl = 0;
thisObj.deal.SwapMarginAmount = 0;
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue);
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * 0.01;
thisObj.floatPosition.CloseFee = TradingFee;
if (thisObj.deal.CloseQty == 0) {
thisObj.floatPosition.TradingAmountFeeAvg = 0;
} else {
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) + (TradingFee / thisObj.deal.CloseQty) * ratio;
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * 0.01 + (TradingFee / thisObj.deal.CloseQty) * ratio;
}
this.interestList.forEach(x => {
/*let interestRatio = x.InterestDirection == 1 ? 1 : -1;*/
@@ -304,6 +302,7 @@ const vue = new Vue({
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
let floatPosition = _.cloneDeep(thisObj.floatPosition);
floatPosition.Quantity = reqObj.CloseQty;
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * 0.01;
reqObj.FlowEvents.push(floatPosition);
var postData = { unwindData: reqObj };
var msg = "确认提交平仓?";