feat(swap): 统一【期初、期末交割价格】精度处理
- 在ConsGlobal中新增SwapDeliveryPriceRound常量定义为9位小数 - 更新incomeSwapTrade.js中交割价格计算逻辑,添加getStorageDeliveryPrice方法 - 修改SwapConsumerService中TradingAmountAvg字段的精度处理 - 添加ValidateDeliveryPrices和NormalizeDeliveryPrices方法进行交割价格验证和标准化 - 在SwapEodPositionService中对PosiGrossPrice和UnderlyingPrice进行精度处理 - 更新SwapFlowEventService中TradingAmountAvg字段的精度处理 - 在SwapFlowImportService中添加交割价格精度处理 - 更新前端界面中的输入格式配置,使用新的交割价格精度设置 - 修改SwapflowList.js中交割价格精度处理逻辑 - 在SwapFlowService中添加交割价格验证和精度处理 - 更新SwapTradeAutoService中交割价格精度处理 - 修改SwapTradeService中PosiGrossPrice字段的精度处理 - 更新unwindSwapTrade.js中交割价格计算逻辑
This commit is contained in:
@@ -64,6 +64,10 @@ namespace YLErp
|
||||
|
||||
public const int PriceRound = 11;
|
||||
/// <summary>
|
||||
/// 互换期初、期末交割价四舍五入保留位数
|
||||
/// </summary>
|
||||
public const int SwapDeliveryPriceRound = 9;
|
||||
/// <summary>
|
||||
/// 金额四舍五入保留位数
|
||||
/// </summary>
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swapFlow.OptTime = result.OptTime;
|
||||
swapFlow.SettleDate = result.SettleDate;
|
||||
swapFlow.TradingAmount = result.TradingAmount;
|
||||
swapFlow.TradingAmountAvg = result.TradingAmountAvg;
|
||||
swapFlow.TradingAmountAvg = Math.Round(result.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swapFlow.TradingAmountFeeAvg = result.TradingAmountFeeAvg;
|
||||
swapFlow.TradingAmountNet = result.TradingAmountNet;
|
||||
swapFlow.TradingAmountNetFee = result.TradingAmountNetFee;
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace YLErp.Modules.SwapModule
|
||||
protected virtual long SaveSwapDeal(UnwindData unwindData, int eventType, int clientCashId, string eventResason = "", bool approve = false)
|
||||
{
|
||||
NormalizeNotionalValues(unwindData);
|
||||
NormalizeDeliveryPrices(unwindData.FlowEvents);
|
||||
return SaveSwapDealInternal(unwindData, eventType, clientCashId, eventResason, approve);
|
||||
}
|
||||
|
||||
@@ -47,6 +48,35 @@ namespace YLErp.Modules.SwapModule
|
||||
unwindData.CloseNotionalValue = Math.Round(unwindData.CloseNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
private static void ValidateDeliveryPrices(UnwindData unwindData)
|
||||
{
|
||||
if (unwindData.FlowEvents == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var item in unwindData.FlowEvents.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)))
|
||||
{
|
||||
var roundedPrice = Math.Round(item.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
if (item.TradingAmountAvg != roundedPrice)
|
||||
{
|
||||
throw new ServiceException($"期末交割价最多保留{ConsGlobal.SwapDeliveryPriceRound}位小数");
|
||||
}
|
||||
item.TradingAmountAvg = roundedPrice;
|
||||
}
|
||||
}
|
||||
|
||||
private static void NormalizeDeliveryPrices(IEnumerable<swap_flow_event> flowEvents)
|
||||
{
|
||||
if (flowEvents == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var item in flowEvents.Where(x => !string.IsNullOrEmpty(x.UnderlyingCode)))
|
||||
{
|
||||
item.TradingAmountAvg = Math.Round(item.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>保存所有变更(生产: DbContext.SaveChanges;测试: 空操作)</summary>
|
||||
protected virtual void SaveAllChanges()
|
||||
{
|
||||
@@ -1230,6 +1260,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
throw new ServiceException("未找到交易信息");
|
||||
}
|
||||
ValidateDeliveryPrices(unwindData);
|
||||
NormalizeNotionalValues(unwindData);
|
||||
//CheckLastEod(unwindData.ValueDate, td.StartDate.Value, unwindData.SwapTradeId); //去掉平仓收盘限制
|
||||
ValidateFrontendPnL(unwindData, isIncome: false); // 只读校验告警,不阻断交易
|
||||
@@ -1279,6 +1310,7 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <param name="unwindPriceFee"></param>
|
||||
public void AuotoSwapUnwind(int tradeid, decimal unwindPrice, decimal unwindPriceFee, decimal unwindNetFee, decimal unwindNet, DateTime valueDate, decimal unwindQty, decimal closeFee)
|
||||
{
|
||||
unwindPrice = Math.Round(unwindPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
unwindPriceFee = decimal.Parse(unwindPriceFee.ToString("F10"));
|
||||
var td = DbContext.trade.Find(tradeid);
|
||||
var positions = DbContext.swap_position.Where(x => x.SwapTradeId == td.id && !x.Invalid);
|
||||
@@ -1710,6 +1742,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
throw new ServiceException("未找到交易信息");
|
||||
}
|
||||
ValidateDeliveryPrices(unwindData);
|
||||
NormalizeIncomeUnwindDate(unwindData);
|
||||
ValidateIncomeValueDate(unwindData, td);
|
||||
//CheckLastEod(unwindData.ValueDate, td.StartDate.Value, unwindData.SwapTradeId); //去掉平仓收盘限制
|
||||
@@ -1750,12 +1783,14 @@ namespace YLErp.Modules.SwapModule
|
||||
throw new Exception("该笔交易状态为平仓待复核,未找到相关记录,请检查该笔交易是否有效");
|
||||
}
|
||||
swapEvent.unwindData = JsonConvert.DeserializeObject<UnwindData>(swapEvent.EventData);
|
||||
NormalizeDeliveryPrices(swapEvent.unwindData.FlowEvents);
|
||||
if (eventType == (int)SwapEventTypeEnum.互换)
|
||||
{
|
||||
NormalizeIncomeUnwindDate(swapEvent.unwindData);
|
||||
ValidateIncomeValueDate(swapEvent.unwindData, td);
|
||||
}
|
||||
var flowList = FindFlowEventsByEventId(swapEvent.id);
|
||||
NormalizeDeliveryPrices(flowList);
|
||||
string action = eventType == (int)SwapEventTypeEnum.互换 ? ClientCashInCashOut.系统操作_互换 : ClientCashInCashOut.系统操作_平仓费;
|
||||
int clientCashId = AddClientCash(td, Convert.ToDouble(-swapEvent.unwindData.SwapRealizedPnL), action, swapEvent.unwindData.ValueDate);
|
||||
if (swapEvent.unwindData.SwapMarginAmount != 0)
|
||||
@@ -1798,6 +1833,7 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
throw new ServiceException("未找到交易信息");
|
||||
}
|
||||
ValidateDeliveryPrices(unwindData);
|
||||
if (eventType == (int)SwapEventTypeEnum.互换)
|
||||
{
|
||||
NormalizeIncomeUnwindDate(unwindData);
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace YLErp.Modules.SwapModule
|
||||
/// <summary>持久化 eod 持仓记录(生产: DbContext.Add;测试: 收集到列表)</summary>
|
||||
protected virtual void PersistEodSwapPosition(eod_swap_position position)
|
||||
{
|
||||
position.PosiGrossPrice = Math.Round(position.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
position.UnderlyingPrice = Math.Round(position.UnderlyingPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
position.PosiNotionalValue = Math.Round(position.PosiNotionalValue, ConsGlobal.MoneyRound, MidpointRounding.AwayFromZero);
|
||||
if (position.id == 0)
|
||||
{
|
||||
@@ -181,10 +183,10 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
var normalizedPrice = BondPriceConverter.ToStorage(price);
|
||||
Log.Error($"互换债券日终价格按展示态返回,已转换为存储态: UnderlyingCode={code}, ValueDate={settleDate:yyyy-MM-dd}, PosiGrossPrice={posiGrossPrice}, SourcePrice={price}, NormalizedPrice={normalizedPrice}");
|
||||
return normalizedPrice;
|
||||
return Math.Round(normalizedPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
return price;
|
||||
return Math.Round(price, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
/// <summary>获取标的缓存数据(生产: DataCacheProvider;测试: 返回内存对象)</summary>
|
||||
@@ -1473,7 +1475,7 @@ namespace YLErp.Modules.SwapModule
|
||||
newEodPayPosition.ContractSize = eventFlow.ContractSize;
|
||||
newEodPayPosition.CountRatio = eventFlow.CountRatio;
|
||||
newEodPayPosition.PosiNetPrice = netPrice;
|
||||
newEodPayPosition.PosiGrossPrice = grossPrice;
|
||||
newEodPayPosition.PosiGrossPrice = Math.Round(grossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
newEodPayPosition.PosiNetFeePrice = netFeePrice;
|
||||
newEodPayPosition.PosiNetNoFeePrice = netNoFeePrice;
|
||||
newEodPayPosition.PosiQuantity = payQty;
|
||||
@@ -1772,7 +1774,7 @@ namespace YLErp.Modules.SwapModule
|
||||
posiQty = 0;
|
||||
}
|
||||
curretEod.PosiGrossPrice = (eod.PosiGrossPrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountAvg)) / (eod.PosiQuantity + openQty);
|
||||
curretEod.PosiGrossPrice = Math.Round(curretEod.PosiGrossPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
curretEod.PosiGrossPrice = Math.Round(curretEod.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
curretEod.PosiNetPrice = (eod.PosiNetPrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountFeeAvg)) / (eod.PosiQuantity + openQty);
|
||||
curretEod.PosiNetPrice = Math.Round(curretEod.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
curretEod.PosiNetNoFeePrice = (eod.PosiNetNoFeePrice * eod.PosiQuantity + openFlowEvents.Sum(a => a.Quantity * a.TradingAmountNetAvg)) / (eod.PosiQuantity + openQty);
|
||||
@@ -1898,14 +1900,14 @@ namespace YLErp.Modules.SwapModule
|
||||
}
|
||||
if (data.IsBond())
|
||||
{
|
||||
return BondPrice(data, settleDate, out vobp);
|
||||
return Math.Round(BondPrice(data, settleDate, out vobp), ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
var price = data.Price ?? 0;
|
||||
if (EodPriceQueryService.TryGetEodPrice(settleDate, code, out var eodPrice))
|
||||
{
|
||||
price = eodPrice.GetPrice(SettlementTypeEnum.ClosePrice);
|
||||
}
|
||||
return Convert.ToDecimal(price);
|
||||
return Math.Round(Convert.ToDecimal(price), ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取债券收盘价格
|
||||
|
||||
@@ -61,6 +61,10 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
foreach (var evt in events)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(evt.UnderlyingCode))
|
||||
{
|
||||
evt.TradingAmountAvg = Math.Round(evt.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
DbContext.swap_flow_event.Add(evt);
|
||||
}
|
||||
DbContext.SaveChanges();
|
||||
@@ -321,7 +325,7 @@ namespace YLErp.Modules.SwapModule
|
||||
DataState = 1,
|
||||
EventDate = flow_merge.OccurTime,
|
||||
UnwindDate = QdpCalendarHelper.GetNonHoliday(flow_merge.OccurTime.AddDays(1)),
|
||||
TradingAmountAvg = TradingAmountAvg,
|
||||
TradingAmountAvg = Math.Round(TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
TradingAmountFeeAvg = TradingAmountFeeAvg,
|
||||
TradingAmountNetFeeAvg = TradingAmountNetFeeAvg,
|
||||
TradingAmountNetAvg = flow_merge.TradingAmountNetAvg,
|
||||
@@ -375,7 +379,7 @@ namespace YLErp.Modules.SwapModule
|
||||
DataState = 1,
|
||||
EventDate = flow_merge.OccurTime,
|
||||
UnwindDate = QdpCalendarHelper.GetNonHoliday(flow_merge.OccurTime.AddDays(1)),
|
||||
TradingAmountAvg = flow_merge.TradingAmountAvg,
|
||||
TradingAmountAvg = Math.Round(flow_merge.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
TradingAmountFeeAvg = flow_merge.TradingAmountFeeAvg,
|
||||
TradingFeePending = flow_merge.TradingFeePending,
|
||||
ClientId = flow_merge.ClientId
|
||||
@@ -409,7 +413,7 @@ namespace YLErp.Modules.SwapModule
|
||||
DataState = (int)SwapFlowDateStateEnum.完成,
|
||||
EventDate = td.TradeDate.Value,
|
||||
UnwindDate = td.StartDate.Value,
|
||||
TradingAmountAvg = position.PosiGrossPrice,
|
||||
TradingAmountAvg = Math.Round(position.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
TradingAmountFeeAvg = position.PosiNetPrice,
|
||||
TradingAmountNetFeeAvg = position.PosiNetFeePrice,
|
||||
TradingAmountNetAvg = position.PosiNetNoFeePrice,
|
||||
@@ -462,7 +466,7 @@ namespace YLErp.Modules.SwapModule
|
||||
DataState = 100,
|
||||
EventDate = td.TradeDate.Value,
|
||||
UnwindDate = QdpCalendarHelper.GetNonHoliday(td.TradeDate.Value.AddDays(1)),
|
||||
TradingAmountAvg = flowMerge.TradingAmountAvg,
|
||||
TradingAmountAvg = Math.Round(flowMerge.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
TradingAmountFeeAvg = flowMerge.TradingAmountFeeAvg,
|
||||
TradingAmountNetFeeAvg = flowMerge.TradingAmountNetFeeAvg,
|
||||
TradingAmountNetAvg = flowMerge.TradingAmountNetAvg,
|
||||
|
||||
@@ -129,6 +129,7 @@ namespace YLErp.Modules.SwapModule
|
||||
if (swap_flow.TradingAmountNetFee.HasValue)
|
||||
swap_flow.TradingAmountNetFee = BondPriceConverter.ToStorage(swap_flow.TradingAmountNetFee.Value);
|
||||
}
|
||||
swap_flow.TradingAmountAvg = Math.Round(swap_flow.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
if (!string.IsNullOrEmpty(clientName))
|
||||
{
|
||||
var client = DataCacheProvider.GetClientDataSource().AsQueryable(x=>x.Name== clientName).FirstOrDefault();
|
||||
|
||||
@@ -473,7 +473,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swap_Flow.UnderlyingCode = req.UnderlyingCode;
|
||||
swap_Flow.BsType = req.BsType;
|
||||
swap_Flow.ContractSize = req.ContractSize;
|
||||
swap_Flow.TradingAmountAvg = req.TradingAmountAvg;
|
||||
swap_Flow.TradingAmountAvg = Math.Round(req.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_Flow.TradingAmountFeeAvg = TradeFeeHelper.CalcPriceWithFee(req.TradingFee,req.TradingAmountAvg,req.TradingQty,req.BsType);
|
||||
swap_Flow.ClientId = req.ClientId;
|
||||
swap_Flow.ytm = req.ytm;
|
||||
@@ -540,7 +540,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swap_Flow.BsType = req.BsType;
|
||||
swap_Flow.DataState = (int)SwapFlowDateStateEnum.等待完成;
|
||||
swap_Flow.ContractSize = req.ContractSize;
|
||||
swap_Flow.TradingAmountAvg = req.TradingAmountAvg;
|
||||
swap_Flow.TradingAmountAvg = Math.Round(req.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_Flow.TradingAmountFeeAvg = req.TradingAmountFeeAvg;
|
||||
UpdateDbOption(swap_Flow);
|
||||
if (req.id == 0)
|
||||
@@ -695,7 +695,7 @@ namespace YLErp.Modules.SwapModule
|
||||
TradingFee = gourpItem.Sum(s => s.TradingFee),
|
||||
DataState = (int)SwapFlowDateStateEnum.等待完成,
|
||||
TradingAmountFeeAvg = gourpItem.Average(s => s.TradingAmountFeeAvg),
|
||||
TradingAmountAvg = gourpItem.Average(s => s.TradingAmountAvg),
|
||||
TradingAmountAvg = Math.Round(gourpItem.Average(s => s.TradingAmountAvg), ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
ContractSize = swapflow.ContractSize
|
||||
};
|
||||
UpdateDbOption(swap_flow_summary);
|
||||
@@ -747,6 +747,11 @@ namespace YLErp.Modules.SwapModule
|
||||
private void CheckValid(swap_flow req)
|
||||
{
|
||||
CheckRequired(req);
|
||||
var roundedPrice = Math.Round(req.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
if (req.TradingAmountAvg != roundedPrice)
|
||||
{
|
||||
throw new ServiceException($"成交全价最多保留{ConsGlobal.SwapDeliveryPriceRound}位小数");
|
||||
}
|
||||
var underlying = DataCacheProvider.GetUnderlyingDataSource().GetData(req.UnderlyingCode);
|
||||
if (underlying == null)
|
||||
{
|
||||
@@ -764,6 +769,7 @@ namespace YLErp.Modules.SwapModule
|
||||
// 数量×100(万手→手),与价格维度无关,保留常量
|
||||
req.TradingQty *= ConsGlobal.bondShowPriceMultiple;
|
||||
}
|
||||
req.TradingAmountAvg = Math.Round(req.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swapFlow.DataState = (int)SwapFlowDateStateEnum.等待完成;
|
||||
}
|
||||
// 债券报价(×100)转入库小数(×0.01),统一走 BondPriceConverter
|
||||
swapFlow.TradingAmountAvg = BondPriceConverter.ToStorage(item.deal_full_price ?? 0);
|
||||
swapFlow.TradingAmountAvg = Math.Round(BondPriceConverter.ToStorage(item.deal_full_price ?? 0), ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swapFlow.TradingAmountFeeAvg = BondPriceConverter.ToStorage(item.deal_full_price_include_fee ?? 0);
|
||||
swapFlow.TradingAmount = swapFlow.TradingQty * swapFlow.ContractSize * swapFlow.TradingAmountAvg;
|
||||
swapFlow.ClientId = Convert.ToInt32(item.client_id ?? 0);
|
||||
@@ -451,7 +451,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swap_flow_summary.FirstFlowTime = swapflow.OptTime;
|
||||
swap_flow_summary.SettleDate = gourpItem.Max(s => s.SettleDate);
|
||||
swap_flow_summary.TradingAmountAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountAvg * s.TradingQty) / swap_flow_summary.TradingQty;
|
||||
swap_flow_summary.TradingAmountAvg = Math.Round(swap_flow_summary.TradingAmountAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_flow_summary.TradingAmountAvg = Math.Round(swap_flow_summary.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
|
||||
swap_flow_summary.TradingAmountFeeAvg = Math.Round(swap_flow_summary.TradingAmountFeeAvg, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_flow_summary.TradingAmountNetAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.TradingAmountNet * s.TradingQty) / swap_flow_summary.TradingQty;
|
||||
@@ -508,6 +508,7 @@ namespace YLErp.Modules.SwapModule
|
||||
swap_flow_summary.SettleDate = gourpItem.Max(s => s.SettleDate);
|
||||
swap_flow_summary.TradingAmount = swap_flow_summary.TradingQty * swap_flow_summary.ContractSize;
|
||||
swap_flow_summary.TradingAmountAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.FullPrice * s.TradingQty) / swap_flow_summary.TradingQty;
|
||||
swap_flow_summary.TradingAmountAvg = Math.Round(swap_flow_summary.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
swap_flow_summary.TradingAmountFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountAvg : swap_flow_summary.TradingAmountAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
|
||||
swap_flow_summary.TradingAmountNetAvg = swap_flow_summary.TradingQty == 0 ? 0 : gourpItem.Sum(s => s.NetPrice * s.TradingQty) / swap_flow_summary.TradingQty;
|
||||
swap_flow_summary.TradingAmountNetFeeAvg = swap_flow_summary.TradingQty == 0 ? swap_flow_summary.TradingAmountNetAvg : swap_flow_summary.TradingAmountNetAvg + swap_flow_summary.TradingFeePending * tradeSide / swap_flow_summary.TradingQty;
|
||||
@@ -1081,7 +1082,7 @@ namespace YLErp.Modules.SwapModule
|
||||
var ratio = flowMergeClone.BsType == 1 ? 1 : -1;
|
||||
var oriRatio = flowMergeClone.BsType == 1 ? -1 : 1;
|
||||
flowMergeClone.TradingFeePending = flowMergeClone.TradingQty / origin.TradingQty * origin.TradingFeePending;
|
||||
flowMergeClone.TradingAmountAvg = origin.TradingAmountAvg + oriRatio * origin.TradingFeePending * 2 / origin.TradingQty;
|
||||
flowMergeClone.TradingAmountAvg = Math.Round(origin.TradingAmountAvg + oriRatio * origin.TradingFeePending * 2 / origin.TradingQty, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
flowMergeClone.TradingAmountNetAvg = origin.TradingAmountNetAvg + oriRatio * origin.TradingFeePending * 2 / origin.TradingQty;
|
||||
|
||||
flowMergeClone.TradingAmountFeeAvg = flowMergeClone.TradingAmountAvg + ratio * flowMergeClone.TradingFeePending / flowMergeClone.TradingQty;
|
||||
|
||||
@@ -51,6 +51,17 @@ namespace YLErp.Modules.SwapModule
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static decimal ValidateDeliveryPrice(decimal price, string fieldName)
|
||||
{
|
||||
var roundedPrice = Math.Round(price, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
if (price != roundedPrice)
|
||||
{
|
||||
throw new ServiceException($"{fieldName}最多保留{ConsGlobal.SwapDeliveryPriceRound}位小数");
|
||||
}
|
||||
return roundedPrice;
|
||||
}
|
||||
|
||||
#region 互换交易保存
|
||||
/// <summary>
|
||||
/// 新版收益互换预付金校验
|
||||
@@ -370,7 +381,7 @@ namespace YLErp.Modules.SwapModule
|
||||
CountRatio = underlying.CountRatio,
|
||||
ContractSize = Convert.ToDecimal(underlying.ContractSize),
|
||||
PosiNetPrice = flowMerge.TradingAmountFeeAvgAbs,
|
||||
PosiGrossPrice = flowMerge.TradingAmountAvg,
|
||||
PosiGrossPrice = Math.Round(flowMerge.TradingAmountAvg, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero),
|
||||
PosiNetFeePrice = flowMerge.TradingAmountNetFeeAvg ?? 0,
|
||||
PosiNetNoFeePrice = flowMerge.TradingAmountNetAvg ?? 0,
|
||||
PosiQuantity = flowMerge.TradingQtyAbs,
|
||||
@@ -1350,8 +1361,11 @@ namespace YLErp.Modules.SwapModule
|
||||
position.UnderlyingCode = swap.UnderlyingCode;
|
||||
position.UnderlyingInstrumentType = swap.UnderlyingInstrumentType;
|
||||
position.PosiDirection = swap.PosiDirection;
|
||||
position.PosiGrossPrice = swap.PosiGrossPrice;
|
||||
position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
|
||||
// position.PosiGrossPrice = string.IsNullOrEmpty(swap.UnderlyingCode)
|
||||
// ? Math.Round(swap.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero)
|
||||
// : ValidateDeliveryPrice(swap.PosiGrossPrice, "期初交割价");
|
||||
position.PosiGrossPrice = Math.Round(swap.PosiGrossPrice, ConsGlobal.SwapDeliveryPriceRound, MidpointRounding.AwayFromZero);
|
||||
position.PosiNetPrice = swap.PosiQuantity == 0 ? 0 : (position.PosiGrossPrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
|
||||
position.PosiNetPrice = Math.Round(position.PosiNetPrice, ConsGlobal.PriceRound, MidpointRounding.AwayFromZero);
|
||||
position.PosiNetNoFeePrice = swap.PosiNetNoFeePrice;
|
||||
position.PosiNetFeePrice = swap.PosiQuantity == 0 ? 0 : (swap.PosiNetNoFeePrice + (position.PosiTradingFeePending / swap.PosiQuantity) * ratio);
|
||||
|
||||
@@ -163,7 +163,7 @@
|
||||
<!-- 期初标的交割净价: TradingAmountNetAvg 字段名为"成交净价(期末语义)",但此处后端 InitIncome 实际装入的是期初净价(position.PosiNetNoFeePrice),值是期初值 -->
|
||||
<td v-if="deal.StructureType!='普通收益互换'">{{priceFormat(floatPosition.TradingAmountNetAvg > 0 ? floatPosition.TradingAmountNetAvg : floatPosition.PosiNetPrice)}}</td>
|
||||
<td>
|
||||
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatEqvNotional" v-on:input="changeUnderlyingPrice" style="width:107px;"></vue-number-input>
|
||||
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatSwapDeliveryPrice" v-on:input="changeUnderlyingPrice" style="width:107px;"></vue-number-input>
|
||||
<a href="javascript:void(0)" v-on:click="refreshUnderlyingPrice()">
|
||||
<span title="使用系统标的价格" class="glyphicon glyphicon-refresh"></span>
|
||||
</a>
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
</td>
|
||||
<td>{{priceFormat(floatPosition.PosiGrossPrice)}}</td>
|
||||
<td>
|
||||
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatEqvNotional" v-on:input="changeUnderlyingPrice" style="width:107px;"></vue-number-input>
|
||||
<vue-number-input v-model="floatPosition.TradingAmountAvg" v-bind:format="inputFormatSwapDeliveryPrice" v-on:input="changeUnderlyingPrice" style="width:107px;"></vue-number-input>
|
||||
<a href="javascript:void(0)" v-on:click="refreshUnderlyingPrice()">
|
||||
<span title="使用系统标的价格" class="glyphicon glyphicon-refresh"></span>
|
||||
</a>
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="formlabel ">成交均价</label>
|
||||
<vue-number-input v-model="swapflow.TradingAmountAvg" v-bind:format="inputFormatTradePrice" v-on:input="changeSpotPrice()"></vue-number-input>
|
||||
<vue-number-input v-model="swapflow.TradingAmountAvg" v-bind:format="inputFormatSwapDeliveryPrice" v-on:input="changeSpotPrice()"></vue-number-input>
|
||||
</div>
|
||||
@*<div class="form-group">
|
||||
<label class="formlabel ">成交均价含费</label>
|
||||
|
||||
@@ -452,7 +452,7 @@
|
||||
</a>
|
||||
</td>
|
||||
<td v-if="trade.StructureType!='普通收益互换'">
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatMarginRateNoPercent" v-on:input="changeSpotPrice(item)"></vue-number-input>
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatSwapBondDeliveryPrice" v-on:input="changeSpotPrice(item)"></vue-number-input>
|
||||
</td>
|
||||
<td v-if="trade.StructureType!='普通收益互换'">
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'PosiNetNoFeePrice')" v-model="item.PosiNetNoFeePrice" v-bind:format="inputFormatMarginRateNoPercent"></vue-number-input>
|
||||
@@ -461,7 +461,7 @@
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'InitYtm')" v-model="item.InitYtm" v-bind:format="inputFormatMarginRateNoPercent"></vue-number-input>
|
||||
</td>
|
||||
<td v-if="trade.StructureType=='普通收益互换'">
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'normalPosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatTradeSinglePrice" v-on:input="changeSpotPrice(item)"></vue-number-input>
|
||||
<vue-number-input :key="getPosiPriceFormatKey(item,'normalPosiGrossPrice')" v-model="item.PosiGrossPrice" v-bind:format="inputFormatSwapDeliveryPrice" v-on:input="changeSpotPrice(item)"></vue-number-input>
|
||||
</td>
|
||||
<td>
|
||||
<vue-number-input v-model="item.PosiQuantity" v-on:input="changeQuantity(item)" v-bind:format="inputFormatTradeAmount"></vue-number-input>{{item.underlying!=null?item.underlying.QuoteUnitString:''}}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//window.otcformat.options.disableGrouping = true;
|
||||
const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '' });
|
||||
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '' });
|
||||
const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.notional.precision, append: '' });
|
||||
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
|
||||
var clients = ylotc.clients;
|
||||
@@ -1198,6 +1199,7 @@ var vue = new Vue({
|
||||
},
|
||||
postSwapflow() {
|
||||
var thisObj = this;
|
||||
thisObj.swapflow.TradingAmountAvg = _.round(Number(thisObj.swapflow.TradingAmountAvg), 9);
|
||||
main.post("/swaptrade2/SaveSwapflow", { req: thisObj.swapflow, step: thisObj.step }).done(function (resp) {
|
||||
if (resp.success) {
|
||||
getList();
|
||||
|
||||
@@ -8,6 +8,7 @@ const inputFormatEqvNotional = Object.freeze({ precision: otcformat.trading.Stoc
|
||||
const inputFormatDividend = Object.freeze({ precision: 2, append: '', negative: true });
|
||||
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
|
||||
const inputFormatMarginRateNoPercent = Object.freeze({ precision: otcformat.trading.umpriceP.precision, append: '', percent: true });
|
||||
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, append: '', negative: true });
|
||||
let ValueDate = model.ValueDate;
|
||||
let MaxIncomeValueDate = model.MaxIncomeValueDate ? model.MaxIncomeValueDate.substr(0, 10) : ValueDate;
|
||||
|
||||
@@ -77,6 +78,9 @@ const vue = new Vue({
|
||||
getPriceScale() {
|
||||
return SwapCalc.getPriceScale(this.multiplier);
|
||||
},
|
||||
getStorageDeliveryPrice() {
|
||||
return _.round(Number(this.floatPosition.TradingAmountAvg) * this.getPriceScale(), 9);
|
||||
},
|
||||
initDeal() {
|
||||
var positions = model.FlowEvents.filter((item) => {
|
||||
return item.UnderlyingCode;
|
||||
@@ -161,7 +165,7 @@ const vue = new Vue({
|
||||
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
|
||||
.done(function (res) {
|
||||
res.obj = res.obj * thisObj.multiplier;
|
||||
thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
|
||||
thisObj.floatPosition.TradingAmountAvg = _.round(Number(res.obj), 9);
|
||||
thisObj.calcFloatClosePnl();
|
||||
});
|
||||
},
|
||||
@@ -180,11 +184,11 @@ const vue = new Vue({
|
||||
let TradingFee = thisObj.floatPosition.TradingFee == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFee);
|
||||
let TradingFeePending = thisObj.floatPosition.TradingFeePending == "" ? 0 : parseFloat(thisObj.floatPosition.TradingFeePending);
|
||||
let DividendIn = thisObj.floatPosition.DividendIn == "" ? 0 : parseFloat(thisObj.floatPosition.DividendIn ?? 0);
|
||||
let scale = thisObj.getPriceScale();
|
||||
let deliveryPrice = thisObj.getStorageDeliveryPrice();
|
||||
// 债券全价是单位价格,价差盈亏应按持仓数量×合约乘数计算;
|
||||
// CloseNotionalValue 是期初全价折算后的名义本金,直接乘价差会重复包含期初价格。
|
||||
let positionAmount = parseFloat(thisObj.floatPosition.Quantity) * parseFloat(thisObj.floatPosition.ContractSize || 1);
|
||||
thisObj.floatPosition.MarkClosePnl = positionAmount * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiGrossPrice) * floatRatio;
|
||||
thisObj.floatPosition.MarkClosePnl = positionAmount * (deliveryPrice - thisObj.initPosiGrossPrice) * floatRatio;
|
||||
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);//MarkClosePnl 纯盯市不要计算交易费用和分红
|
||||
// 守卫: 浮动盈亏合计必须保留 2 位小数 → 对应历史 bug 3c5f25a5(原代码缺精度保留)
|
||||
// 数值由 swapCalc.calcFloatPnlSum 计算, 此处 .toFixed(2) 仅保留字符串类型以兼容下游
|
||||
@@ -205,13 +209,13 @@ const vue = new Vue({
|
||||
thisObj.deal.SwapRealizedPnL = pnl;
|
||||
thisObj.deal.SwapMarginRebatePnl = 0;
|
||||
thisObj.deal.SwapMarginAmount = 0;
|
||||
let scale = thisObj.getPriceScale();
|
||||
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseNotionalValue) * scale;
|
||||
let deliveryPrice = thisObj.getStorageDeliveryPrice();
|
||||
thisObj.floatPosition.TradingAmount = deliveryPrice * parseFloat(thisObj.deal.CloseNotionalValue);
|
||||
thisObj.floatPosition.CloseFee = TradingFee;
|
||||
if (thisObj.deal.CloseQty > 0) {
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice + (TradingFee / thisObj.deal.CloseQty) * floatRatio;
|
||||
} else {
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale;
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice;
|
||||
}
|
||||
this.interestList.forEach(x => {
|
||||
//let interestRatio = x.InterestDirection == 1 ? 1 : -1;
|
||||
@@ -277,7 +281,7 @@ const vue = new Vue({
|
||||
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
|
||||
let floatPosition = _.cloneDeep(thisObj.floatPosition);
|
||||
floatPosition.Quantity = 0;
|
||||
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
|
||||
floatPosition.TradingAmountAvg = thisObj.getStorageDeliveryPrice();
|
||||
reqObj.FlowEvents.push(floatPosition);
|
||||
var postData = { unwindData: reqObj };
|
||||
var msg = "确认提交收益结算?";
|
||||
|
||||
@@ -14,6 +14,8 @@ const inputFormatTradePrice = Object.freeze({ precision: otcformat.trading.trade
|
||||
const inputFormatTradeSinglePrice = Object.freeze({ precision: otcformat.trading.tradeSinglePrice.precision, negative: true, append: '', percent: false });
|
||||
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
|
||||
const inputFormatMarginRateNoPercent = Object.freeze({ precision: otcformat.trading.umpriceP.precision, append: '', percent:true });
|
||||
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '', percent: false });
|
||||
const inputFormatSwapBondDeliveryPrice = Object.freeze({ precision: 9, negative: true, append: '', percent: true });
|
||||
|
||||
const consUnderlyingFlagBase = (function () {
|
||||
let unSelFlag = tradeHelper.UnderlyingSelectFlag;
|
||||
@@ -277,7 +279,8 @@ const vue = new Vue({
|
||||
//计算数量
|
||||
if (this.paySwapList.length > 0) {
|
||||
var item = this.paySwapList[0];
|
||||
var notional = item.PosiGrossPrice * item.ContractSize;
|
||||
var deliveryPrice = _.round(Number(item.PosiGrossPrice), 9);
|
||||
var notional = deliveryPrice * item.ContractSize;
|
||||
item.PosiQuantity = notional == 0 ? 0 : _.round(this.trade.StockEqvNotional / notional, page.otcFormatConfig.StockEqvNotional.precision);
|
||||
this.calcNotional();
|
||||
}
|
||||
@@ -358,7 +361,8 @@ const vue = new Vue({
|
||||
}
|
||||
var national = payItem.PosiQuantity * payItem.ContractSize;
|
||||
// 守卫: 名义本金必须 round 到 2 位 → 对应历史 bug f873239a(缺 _.round); 外置到 swapCalc.calcStockEqvNotional
|
||||
var stockEqvNotional = SwapCalc.calcStockEqvNotional(payItem.PosiGrossPrice, national);//名义本金=期初价格*数量*乘数
|
||||
var deliveryPrice = _.round(Number(payItem.PosiGrossPrice), 9);
|
||||
var stockEqvNotional = SwapCalc.calcStockEqvNotional(deliveryPrice, national);//名义本金=期初价格*数量*乘数
|
||||
this.trade.StockEqvNotional = otcformat.trading.stockEqvNotional(stockEqvNotional);
|
||||
payItem.PosiNotionalValue = this.trade.StockEqvNotional;
|
||||
}
|
||||
@@ -502,6 +506,7 @@ const vue = new Vue({
|
||||
errorcount++;
|
||||
return false;
|
||||
}
|
||||
x.PosiGrossPrice = _.round(Number(x.PosiGrossPrice), 9);
|
||||
thisObj.trade.swap_positions.push(x);
|
||||
});
|
||||
} else {
|
||||
@@ -628,7 +633,7 @@ const vue = new Vue({
|
||||
main.post("/pricing/AjaxGetUnderlyingPrice", { underlyingCode: underlyingCode, tradeDate: StartDate })
|
||||
.done(function (resp) {
|
||||
item.PosiNetNoFeePrice = otcformat.trading.umprice(resp.obj.netPrice);
|
||||
item.PosiGrossPrice = otcformat.trading.umprice(resp.obj.price);
|
||||
item.PosiGrossPrice = _.round(Number(resp.obj.price), 9);
|
||||
thisObj.calcNotional();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -7,6 +7,7 @@ const inputFormatTradeAmount = Object.freeze({ precision: otcformat.trading.noti
|
||||
const inputFormatEqvNotional = Object.freeze({ precision: otcformat.trading.StockEqvNotional.precision, append: '', negative: true });
|
||||
const inputFormatMarginRate = Object.freeze({ precision: otcformat.trading.marginRateP.precision, append: '%' });
|
||||
const inputFormatMarginRateNoPercent = Object.freeze({ precision: otcformat.trading.umpriceP.precision, append: '', percent: true });
|
||||
const inputFormatSwapDeliveryPrice = Object.freeze({ precision: 9, append: '', negative: true });
|
||||
let ValueDate = model.ValueDate;
|
||||
const vue = new Vue({
|
||||
el: '#vueDiv',
|
||||
@@ -40,6 +41,9 @@ const vue = new Vue({
|
||||
getPriceScale() {
|
||||
return this.multiplier == 100 ? 0.01 : 1;
|
||||
},
|
||||
getStorageDeliveryPrice() {
|
||||
return _.round(Number(this.floatPosition.TradingAmountAvg) * this.getPriceScale(), 9);
|
||||
},
|
||||
initDeal() {
|
||||
var positions = model.FlowEvents.filter((item) => {
|
||||
return item.UnderlyingCode;
|
||||
@@ -84,7 +88,7 @@ const vue = new Vue({
|
||||
this.deal.SwapCloseAmount = otcformat.trading.StockEqvNotional(this.deal.SwapCloseAmount);
|
||||
//this.floatPosition.PosiNetPrice = otcformat.trading.tradeSinglePrice(this.floatPosition.PosiNetPrice);
|
||||
//this.floatPosition.PosiGrossPrice = otcformat.trading.tradeSinglePrice(this.floatPosition.PosiGrossPrice);
|
||||
this.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(this.floatPosition.TradingAmountAvg);
|
||||
this.floatPosition.TradingAmountAvg = _.round(Number(this.floatPosition.TradingAmountAvg), 9);
|
||||
this.floatPosition.TradingFee = otcformat.trading.StockEqvNotional(this.floatPosition.TradingFee);
|
||||
this.floatPosition.TradingFeePending = otcformat.trading.StockEqvNotional(this.floatPosition.TradingFeePending);
|
||||
this.floatPosition.DividendIn = parseFloat(this.floatPosition.DividendIn).toFixed(2);
|
||||
@@ -212,7 +216,7 @@ const vue = new Vue({
|
||||
{ code: thisObj.floatPosition.UnderlyingCode, valuedate: thisObj.deal.ValueDate })
|
||||
.done(function (res) {
|
||||
res.obj = res.obj * thisObj.multiplier;
|
||||
thisObj.floatPosition.TradingAmountAvg = otcformat.trading.tradeSinglePrice(res.obj);
|
||||
thisObj.floatPosition.TradingAmountAvg = _.round(Number(res.obj), 9);
|
||||
thisObj.calcFloatClosePnl();
|
||||
});
|
||||
},
|
||||
@@ -222,8 +226,8 @@ 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);
|
||||
let scale = thisObj.getPriceScale();
|
||||
thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (thisObj.floatPosition.TradingAmountAvg * scale - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
|
||||
let deliveryPrice = thisObj.getStorageDeliveryPrice();
|
||||
thisObj.floatPosition.MarkClosePnl = Math.round(thisObj.deal.CloseQty * (deliveryPrice - thisObj.initPosiNetPrice) * floatRatio * longRatio * 10000) / 10000;
|
||||
thisObj.floatPosition.MarkClosePnl = Number(thisObj.floatPosition.MarkClosePnl.toFixed(2));//MarkClosePnl 纯盯市不要计算交易费用和分红
|
||||
thisObj.floatPosition.MarkClosePnl = otcformat.trading.StockEqvNotional(thisObj.floatPosition.MarkClosePnl);
|
||||
thisObj.floatPosition.FloatPnlSum = (parseFloat(thisObj.floatPosition.MarkClosePnl) + TradingFee + TradingFeePending + parseFloat(thisObj.floatPosition.DividendIn)).toFixed(2);
|
||||
@@ -253,13 +257,13 @@ const vue = new Vue({
|
||||
thisObj.deal.SwapRealizedPnL = pnl;
|
||||
thisObj.deal.SwapMarginRebatePnl = 0;
|
||||
thisObj.deal.SwapMarginAmount = 0;
|
||||
let scale = thisObj.getPriceScale();
|
||||
thisObj.floatPosition.TradingAmount = parseFloat(thisObj.floatPosition.TradingAmountAvg) * parseFloat(thisObj.deal.CloseQty) * scale;
|
||||
let deliveryPrice = thisObj.getStorageDeliveryPrice();
|
||||
thisObj.floatPosition.TradingAmount = deliveryPrice * parseFloat(thisObj.deal.CloseQty);
|
||||
thisObj.floatPosition.CloseFee = TradingFee;
|
||||
if (thisObj.deal.CloseQty == 0) {
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = 0;
|
||||
} else {
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = parseFloat(thisObj.floatPosition.TradingAmountAvg) * scale + (TradingFee / thisObj.deal.CloseQty) * ratio;
|
||||
thisObj.floatPosition.TradingAmountFeeAvg = deliveryPrice + (TradingFee / thisObj.deal.CloseQty) * ratio;
|
||||
}
|
||||
this.interestList.forEach(x => {
|
||||
/*let interestRatio = x.InterestDirection == 1 ? 1 : -1;*/
|
||||
@@ -360,7 +364,7 @@ const vue = new Vue({
|
||||
thisObj.floatPosition.EventDate = thisObj.deal.ValueDate;
|
||||
let floatPosition = _.cloneDeep(thisObj.floatPosition);
|
||||
floatPosition.Quantity = reqObj.CloseQty;
|
||||
floatPosition.TradingAmountAvg = floatPosition.TradingAmountAvg * thisObj.getPriceScale();
|
||||
floatPosition.TradingAmountAvg = thisObj.getStorageDeliveryPrice();
|
||||
reqObj.FlowEvents.push(floatPosition);
|
||||
var postData = { unwindData: reqObj };
|
||||
var msg = "确认提交平仓?";
|
||||
|
||||
Reference in New Issue
Block a user