tweak: 重新定义交易日规则(夜盘归属下一天,周五夜盘归属下周一)

refactor3.0
Lxy 1 week ago
parent 6559534463
commit e18473862e

@ -6,7 +6,7 @@ import re
import uuid
import json
import logging
from datetime import datetime
from datetime import datetime, timedelta
from collections import defaultdict
from pathlib import Path
@ -194,6 +194,48 @@ def _normalize_time(time_val) -> str:
return s
def recalculate_trade_date(trade_date: str, trade_time: str) -> str:
"""
根据交易时间重新计算交易日
期货交易规则
- 前一交易日 21:00 之后到当前交易日 15:00 之前的交易算作当天交易
- 周五 21:00 之后的夜盘交易算作下周一的交易数据
:param trade_date: 原始交易日 (YYYY-MM-DD)
:param trade_time: 交易时间 (HH:MM:SS)
:return: 重新计算后的交易日
"""
if not trade_date or not trade_time:
return trade_date
try:
# 解析日期和时间
dt = datetime.strptime(trade_date, '%Y-%m-%d')
time_parts = trade_time.split(':')
hour = int(time_parts[0])
# 判断是否在夜盘时段 (21:00 之后)
if hour >= 21:
# 夜盘交易,交易日归属下一天
next_day = dt + timedelta(days=1)
# 如果是周五 (weekday=4),下一天是周六,需要跳到下周一
if dt.weekday() == 4: # 周五
next_day = dt + timedelta(days=3) # 跳到下周一
# 如果是周六 (weekday=5),跳到下周一
elif dt.weekday() == 5:
next_day = dt + timedelta(days=2)
# 如果是周日 (weekday=6),跳到下周一
elif dt.weekday() == 6:
next_day = dt + timedelta(days=1)
return next_day.strftime('%Y-%m-%d')
else:
# 日盘交易,保持原交易日
return trade_date
except (ValueError, IndexError):
return trade_date
def _build_dedup_key(trade_date: str, variety: str, trade_time: str, price: float) -> str:
"""构建去重键:交易日+品种+交易时间+价格价格保留2位小数避免浮点精度问题"""
return f"{trade_date}|{variety}|{trade_time}|{round(price, 2)}"
@ -280,8 +322,10 @@ def save_to_db(
continue
futures_parsed += 1
variety = extract_variety(contract)
trade_date = _normalize_date(row.get('实际成交日期', ''))
raw_date = _normalize_date(row.get('实际成交日期', ''))
trade_time = _normalize_time(row.get('成交时间', ''))
# 根据交易时间重新计算交易日(夜盘归属下一天)
trade_date = recalculate_trade_date(raw_date, trade_time)
bs_flag = str(row.get('买/卖', '')).strip()
oc_flag = str(row.get('开/平', '')).strip()
price = safe_float(row.get('成交价'))
@ -300,7 +344,7 @@ def save_to_db(
# 记录前几条的去重键用于调试
if futures_parsed <= 3:
logger.info(f"[去重校验] 期货记录 #{futures_parsed}: date={trade_date!r}, variety={variety!r}, time={trade_time!r}, price={price!r} => key={dedup_key!r}")
logger.info(f"[去重校验] 期货记录 #{futures_parsed}: raw_date={raw_date!r}, trade_date={trade_date!r}, variety={variety!r}, time={trade_time!r}, price={price!r} => key={dedup_key!r}")
new_keys_in_batch.add(dedup_key)
rec = TradeRecord(
@ -331,8 +375,10 @@ def save_to_db(
continue
options_parsed += 1
variety = extract_variety(contract)
trade_date = _normalize_date(row.get('成交日期', ''))
raw_date = _normalize_date(row.get('成交日期', ''))
trade_time = _normalize_time(row.get('成交时间', ''))
# 根据交易时间重新计算交易日(夜盘归属下一天)
trade_date = recalculate_trade_date(raw_date, trade_time)
bs_flag = str(row.get('买/卖', '')).strip()
price = safe_float(row.get('权利金单价'))

@ -0,0 +1,19 @@
# 设计文档
## 实现方案
### 交易日重计算函数 `recalculate_trade_date`
输入:原始交易日 (YYYY-MM-DD) + 交易时间 (HH:MM:SS)
输出:重新计算后的交易日
逻辑:
1. 解析交易时间,判断是否在 21:00 之后
2. 如果在 21:00 之后(夜盘):
- 如果原始交易日是周五,则交易日 = 下周一
- 否则交易日 = 原始交易日 + 1 天
3. 如果在 15:00 之前且不在夜盘时段,保持原交易日
4. 其他情况保持原交易日
### 应用位置
`save_to_db` 中处理每条记录时,调用 `recalculate_trade_date` 重新计算交易日。

@ -0,0 +1,14 @@
# 交易日定义重新定义
## 动机
当前交易日直接使用结算单中的"实际成交日期",但期货交易有夜盘,需要重新定义交易日归属:
- 前一交易日 21:00 之后到当前交易日 15:00 之前的交易,算作当天交易
- 周五 21:00 之后的夜盘交易,算作下周一的交易数据
## 目标
1. 在导入时根据交易时间重新计算交易日
2. 正确处理周五夜盘归属下周一的情况
## 范围
- `app/services/trade_parser.py` — 新增交易日重计算函数
- 导入时应用新的交易日规则

@ -0,0 +1,5 @@
# 任务列表
- [x] 1. 新增交易日重计算函数 `recalculate_trade_date`
- [x] 2. 在 `save_to_db` 中应用新的交易日规则
- [x] 3. 测试验证交易日计算逻辑
Loading…
Cancel
Save