This commit is contained in:
薇薇安 2026-02-08 20:33:37 +08:00
parent cc324eead5
commit ec54716266
3 changed files with 241 additions and 7 deletions

View File

@ -641,13 +641,51 @@ async def get_realtime_positions(account_id: int = Depends(get_account_id)):
logger.info(f"获取到 {len(positions)} 个持仓") logger.info(f"获取到 {len(positions)} 个持仓")
# 并发获取所有持仓的挂单信息 # 并发获取所有持仓的挂单信息包括普通挂单和Algo挂单
open_orders_map = {} open_orders_map = {}
try: try:
position_symbols = [p.get('symbol') for p in positions if float(p.get('positionAmt', 0)) != 0] position_symbols = [p.get('symbol') for p in positions if float(p.get('positionAmt', 0)) != 0]
if position_symbols: if position_symbols:
logger.info(f"正在获取挂单信息: {position_symbols}") # 定义获取函数同时获取普通挂单和Algo挂单
tasks = [client.get_open_orders(sym) for sym in position_symbols] async def fetch_both_orders(symbol):
try:
# 并发调用两个接口
t1 = client.get_open_orders(symbol)
t2 = client.futures_get_open_algo_orders(symbol, algo_type="CONDITIONAL")
res = await asyncio.gather(t1, t2, return_exceptions=True)
orders = []
# 1. 普通订单
if isinstance(res[0], list):
orders.extend(res[0])
else:
logger.warning(f"获取 {symbol} 普通挂单失败: {res[0]}")
# 2. Algo订单 (需要标准化为普通订单格式)
if isinstance(res[1], list):
for algo in res[1]:
# 标准化 Algo Order 结构
orders.append({
'orderId': algo.get('algoId'),
'type': algo.get('orderType'), # Algo订单使用 orderType
'side': algo.get('side'),
'stopPrice': algo.get('triggerPrice'), # Algo订单使用 triggerPrice
'price': 0, # 通常为0
'origType': algo.get('algoType'),
'reduceOnly': algo.get('reduceOnly'),
'status': 'NEW', # 列表中都是生效中的
'_is_algo': True
})
else:
logger.warning(f"获取 {symbol} Algo挂单失败: {res[1]}")
return orders
except Exception as e:
logger.error(f"获取 {symbol} 订单组合失败: {e}")
return []
logger.info(f"正在获取挂单信息(包含Algo): {position_symbols}")
tasks = [fetch_both_orders(sym) for sym in position_symbols]
results = await asyncio.gather(*tasks, return_exceptions=True) results = await asyncio.gather(*tasks, return_exceptions=True)
for sym, orders in zip(position_symbols, results): for sym, orders in zip(position_symbols, results):

View File

@ -3,8 +3,13 @@
cd "$(dirname "$0")" cd "$(dirname "$0")"
# 查找运行中的uvicorn进程 # 查找运行中的uvicorn进程 (优先使用 lsof 查找端口占用)
PID=$(ps aux | grep "uvicorn api.main:app" | grep -v grep | awk '{print $2}') PID=$(lsof -t -i:8001)
if [ -z "$PID" ]; then
# 回退到 ps 查找 (如果 lsof 没找到或不可用)
PID=$(ps aux | grep "uvicorn api.main:app" | grep -v grep | awk '{print $2}')
fi
if [ -z "$PID" ]; then if [ -z "$PID" ]; then
echo "未找到运行中的后端服务" echo "未找到运行中的后端服务"
@ -16,8 +21,8 @@ else
kill $PID kill $PID
sleep 2 sleep 2
# 检查是否成功停止 # 检查是否成功停止 (使用 kill -0 检查进程是否存在,替代 ps -p)
if ps -p $PID > /dev/null 2>&1; then if kill -0 $PID > /dev/null 2>&1; then
echo "强制停止服务..." echo "强制停止服务..."
kill -9 $PID kill -9 $PID
sleep 1 sleep 1

View File

@ -0,0 +1,191 @@
[
{
"symbol": "FHEUSDT",
"side": "SELL",
"quantity": 328,
"entry_price": 0.08613,
"entry_value_usdt": 28.25064,
"notional_usdt": 28.47696,
"margin_usdt": 3.55962,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 0.08682,
"pnl": -0.22632,
"pnl_percent": -6.357982031789911,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "MUSDT",
"side": "BUY",
"quantity": 13,
"entry_price": 1.6629,
"entry_value_usdt": 21.6177,
"notional_usdt": 19.5280163,
"margin_usdt": 2.4410020375,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 1.5021551,
"pnl": -2.0896837,
"pnl_percent": -85.607618014944,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "ENSOUSDT",
"side": "BUY",
"quantity": 17.2,
"entry_price": 1.3622,
"entry_value_usdt": 23.42984,
"notional_usdt": 23.1856,
"margin_usdt": 2.8982,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 1.348,
"pnl": -0.24424,
"pnl_percent": -8.427299703264095,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "GPSUSDT",
"side": "BUY",
"quantity": 2129,
"entry_price": 0.009901,
"entry_value_usdt": 21.079229,
"notional_usdt": 20.53067086,
"margin_usdt": 2.5663338575,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 0.00964334,
"pnl": -0.54855814,
"pnl_percent": -21.375166695356587,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "WLFIUSDT",
"side": "SELL",
"quantity": 487,
"entry_price": 0.0982,
"entry_value_usdt": 47.8234,
"notional_usdt": 49.8688,
"margin_usdt": 6.2336,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 0.1024,
"pnl": -2.0454,
"pnl_percent": -32.8125,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "ZKUSDT",
"side": "SELL",
"quantity": 2163,
"entry_price": 0.02166,
"entry_value_usdt": 46.850579999999994,
"notional_usdt": 46.74243,
"margin_usdt": 5.84280375,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 0.02161,
"pnl": 0.10815,
"pnl_percent": 1.8509949097639982,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
},
{
"symbol": "ROSEUSDT",
"side": "SELL",
"quantity": 3556,
"entry_price": 0.01252,
"entry_value_usdt": 44.521119999999996,
"notional_usdt": 44.34332,
"margin_usdt": 5.542915,
"original_notional_usdt": null,
"original_margin_usdt": null,
"mark_price": 0.01247,
"pnl": 0.1778,
"pnl_percent": 3.2076984763432246,
"leverage": 8,
"entry_time": null,
"stop_loss_price": null,
"take_profit_price": null,
"take_profit_1": null,
"take_profit_2": null,
"atr": null,
"entry_order_id": null,
"entry_order_type": null,
"open_orders": [],
"active_sl_orders": "",
"active_tp_orders": "",
"binance_open_orders_raw": []
}
]