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

refactor3.0
Lxy 1 week ago
parent 6559534463
commit e18473862e

@ -6,7 +6,7 @@ import re
import uuid import uuid
import json import json
import logging import logging
from datetime import datetime from datetime import datetime, timedelta
from collections import defaultdict from collections import defaultdict
from pathlib import Path from pathlib import Path
@ -194,6 +194,48 @@ def _normalize_time(time_val) -> str:
return s 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: def _build_dedup_key(trade_date: str, variety: str, trade_time: str, price: float) -> str:
"""构建去重键:交易日+品种+交易时间+价格价格保留2位小数避免浮点精度问题""" """构建去重键:交易日+品种+交易时间+价格价格保留2位小数避免浮点精度问题"""
return f"{trade_date}|{variety}|{trade_time}|{round(price, 2)}" return f"{trade_date}|{variety}|{trade_time}|{round(price, 2)}"
@ -280,8 +322,10 @@ def save_to_db(
continue continue
futures_parsed += 1 futures_parsed += 1
variety = extract_variety(contract) variety = extract_variety(contract)
trade_date = _normalize_date(row.get('实际成交日期', '')) raw_date = _normalize_date(row.get('实际成交日期', ''))
trade_time = _normalize_time(row.get('成交时间', '')) trade_time = _normalize_time(row.get('成交时间', ''))
# 根据交易时间重新计算交易日(夜盘归属下一天)
trade_date = recalculate_trade_date(raw_date, trade_time)
bs_flag = str(row.get('买/卖', '')).strip() bs_flag = str(row.get('买/卖', '')).strip()
oc_flag = str(row.get('开/平', '')).strip() oc_flag = str(row.get('开/平', '')).strip()
price = safe_float(row.get('成交价')) price = safe_float(row.get('成交价'))
@ -300,7 +344,7 @@ def save_to_db(
# 记录前几条的去重键用于调试 # 记录前几条的去重键用于调试
if futures_parsed <= 3: 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) new_keys_in_batch.add(dedup_key)
rec = TradeRecord( rec = TradeRecord(
@ -331,8 +375,10 @@ def save_to_db(
continue continue
options_parsed += 1 options_parsed += 1
variety = extract_variety(contract) variety = extract_variety(contract)
trade_date = _normalize_date(row.get('成交日期', '')) raw_date = _normalize_date(row.get('成交日期', ''))
trade_time = _normalize_time(row.get('成交时间', '')) trade_time = _normalize_time(row.get('成交时间', ''))
# 根据交易时间重新计算交易日(夜盘归属下一天)
trade_date = recalculate_trade_date(raw_date, trade_time)
bs_flag = str(row.get('买/卖', '')).strip() bs_flag = str(row.get('买/卖', '')).strip()
price = safe_float(row.get('权利金单价')) 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