feat(订单推送/通知): 按实际成交价与 size_matched 展示价格与数量
- 实际成交价公式: original_size * price / size_matched,数量展示用 size_matched - OrderPushService/OrderStatusUpdateService/CryptoTail: 用公式计算 avgFilledPrice,移除 getTrades 依赖 - TelegramNotificationService: 有 avgFilledPrice 时展示数量用 filled,ORDER_SUCCESS/CRYPTO_TAIL 一致 - 前端订单推送: 有成交时展示 size_matched;无 orderDetail 时用 WebSocket 数据计算价格与数量 - OrderDetailDto 增加 avgFilledPrice;PolymarketClobService 移除 getAvgFilledPriceFromTradeIds Made-with: Cursor
This commit is contained in:
+20
-11
@@ -117,28 +117,37 @@ function App() {
|
||||
}
|
||||
}
|
||||
|
||||
// 优先使用订单详情中的数据,如果没有则使用 WebSocket 消息中的数据
|
||||
const price = orderDetail ? parseFloat(orderDetail.price).toFixed(4) : parseFloat(order.price).toFixed(4)
|
||||
const size = orderDetail ? parseFloat(orderDetail.size).toFixed(2) : parseFloat(order.original_size).toFixed(2)
|
||||
const filled = orderDetail ? parseFloat(orderDetail.filled).toFixed(2) : parseFloat(order.size_matched).toFixed(2)
|
||||
// 实际成交价 = original_size*price/size_matched;有成交时数量用 size_matched
|
||||
const size = orderDetail ? orderDetail.size : order.original_size
|
||||
const filled = orderDetail ? orderDetail.filled : order.size_matched
|
||||
const sizeNum = parseFloat(size).toFixed(2)
|
||||
const filledNum = parseFloat(filled).toFixed(2)
|
||||
const hasFilled = parseFloat(filled) > 0
|
||||
const price = orderDetail
|
||||
? (orderDetail.avgFilledPrice ?? orderDetail.price)
|
||||
: (hasFilled
|
||||
? (parseFloat(order.original_size) * parseFloat(order.price) / parseFloat(order.size_matched)).toString()
|
||||
: order.price)
|
||||
const priceStr = parseFloat(price).toFixed(4)
|
||||
const status = orderDetail?.status || 'UNKNOWN'
|
||||
|
||||
// 有成交时展示数量用 size_matched(filled),否则用 original_size
|
||||
const displaySize = (orderDetail?.avgFilledPrice || (orderDetail == null && hasFilled)) ? filledNum : sizeNum
|
||||
|
||||
// 构建描述信息
|
||||
let description = `${t('order.market')}: ${marketName}\n${sideText} ${size} @ ${price}`
|
||||
let description = `${t('order.market')}: ${marketName}\n${sideText} ${displaySize} @ ${priceStr}`
|
||||
|
||||
// 如果有订单详情,显示更详细的信息
|
||||
if (orderDetail) {
|
||||
description += `\n${t('order.status')}: ${status}`
|
||||
if (parseFloat(filled) > 0) {
|
||||
description += ` | ${t('order.filled')}: ${filled}`
|
||||
if (parseFloat(filledNum) > 0) {
|
||||
description += ` | ${t('order.filled')}: ${filledNum}`
|
||||
}
|
||||
const remaining = (parseFloat(size) - parseFloat(filled)).toFixed(2)
|
||||
const remaining = (parseFloat(sizeNum) - parseFloat(filledNum)).toFixed(2)
|
||||
if (parseFloat(remaining) > 0) {
|
||||
description += ` | ${t('order.remaining')}: ${remaining}`
|
||||
}
|
||||
} else if (order.type === 'UPDATE' && parseFloat(order.size_matched) > 0) {
|
||||
// 如果没有订单详情,使用 WebSocket 消息中的已成交数量
|
||||
description += `\n${t('order.filled')}: ${filled}`
|
||||
description += `\n${t('order.filled')}: ${filledNum}`
|
||||
}
|
||||
|
||||
// 根据订单类型选择通知类型
|
||||
|
||||
@@ -580,12 +580,13 @@ export interface OrderMessage {
|
||||
|
||||
/**
|
||||
* 订单详情(通过 API 获取)
|
||||
* price 为订单限价,avgFilledPrice 为平均成交价(有成交时优先用于展示)
|
||||
*/
|
||||
export interface OrderDetail {
|
||||
id: string // 订单 ID
|
||||
market: string // 市场 ID (condition ID)
|
||||
side: string // BUY/SELL
|
||||
price: string // 价格
|
||||
price: string // 订单限价
|
||||
size: string // 订单大小
|
||||
filled: string // 已成交数量
|
||||
status: string // 订单状态
|
||||
@@ -593,6 +594,7 @@ export interface OrderDetail {
|
||||
marketName?: string // 市场名称
|
||||
marketSlug?: string // 市场 slug
|
||||
marketIcon?: string // 市场图标
|
||||
avgFilledPrice?: string // 平均成交价(有成交时优先展示)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user