1
This commit is contained in:
parent
b41a907d07
commit
fc5afb0e84
@ -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)
|
||||||
|
|
||||||
# 获取所有已平仓订单(按日期范围)
|
# 获取所有已平仓订单(按日期范围)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user