This commit is contained in:
aaron 2026-02-26 10:03:40 +08:00
parent b41a907d07
commit fc5afb0e84

View File

@ -2,7 +2,7 @@
模拟交易服务 - 订单管理和盈亏统计 模拟交易服务 - 订单管理和盈亏统计
""" """
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta, timezone
from typing import Dict, Any, List, Optional from typing import Dict, Any, List, Optional
from app.models.paper_trading import PaperOrder, OrderStatus, OrderSide, SignalGrade, EntryType from app.models.paper_trading import PaperOrder, OrderStatus, OrderSide, SignalGrade, EntryType
@ -11,6 +11,18 @@ from app.config import get_settings
from app.utils.logger import logger from app.utils.logger import logger
def get_beijing_time() -> datetime:
"""
获取东八区北京时间当前时间
Returns:
东八区的当前时间
"""
utc_time = datetime.utcnow().replace(tzinfo=timezone.utc)
beijing_tz = timezone(timedelta(hours=8))
return utc_time.astimezone(beijing_tz).replace(tzinfo=None)
class PaperTradingService: class PaperTradingService:
"""模拟交易服务""" """模拟交易服务"""
@ -273,7 +285,7 @@ class PaperTradingService:
# 现价单:立即开仓 # 现价单:立即开仓
status = OrderStatus.OPEN status = OrderStatus.OPEN
filled_price = current_price if current_price else entry_price filled_price = current_price if current_price else entry_price
opened_at = datetime.utcnow() opened_at = get_beijing_time()
else: else:
# 挂单:等待触发 # 挂单:等待触发
status = OrderStatus.PENDING status = OrderStatus.PENDING
@ -519,7 +531,7 @@ class PaperTradingService:
# 更新订单状态 # 更新订单状态
db_order.status = OrderStatus.OPEN db_order.status = OrderStatus.OPEN
db_order.filled_price = filled_price db_order.filled_price = filled_price
db_order.opened_at = datetime.utcnow() db_order.opened_at = get_beijing_time()
db.commit() db.commit()
db.refresh(db_order) db.refresh(db_order)
@ -627,12 +639,12 @@ class PaperTradingService:
pnl_amount = round(db_order.quantity * pnl_percent / 100, 2) pnl_amount = round(db_order.quantity * pnl_percent / 100, 2)
# 计算持仓时间 # 计算持仓时间
hold_duration = datetime.utcnow() - db_order.opened_at if db_order.opened_at else timedelta(0) hold_duration = get_beijing_time() - db_order.opened_at if db_order.opened_at else timedelta(0)
# 更新订单 # 更新订单
db_order.status = status db_order.status = status
db_order.exit_price = exit_price db_order.exit_price = exit_price
db_order.closed_at = datetime.utcnow() db_order.closed_at = get_beijing_time()
db_order.pnl_amount = round(pnl_amount, 2) db_order.pnl_amount = round(pnl_amount, 2)
db_order.pnl_percent = round(pnl_percent, 4) db_order.pnl_percent = round(pnl_percent, 4)
@ -1161,7 +1173,7 @@ class PaperTradingService:
db = db_service.get_session() db = db_service.get_session()
try: try:
order.status = OrderStatus.CANCELLED order.status = OrderStatus.CANCELLED
order.closed_at = datetime.utcnow() order.closed_at = get_beijing_time()
db.merge(order) db.merge(order)
db.commit() db.commit()
@ -1437,7 +1449,7 @@ class PaperTradingService:
return 0.0 return 0.0
# 确保订单按平仓时间排序 # 确保订单按平仓时间排序
orders = sorted(orders, key=lambda o: o.closed_at or datetime.utcnow()) orders = sorted(orders, key=lambda o: o.closed_at or get_beijing_time())
# 模拟账户权益曲线 # 模拟账户权益曲线
initial_balance = self.initial_balance initial_balance = self.initial_balance
@ -1599,7 +1611,7 @@ class PaperTradingService:
""" """
db = db_service.get_session() db = db_service.get_session()
try: try:
cutoff_time = datetime.utcnow() - timedelta(hours=hours) cutoff_time = get_beijing_time() - timedelta(hours=hours)
# 查询时间段内平仓的订单 # 查询时间段内平仓的订单
closed_orders = db.query(PaperOrder).filter( closed_orders = db.query(PaperOrder).filter(
@ -1701,7 +1713,7 @@ class PaperTradingService:
lines.append(f"{grade}级: {g['count']}笔 | 胜率{g['win_rate']}% | {pnl_sign}${g['total_pnl']:.0f}") lines.append(f"{grade}级: {g['count']}笔 | 胜率{g['win_rate']}% | {pnl_sign}${g['total_pnl']:.0f}")
lines.append("") lines.append("")
lines.append(f"<i>报告时间: {datetime.now().strftime('%Y-%m-%d %H:%M')}</i>") lines.append(f"<i>报告时间: {get_beijing_time().strftime('%Y-%m-%d %H:%M')}</i>")
return "\n".join(lines) return "\n".join(lines)
@ -1844,7 +1856,7 @@ class PaperTradingService:
# 更新订单状态 # 更新订单状态
order.status = OrderStatus.CLOSED order.status = OrderStatus.CLOSED
order.close_price = current_price order.close_price = current_price
order.close_time = datetime.utcnow() order.close_time = get_beijing_time()
order.pnl = pnl['pnl'] order.pnl = pnl['pnl']
order.pnl_percent = pnl['pnl_percent'] order.pnl_percent = pnl['pnl_percent']
order.close_reason = close_reason order.close_reason = close_reason
@ -1904,7 +1916,7 @@ class PaperTradingService:
from collections import defaultdict from collections import defaultdict
# 计算起始日期 # 计算起始日期
end_date = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0) end_date = get_beijing_time().replace(hour=0, minute=0, second=0, microsecond=0)
start_date = end_date - timedelta(days=days) start_date = end_date - timedelta(days=days)
# 获取所有已平仓订单(按日期范围) # 获取所有已平仓订单(按日期范围)