update
This commit is contained in:
parent
a9f0aa0717
commit
9eb9bc9a49
@ -24,17 +24,42 @@ class OrderResponse(BaseModel):
|
|||||||
@router.get("/orders")
|
@router.get("/orders")
|
||||||
async def get_orders(
|
async def get_orders(
|
||||||
symbol: Optional[str] = Query(None, description="交易对筛选"),
|
symbol: Optional[str] = Query(None, description="交易对筛选"),
|
||||||
status: Optional[str] = Query(None, description="状态筛选: active, closed"),
|
status: Optional[str] = Query(None, description="状态筛选: active, closed, exchange"),
|
||||||
limit: int = Query(100, description="返回数量限制")
|
limit: int = Query(100, description="返回数量限制")
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
获取实盘订单列表
|
获取实盘订单列表
|
||||||
|
|
||||||
- symbol: 可选,按交易对筛选
|
- symbol: 可选,按交易对筛选
|
||||||
- status: 可选,active=活跃订单, closed=已平仓订单
|
- status: 可选
|
||||||
|
- active: 本地数据库的活跃订单
|
||||||
|
- closed: 本地数据库的历史订单
|
||||||
|
- exchange: 交易所的历史订单(推荐)
|
||||||
- limit: 返回数量限制,默认100
|
- limit: 返回数量限制,默认100
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# 如果请求交易所历史订单,直接从交易所获取
|
||||||
|
if status == "exchange":
|
||||||
|
trading_api = get_bitget_trading_api()
|
||||||
|
|
||||||
|
if not trading_api:
|
||||||
|
return {
|
||||||
|
"success": False,
|
||||||
|
"message": "Bitget API 未配置",
|
||||||
|
"count": 0,
|
||||||
|
"orders": []
|
||||||
|
}
|
||||||
|
|
||||||
|
orders = trading_api.get_closed_orders(symbol, limit)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"count": len(orders),
|
||||||
|
"orders": orders,
|
||||||
|
"source": "exchange"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 否则从本地数据库获取
|
||||||
service = get_real_trading_service()
|
service = get_real_trading_service()
|
||||||
|
|
||||||
if not service:
|
if not service:
|
||||||
@ -76,7 +101,8 @@ async def get_orders(
|
|||||||
return {
|
return {
|
||||||
"success": True,
|
"success": True,
|
||||||
"count": len(orders),
|
"count": len(orders),
|
||||||
"orders": orders
|
"orders": orders,
|
||||||
|
"source": "database"
|
||||||
}
|
}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"获取实盘订单列表失败: {e}")
|
logger.error(f"获取实盘订单列表失败: {e}")
|
||||||
|
|||||||
@ -364,6 +364,35 @@ class BitgetTradingAPI:
|
|||||||
return positions[0]
|
return positions[0]
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def get_closed_orders(self, symbol: str = None, limit: int = 100) -> List[Dict]:
|
||||||
|
"""
|
||||||
|
查询历史成交订单(从交易所获取)
|
||||||
|
|
||||||
|
Args:
|
||||||
|
symbol: 交易对(不传则查询所有)
|
||||||
|
limit: 返回数量
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
历史订单列表
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# 使用 CCXT 的 fetch_closed_orders 或 fetch_my_trades
|
||||||
|
if symbol:
|
||||||
|
ccxt_symbol = self._standardize_symbol(symbol)
|
||||||
|
orders = self.exchange.fetch_closed_orders(ccxt_symbol, limit=limit)
|
||||||
|
else:
|
||||||
|
orders = self.exchange.fetch_closed_orders(limit=limit)
|
||||||
|
|
||||||
|
logger.debug(f"查询到 {len(orders)} 条历史订单")
|
||||||
|
return orders
|
||||||
|
|
||||||
|
except ccxt.BaseError as e:
|
||||||
|
logger.error(f"❌ 查询历史订单失败: {e}")
|
||||||
|
return []
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"❌ 查询历史订单异常: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
# ==================== 账户操作 ====================
|
# ==================== 账户操作 ====================
|
||||||
|
|
||||||
def get_balance(self) -> Dict:
|
def get_balance(self) -> Dict:
|
||||||
|
|||||||
@ -229,6 +229,14 @@
|
|||||||
color: #ff4444;
|
color: #ff4444;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.fee-positive {
|
||||||
|
color: #00ff41;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fee-negative {
|
||||||
|
color: #ff4444;
|
||||||
|
}
|
||||||
|
|
||||||
.status-badge {
|
.status-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 2px 8px;
|
padding: 2px 8px;
|
||||||
@ -498,14 +506,11 @@
|
|||||||
<tr v-else>
|
<tr v-else>
|
||||||
<th>交易对</th>
|
<th>交易对</th>
|
||||||
<th>方向</th>
|
<th>方向</th>
|
||||||
<th>等级</th>
|
<th>类型</th>
|
||||||
<th>入场价</th>
|
<th>价格</th>
|
||||||
<th>当前价</th>
|
|
||||||
<th>数量</th>
|
<th>数量</th>
|
||||||
<th>杠杆</th>
|
<th>成交金额</th>
|
||||||
<th>止损</th>
|
<th>手续费</th>
|
||||||
<th>止盈</th>
|
|
||||||
<th>盈亏</th>
|
|
||||||
<th>状态</th>
|
<th>状态</th>
|
||||||
<th>时间</th>
|
<th>时间</th>
|
||||||
</tr>
|
</tr>
|
||||||
@ -536,36 +541,28 @@
|
|||||||
</template>
|
</template>
|
||||||
<!-- 订单表格 -->
|
<!-- 订单表格 -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<tr v-for="order in displayOrders" :key="order.order_id">
|
<tr v-for="order in displayOrders" :key="order.id || order.order_id">
|
||||||
<td><strong>{{ order.symbol }}</strong></td>
|
<td><strong>{{ formatSymbol(order.symbol) }}</strong></td>
|
||||||
<td>
|
<td>
|
||||||
<span class="side-badge" :class="'side-' + order.side">
|
<span class="side-badge" :class="order.side === 'buy' ? 'side-long' : 'side-short'">
|
||||||
{{ order.side === 'long' ? '做多' : '做空' }}
|
{{ order.side === 'buy' ? '买入' : '卖出' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
|
<td>{{ order.type || 'market' }}</td>
|
||||||
|
<td>${{ order.price ? parseFloat(order.price).toLocaleString() : '市价' }}</td>
|
||||||
|
<td>{{ order.amount || order.filled || '0' }}</td>
|
||||||
|
<td>${{ order.cost ? parseFloat(order.cost).toFixed(2) : '-' }}</td>
|
||||||
<td>
|
<td>
|
||||||
<span class="grade-badge" :class="'grade-' + (order.signal_grade || 'D')">
|
<span :class="getFeeClass(order)">
|
||||||
{{ order.signal_grade || 'D' }}
|
{{ order.fee && parseFloat(order.fee) !== 0 ? (order.fee > 0 ? '+' : '') + parseFloat(order.fee).toFixed(4) : '-' }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>${{ order.entry_price ? order.entry_price.toLocaleString() : '-' }}</td>
|
|
||||||
<td>${{ order.current_price ? order.current_price.toLocaleString() : '-' }}</td>
|
|
||||||
<td>${{ order.quantity ? order.quantity.toLocaleString() : '-' }}</td>
|
|
||||||
<td>{{ order.leverage || 1 }}x</td>
|
|
||||||
<td>${{ order.stop_loss ? order.stop_loss.toLocaleString() : '-' }}</td>
|
|
||||||
<td>${{ order.take_profit ? order.take_profit.toLocaleString() : '-' }}</td>
|
|
||||||
<td>
|
|
||||||
<span v-if="order.pnl !== undefined" :class="order.pnl >= 0 ? 'pnl-positive' : 'pnl-negative'">
|
|
||||||
{{ order.pnl >= 0 ? '+' : '' }}${{ order.pnl.toFixed(2) }}
|
|
||||||
</span>
|
|
||||||
<span v-else>-</span>
|
|
||||||
</td>
|
|
||||||
<td>
|
<td>
|
||||||
<span class="status-badge" :class="'status-' + order.status">
|
<span class="status-badge" :class="'status-' + order.status">
|
||||||
{{ formatStatus(order.status) }}
|
{{ formatOrderStatus(order.status) }}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ formatTime(order.created_at) }}</td>
|
<td>{{ formatTime(order.datetime || order.timestamp) }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -664,7 +661,8 @@
|
|||||||
|
|
||||||
async fetchHistoryOrders() {
|
async fetchHistoryOrders() {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get('/api/real-trading/orders?status=closed&limit=50');
|
// 从交易所获取历史订单
|
||||||
|
const response = await axios.get('/api/real-trading/orders?status=exchange&limit=50');
|
||||||
if (response.data.success) {
|
if (response.data.success) {
|
||||||
this.historyOrders = response.data.orders;
|
this.historyOrders = response.data.orders;
|
||||||
}
|
}
|
||||||
@ -710,6 +708,28 @@
|
|||||||
// 例如:BTC/USDT:USDT -> BTCUSDT
|
// 例如:BTC/USDT:USDT -> BTCUSDT
|
||||||
if (!symbol) return '-';
|
if (!symbol) return '-';
|
||||||
return symbol.replace('/', '').replace(':', '');
|
return symbol.replace('/', '').replace(':', '');
|
||||||
|
},
|
||||||
|
|
||||||
|
formatOrderStatus(status) {
|
||||||
|
const map = {
|
||||||
|
'open': '挂单中',
|
||||||
|
'closed': '已成交',
|
||||||
|
'canceled': '已取消',
|
||||||
|
'cancelled': '已取消',
|
||||||
|
'filled': '已成交',
|
||||||
|
'partially_filled': '部分成交',
|
||||||
|
'rejected': '已拒绝',
|
||||||
|
'expired': '已过期'
|
||||||
|
};
|
||||||
|
return map[status] || status;
|
||||||
|
},
|
||||||
|
|
||||||
|
getFeeClass(order) {
|
||||||
|
const fee = parseFloat(order.fee || 0);
|
||||||
|
if (fee === 0) return '';
|
||||||
|
// 如果是 taker (fee > 0),显示为负(花费)
|
||||||
|
// 如果是 maker (fee < 0),显示为正(返还)
|
||||||
|
return fee > 0 ? 'fee-negative' : 'fee-positive';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user