179 lines
6.1 KiB
Python
179 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
检查数据库中的异常订单
|
||
用于调试莫名奇妙出现的平仓消息问题
|
||
"""
|
||
import sys
|
||
import os
|
||
|
||
# 添加项目路径
|
||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||
|
||
from app.services.db_service import db_service
|
||
from app.models.paper_trading import PaperOrder, OrderStatus
|
||
from sqlalchemy import text
|
||
from datetime import datetime, timedelta
|
||
|
||
|
||
def check_abnormal_orders():
|
||
"""检查所有异常订单"""
|
||
|
||
db = db_service.get_session()
|
||
|
||
print("=" * 80)
|
||
print("异常订单检查报告")
|
||
print("=" * 80)
|
||
print(f"检查时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
|
||
print()
|
||
|
||
# 1. 检查 OPEN 状态但 filled_price 为 0 或 None 的订单
|
||
print("【1】OPEN 状态但成交价无效的订单(可能导致错误平仓):")
|
||
print("-" * 80)
|
||
invalid_filled_orders = db.query(PaperOrder).filter(
|
||
PaperOrder.status == OrderStatus.OPEN,
|
||
(PaperOrder.filled_price == None) | (PaperOrder.filled_price == 0)
|
||
).all()
|
||
|
||
if invalid_filled_orders:
|
||
for order in invalid_filled_orders:
|
||
print(f" ⚠️ 订单ID: {order.order_id}")
|
||
print(f" 交易对: {order.symbol}")
|
||
print(f" 方向: {order.side.value}")
|
||
print(f" 状态: {order.status.value}")
|
||
print(f" 入场价: {order.entry_price}")
|
||
print(f" 成交价: {order.filled_price} ❌ 无效")
|
||
print(f" 创建时间: {order.created_at}")
|
||
print()
|
||
else:
|
||
print(" ✅ 无异常订单")
|
||
print()
|
||
|
||
# 2. 检查 PENDING 状态但已有成交价的订单
|
||
print("【2】PENDING 状态但有成交价的订单(状态不一致):")
|
||
print("-" * 80)
|
||
pending_with_filled = db.query(PaperOrder).filter(
|
||
PaperOrder.status == OrderStatus.PENDING,
|
||
PaperOrder.filled_price != None,
|
||
PaperOrder.filled_price > 0
|
||
).all()
|
||
|
||
if pending_with_filled:
|
||
for order in pending_with_filled:
|
||
print(f" ⚠️ 订单ID: {order.order_id}")
|
||
print(f" 交易对: {order.symbol}")
|
||
print(f" 成交价: {order.filled_price}")
|
||
print(f" 状态: PENDING(应该是 OPEN)")
|
||
print()
|
||
else:
|
||
print(" ✅ 无异常订单")
|
||
print()
|
||
|
||
# 3. 检查最近1小时内平仓的订单(入场价或出场价为0)
|
||
print("【3】最近平仓订单中价格异常的记录:")
|
||
print("-" * 80)
|
||
one_hour_ago = datetime.now() - timedelta(hours=1)
|
||
closed_abnormal = db.query(PaperOrder).filter(
|
||
PaperOrder.status.in_([OrderStatus.CLOSED, OrderStatus.CLOSED_TP, OrderStatus.CLOSED_SL, OrderStatus.CLOSED_BE]),
|
||
PaperOrder.closed_at >= one_hour_ago,
|
||
(
|
||
(PaperOrder.filled_price == None) | (PaperOrder.filled_price == 0) |
|
||
(PaperOrder.exit_price == None) | (PaperOrder.exit_price == 0)
|
||
)
|
||
).all()
|
||
|
||
if closed_abnormal:
|
||
for order in closed_abnormal:
|
||
print(f" ⚠️ 订单ID: {order.order_id}")
|
||
print(f" 交易对: {order.symbol}")
|
||
print(f" 成交价: {order.filled_price}")
|
||
print(f" 出场价: {order.exit_price}")
|
||
print(f" 平仓时间: {order.closed_at}")
|
||
print(f" 平仓原因: {order.status.value}")
|
||
print()
|
||
else:
|
||
print(" ✅ 无异常记录")
|
||
print()
|
||
|
||
# 4. 检查所有活跃订单的状态统计
|
||
print("【4】活跃订单状态统计:")
|
||
print("-" * 80)
|
||
active_stats = db.execute(text("""
|
||
SELECT
|
||
status,
|
||
COUNT(*) as count,
|
||
SUM(CASE WHEN filled_price IS NULL OR filled_price = 0 THEN 1 ELSE 0 END) as invalid_count
|
||
FROM paper_orders
|
||
WHERE status IN ('PENDING', 'OPEN')
|
||
GROUP BY status
|
||
"""))
|
||
|
||
for row in active_stats:
|
||
status_name = row[0]
|
||
count = row[1]
|
||
invalid = row[2]
|
||
print(f" {status_name}: {count} 个(异常: {invalid} 个)")
|
||
print()
|
||
|
||
# 5. 检查重复订单
|
||
print("【5】可能重复的订单(同一交易对、同一方向、相近创建时间):")
|
||
print("-" * 80)
|
||
duplicates = db.execute(text("""
|
||
SELECT symbol, side, created_at, order_id, entry_price
|
||
FROM paper_orders
|
||
WHERE status IN ('PENDING', 'OPEN')
|
||
AND created_at >= datetime('now', '-1 hour')
|
||
ORDER BY symbol, side, created_at DESC
|
||
""")).fetchall()
|
||
|
||
# 简单的重复检测:同一交易对+方向在1分钟内创建
|
||
seen = {}
|
||
duplicate_found = False
|
||
for row in duplicates:
|
||
key = (row[0], row[1]) # symbol + side
|
||
if key in seen:
|
||
prev_time = seen[key]
|
||
if abs((row[2] - prev_time).total_seconds()) < 60:
|
||
print(f" ⚠️ 可能重复: {row[0]} {row[1]}")
|
||
print(f" 订单ID: {row[3]}")
|
||
print(f" 时间: {row[2]}")
|
||
duplicate_found = True
|
||
seen[key] = row[2]
|
||
|
||
if not duplicate_found:
|
||
print(" ✅ 无明显重复")
|
||
print()
|
||
|
||
# 6. 最近的活动日志
|
||
print("【6】最近10条订单变更记录(按时间倒序):")
|
||
print("-" * 80)
|
||
recent_orders = db.query(PaperOrder).order_by(
|
||
PaperOrder.updated_at.desc()
|
||
).limit(10).all()
|
||
|
||
for order in recent_orders:
|
||
print(f" {order.updated_at.strftime('%H:%M:%S')} | {order.symbol} | "
|
||
f"{order.side.value:4s} | {order.status.value:15s} | "
|
||
f"入场:{order.entry_price} 成交:{order.filled_price}")
|
||
print()
|
||
|
||
print("=" * 80)
|
||
print("检查完成")
|
||
print("=" * 80)
|
||
|
||
# 输出清理建议
|
||
if invalid_filled_orders:
|
||
print()
|
||
print("🔧 发现异常订单!建议执行以下操作:")
|
||
print()
|
||
print("1. 删除 OPEN 状态但成交价无效的订单:")
|
||
for order in invalid_filled_orders:
|
||
print(f" DELETE FROM paper_orders WHERE order_id = '{order.order_id}';")
|
||
print()
|
||
print("2. 或者运行 python fix_abnormal_orders.py 自动修复")
|
||
|
||
db.close()
|
||
|
||
|
||
if __name__ == "__main__":
|
||
check_abnormal_orders()
|