4.8 KiB
4.8 KiB
时区处理修复总结
✅ 已完成的修改
1. trading_system/position_manager.py
修改内容:
- ✅ 导入
get_beijing_time函数(从database.models或创建本地版本) - ✅ 将
entryTime的存储从datetime.now()改为get_beijing_time() - ✅ 将所有计算持续时间的地方从
datetime.now()改为get_beijing_time()
修改位置:
- 第337行:
'entryTime': get_beijing_time()- 开仓时记录入场时间 - 第464行及多处:
exit_dt = get_beijing_time()- 计算持仓持续时间时使用北京时间
2. backend/database/models.py
已确认:
- ✅
Trade.create()方法已使用get_beijing_time()设置entry_time - ✅
Trade.update_exit()方法已使用get_beijing_time()设置exit_time - ✅ 所有其他模型(
AccountSnapshot,MarketScan,TradingSignal,TradeRecommendation)都已使用get_beijing_time()
3. SQL更新脚本
文件:backend/database/update_timezone_to_beijing.sql
功能:
- 将旧数据的
entry_time和exit_time从UTC时间(或服务器本地时间)转换为北京时间(UTC+8) - 提供了三种转换方法:
- 直接加8小时(如果旧数据是UTC时间)
- 根据服务器时区调整(如果旧数据是服务器本地时间)
- 使用MySQL时区转换函数(需要加载时区数据)
使用方法:
-- 1. 先备份数据库
mysqldump -u root -p auto_trade_sys > backup_$(date +%Y%m%d_%H%M%S).sql
-- 2. 根据实际情况调整SQL脚本中的时间偏移量
-- 3. 运行SQL脚本
mysql -u root -p auto_trade_sys < backend/database/update_timezone_to_beijing.sql
时间处理流程
开仓(Entry Time)
position_manager.py中open_position()方法:- 内存中存储:
'entryTime': get_beijing_time() - 数据库入库:
Trade.create()→ 使用get_beijing_time()设置entry_time
- 内存中存储:
平仓(Exit Time)
position_manager.py中各种平仓方法:- 计算持续时间:
exit_dt = get_beijing_time() - 数据库更新:
Trade.update_exit()→ 使用get_beijing_time()设置exit_time
- 计算持续时间:
时间格式
- 数据库存储:
TIMESTAMP类型,无时区信息(MySQL默认) - Python代码:使用
datetime对象,通过get_beijing_time()确保是北京时间(UTC+8) - 显示:前端可以根据需要转换为任何时区显示
验证方法
1. 检查新数据
-- 查看最近几条记录的入场时间
SELECT id, symbol, entry_time, exit_time, status
FROM trades
ORDER BY id DESC
LIMIT 10;
2. 检查时间是否合理
-- 检查是否有异常的时间(例如未来时间或很久以前的时间)
SELECT id, symbol, entry_time, exit_time
FROM trades
WHERE entry_time > NOW()
OR entry_time < '2020-01-01'
OR (exit_time IS NOT NULL AND exit_time > NOW())
OR (exit_time IS NOT NULL AND exit_time < entry_time);
3. 检查持续时间计算
-- 检查持仓持续时间是否合理
SELECT
id,
symbol,
entry_time,
exit_time,
TIMESTAMPDIFF(MINUTE, entry_time, COALESCE(exit_time, NOW())) as duration_minutes,
duration_minutes as stored_duration
FROM trades
WHERE exit_time IS NOT NULL
ORDER BY id DESC
LIMIT 10;
注意事项
-
旧数据处理:
- 如果旧数据已经是北京时间,不需要运行SQL更新脚本
- 如果旧数据是UTC时间,需要加8小时
- 如果旧数据是其他时区,需要相应调整
-
时区一致性:
- 所有入库时间都使用北京时间(UTC+8)
- 所有计算持续时间的地方也使用北京时间
- 前端显示可以根据需要转换时区
-
数据库时区设置:
- MySQL的
TIMESTAMP类型会根据服务器时区自动转换 - 建议服务器时区设置为
Asia/Shanghai或UTC+8 - 可以通过
SELECT @@global.time_zone, @@session.time_zone;查看
- MySQL的
-
代码时区处理:
- Python代码中使用
get_beijing_time()确保时区一致 - 不依赖系统时区设置,避免时区问题
- Python代码中使用
测试建议
-
开仓测试:
- 开仓后检查数据库中的
entry_time是否为北京时间 - 检查内存中的
entryTime是否为北京时间
- 开仓后检查数据库中的
-
平仓测试:
- 平仓后检查数据库中的
exit_time是否为北京时间 - 检查
duration_minutes计算是否正确
- 平仓后检查数据库中的
-
时区转换测试:
- 在不同时区的服务器上测试(如果可能)
- 验证时间显示是否正确
总结
✅ 所有入库时间已统一使用北京时间 ✅ 所有计算持续时间的地方已使用北京时间 ✅ 已提供SQL脚本更新旧数据 ✅ 代码已通过语法检查
现在系统的时间处理已经完全统一,所有时间都使用北京时间(UTC+8)存储和计算。