第24章 量化数据治理体系
本章顾问:沈飞(数据工程)
预估时长:3小时
本章前置检查:
- □ 已完成第23章的学习,理解量化公司的业务流程
- □ 已注册Tushare账号并获取Token
- □ 熟悉Python和Pandas基础操作
本章难点提示:
- 24.2节的复权处理是新手最容易出错的环节,务必理解前复权与后复权的区别。Tushare的
adj_factor复权因子字段提供了完整的复权支持,建议使用后复权作为统一基准。 - 24.3节的自动化数据质量监控是生产环境的关键基础设施,初学阶段可以简化实现,但要理解各检查项的意义。
- 24.4节介绍的DVC数据版本控制属于进阶内容,如果数据量不大可以先使用简单的Parquet目录分区方式管理。
🎯 本章教学目标:掌握量化数据治理的完整流程,学会使用Tushare获取金融数据,掌握Pandas进行数据清洗和预处理的方法,建立自动化数据质量监控体系,理解并实现数据版本控制策略。
![图片[1]-量化数据治理体系完全指南:从Tushare采集到DuckDB存储的全链路方案](http://www.ifisme.cn/wp-content/uploads/2026/05/教材2401.png)
24.1 数据源的选择与对比
🎯 本节目标:了解各类金融数据源的优缺点,学会使用Tushare获取行情和财务数据。
预计时长:1小时
24.1.1 为什么数据治理是量化的基石
在量化投资中,数据是策略研发的基础。用沈飞的话说:“数据质量直接决定了回测的可信度和实盘的可靠性。”低质量的数据可能导致:
- 策略回测表现虚高,实盘却亏损
- 因子测试结果不可复现
- 误判市场规律,造成真实损失
沈飞注:我在实盘中见过最惨痛的教训,是一个动量因子在回测中表现优异,后来发现是因为数据中包含未来信息(前视偏差)。那之后,团队建立了严格的数据验证流程。不要以为数据源可信就跳过验证——这是血的教训。
因此,本章将从数据源选择开始,建立一套完整的数据治理体系。
24.1.2 Tushare入门:注册与Token获取
Tushare是一个免费、开源的Python财经数据接口包,为金融分析人员提供快速、整洁、便于分析的数据。其核心优势包括:数据覆盖股票、基金、期货、宏观经济等20+个领域,提供日级/分钟级/Tick级多频段数据;标准化API设计使数据获取代码量减少70%以上;免费版即可满足基础策略开发需求,专业版提供更丰富的衍生数据。-13
获取Tushare Pro Token的步骤:访问Tushare社区门户(https://tushare.pro),点击右上角“注册”完成账号注册。-5注册成功后会获得100积分。-然后在个人主页里填写并完善个人信息,可获得额外20积分。对于股票行情数据,只要有120积分就可以相对高频地提取数据了,这120积分随手可得。-1最后进入个人主页,在“接口TOKEN”页面复制token。-
沈飞注:建议在完成基础120积分需求后,通过分享接口文档到社交媒体等方式进一步获取更多积分,以保证高频数据调取的稳定性。-
24.1.3 安装与初始化
在命令行中执行:pip install tushare pandas numpy matplotlib。-5-13
然后在Python中进行初始化:
python
import tushare as ts
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体,避免图表显示为方框
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 设置token
ts.set_token('你的token') # 请将'你的token'替换为实际token
pro = ts.pro_api()
print(f"tushare版本: {ts.__version__}")
print("Tushare初始化成功!")
24.1.4 常用数据接口速查
python
# 获取股票基本信息 stock_info = pro.stock_basic(exchange='', list_status='L') # 获取单只股票日线数据 df = pro.daily(ts_code='600519.SH', start_date='20200101', end_date='20231231') # 获取指定交易日的全市场行情(效率更高,推荐) df = pro.daily(trade_date='20231231') # 获取交易日历 trade_cal = pro.trade_cal(exchange='SSE', is_open='1', start_date='20200101', end_date='20231231') # 获取财务指标(需要更高积分) df = pro.fina_indicator(ts_code='600519.SH', start_date='20200101', end_date='20231231') # 获取沪深300成分股权重 hs300 = pro.index_weight(index_code='000300.SH')
龙马注:提取数据的效率优化技巧——如果要获取全市场历史数据,建议按
trade_date循环提取数据而非使用ts_code循环。-1在实际循环提取数据时,可以先通过交易日历拿到一段历史的所有交易日,再按日期循环。同时建议实现一个带重试机制的函数以避免网络波动导致数据中断:-1
python
def get_daily_with_retry(pro, ts_code='', trade_date='',
start_date='', end_date='', max_retries=3):
for attempt in range(max_retries):
try:
if trade_date:
df = pro.daily(ts_code=ts_code, trade_date=trade_date)
else:
df = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date)
return df
except Exception as e:
print(f"第{attempt+1}次尝试失败: {e}")
time.sleep(1)
return pd.DataFrame()
24.1.5 数据源对比与选择建议
| 数据源 | 免费额度 | 数据覆盖 | 适用场景 |
|---|---|---|---|
| Tushare | 120积分基础版 | 股票、基金、期货、宏观 | 个人量化研究、策略开发 |
| 聚宽 | 免费(部分数据) | A股数据、因子库 | 回测平台集成 |
| 米筐 | 免费(基础版) | 股票、ETF、因子 | 策略研究 |
| Wind | 商业付费 | 全市场数据 | 机构专业研究 |
| Yahoo Finance | 免费 | 美股、全球市场 | 全球资产配置 |
沈飞注:对于个人量化投资者,Tushare是目前最友好、最实用的选择——免费、数据全面、社区活跃。如果你刚开始量化学习,直接从Tushare开始足够了。付费数据源不是必需品,它解决的是更专业的需求,不是基础入门门槛。
24.2 数据清洗与预处理规范
🎯 本节目标:掌握金融数据清洗的完整流程,能够独立处理缺失值、异常值、复权等常见问题。
预计时长:1小时
重要提醒:数据清洗不仅是技术活,更是量化分析中决定策略可靠性的关键环节。低质量的数据会直接导致回测结果失真。本节提供的所有功能函数均应封装为可复用的
data_cleaner模块,纳入数据治理体系日常调用。
24.2.1 数据清洗的必要性
原始数据从API获取后通常存在缺失值、异常值、价格未复权等问题。例如停牌日产生缺失、数据源错误导致异常报价、由于分红、送股等原因,股价需要进行复权处理才能真实反映投资回报。这些问题如果不处理,会直接污染因子计算结果和回测绩效的真实性。
由于分红、送股等原因,股价需要进行复权处理才能真实反映投资回报。Tushare返回的股票日线行情包含adj_factor(复权因子)字段,通过该字段可以完成精准的复权计算。
Tushare日线数据关键字段:trade_date(交易日期)、ts_code(股票代码)、open(开盘价)、close(收盘价)、high(最高价)、low(最低价)、vol(成交量)、amount(成交金额)、adj_factor(复权因子)。
24.2.2 数据清洗5步流程
Step 1:数据类型转换与校验
Tushare返回的数据通常已经是正确的数据类型,但仍需进行必要的校验:
python
def validate_data_types(df):
"""校验数据类型是否正确"""
# 确保数值列为float类型
numeric_cols = ['open', 'high', 'low', 'close', 'vol', 'amount', 'adj_factor']
for col in numeric_cols:
if col in df.columns:
df[col] = pd.to_numeric(df[col], errors='coerce')
# 确保日期列为datetime类型
if 'trade_date' in df.columns:
df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')
return df
Step 2:处理缺失值
python
def handle_missing_values(df, method='ffill'):
"""
处理缺失值
method: 'ffill'(前向填充), 'bfill'(后向填充), 'drop'(删除)
"""
if method == 'ffill':
df.fillna(method='ffill', inplace=True)
elif method == 'bfill':
df.fillna(method='bfill', inplace=True)
elif method == 'drop':
df.dropna(inplace=True)
# 检查是否还有缺失值
if df.isnull().sum().sum() > 0:
print(f"警告: 仍有{df.isnull().sum().sum()}个缺失值未处理")
return df
Step 3:异常值检测与处理
python
def detect_outliers_zscore(df, column, threshold=3):
"""使用Z-Score方法检测异常值"""
mean = df[column].mean()
std = df[column].std()
z_scores = np.abs((df[column] - mean) / std)
outliers = df[z_scores > threshold]
return outliers
def handle_outliers_iqr(df, column, multiplier=1.5):
"""使用IQR(四分位距)方法处理异常值"""
Q1 = df[column].quantile(0.25)
Q3 = df[column].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - multiplier * IQR
upper_bound = Q3 + multiplier * IQR
# 将异常值替换为边界值或中位数
df[column] = df[column].clip(lower_bound, upper_bound)
return df
Step 4:复权价格计算
python
def calculate_adj_price(df, price_type='close'):
"""
计算后复权价格
后复权价格 = 实际价格 × 复权因子
后复权可以真实反映资产的长期投资回报
"""
df['adj_close'] = df['close'] * df['adj_factor']
# 同时计算其他价格字段的复权值
df['adj_open'] = df['open'] * df['adj_factor']
df['adj_high'] = df['high'] * df['adj_factor']
df['adj_low'] = df['low'] * df['adj_factor']
return df
沈飞注:复权处理必须统一使用后复权价格。前复权会让历史价格看起来更低,容易在回测中引入前视偏差。后复权价格更能真实反映资产的长期投资回报,是专业量化实践中推荐的标准做法。
Step 5:价格验证与逻辑一致性检查
python
def validate_price_consistency(df):
"""确保价格逻辑一致性:High ≥ Open/Close ≥ Low"""
violations = []
for idx, row in df.iterrows():
if row['high'] < max(row['open'], row['close']):
violations.append(idx)
if row['low'] > min(row['open'], row['close']):
violations.append(idx)
if len(violations) > 0:
print(f"警告: 发现{len(violations)}行价格逻辑异常")
df.loc[violations, 'high'] = df.loc[violations][['open','close']].max(axis=1)
df.loc[violations, 'low'] = df.loc[violations][['open','close']].min(axis=1)
return df
24.2.3 完整清洗整合函数
python
def clean_ohlc_data(df):
"""完整价量数据清洗流水线"""
original_len = len(df)
# Step 1: 数据类型转换
df = validate_data_types(df)
# Step 2: 按交易日期排序
df = df.sort_values('trade_date')
# Step 3: 处理缺失值(前向填充)
df = handle_missing_values(df, method='ffill')
# Step 4: 异常值处理(仅针对价格列)
price_cols = ['open', 'high', 'low', 'close']
for col in price_cols:
if col in df.columns:
df = handle_outliers_iqr(df, col)
# Step 5: 价格逻辑一致性验证
df = validate_price_consistency(df)
# Step 6: 计算后复权价格
if 'adj_factor' in df.columns:
df = calculate_adj_price(df)
# 输出清洗统计
print(f"清洗完成:原始{original_len}行 → 最终{len(df)}行,删除{original_len - len(df)}行")
return df
24.2.4 时间序列对齐处理
在多资产分析时,需要将不同股票的行情数据对齐到相同的时间轴:
python
def align_time_series(df_dict, on='trade_date'):
"""
将多个股票的DataFrame按日期对齐
df_dict: {'600519.SH': df1, '000858.SZ': df2, ...}
"""
aligned = pd.DataFrame()
for ts_code, df in df_dict.items():
df = df.set_index(on)[['adj_close']].rename(columns={'adj_close': ts_code})
aligned = pd.concat([aligned, df], axis=1)
# 前向填充缺失值(停牌日)
aligned.fillna(method='ffill', inplace=True)
# 删除开市前/退市后的无效数据
aligned.dropna(inplace=True)
return aligned
24.3 数据质量监控体系
🎯 本节目标:建立自动化的数据质量监控体系,通过Agent定时检查数据完整性、一致性,并及时告警。
预计时长:0.5小时
24.3.1 为什么需要数据质量监控
数据源本身可能存在延迟、缺失、异常等问题。如果在回测或策略运行中使用了低质量数据,结果将不可信。尤其在实盘环境中,如果数据源故障而未被及时发现,可能导致策略信号错误,造成真实损失。因此,需要建立一个自动化的监控体系,主动发现数据问题并及时告警。
数据质量监控在现代金融体系中已成为标准实践。例如,中原银行通过数据质量监控平台(DQM)自动检测缺失值、异常值,清洗后数据准确率达99.9%。光大银行通过数据质量管控工具实现了“事中刚控”和“事后监测”,能在发现数据异常时实时阻断批量任务执行。--25本节我们将构建适合个人量化的轻量级监控框架。
24.3.2 关键监控规则
| 监控项 | 检查内容 | 异常阈值 | 处理动作 |
|---|---|---|---|
| 数据完整性 | 当日缺失股票数量 | 缺失率>5% | 告警 |
| 数据时效性 | 最新数据时间戳 | 超过T+1交易日14:00 | 告警+切换备用源 |
| 数据稳定性 | 复权因子变化率 | 日波动>3% | 告警+人工复核 |
| 数据边界检查 | 价格变动幅度 | 当日涨跌>10% | 记录+标记 |
| 一致性检查 | 总市值与流通市值关系 | 逻辑违反 | 告警+标记 |
24.3.3 实现监控Agent(基于OpenClaw)
由于人工逐项检查不可持续,必须通过Agent实现自动化监控。我们可以利用OpenClaw的Cron定时任务配合Hermes的数据分析能力来构建一套完整的监控体系。
Step 1:编写数据质量检查函数
首先创建一个独立的Python脚本,封装数据质量检查逻辑:
python
# data_quality_checker.py
import tushare as ts
import pandas as pd
from datetime import datetime, timedelta
def check_data_completeness(trade_date):
"""检查指定交易日数据完整性"""
pro = ts.pro_api()
try:
df = pro.daily(trade_date=trade_date)
total_stocks = len(df)
missing_data = df[df['close'].isnull()] # 收盘价缺失
missing_rate = len(missing_data) / total_stocks
return {
'status': 'warning' if missing_rate > 0.05 else 'normal',
'total_stocks': total_stocks,
'missing_count': len(missing_data),
'missing_rate': missing_rate
}
except Exception as e:
return {'status': 'error', 'error_msg': str(e)}
def check_data_timeliness():
"""检查数据时效性"""
pro = ts.pro_api()
pro_daily = pro.daily()
latest_date = pro_daily['trade_date'].max()
latest_dt = datetime.strptime(str(latest_date), '%Y%m%d')
now = datetime.now()
days_behind = (now - latest_dt).days
return {
'status': 'warning' if days_behind > 1 else 'normal',
'latest_date': latest_date,
'days_behind': days_behind
}
Step 2:创建Cron定时任务
在OpenClaw中创建定时任务,每天收盘后自动执行数据质量检查。执行方法:在OpenClaw中运行以下命令:
bash
openclaw cron add --name "data_quality_monitor" \ --cron "0 16 * * 1-5" --tz Asia/Shanghai \ --message "检查今日数据完整性、时效性和稳定性,输出报告到飞书监控群。如发现异常,标记等级并@我。"
如果需要更密集的实时监控,可修改Cron表达式为更短的间隔,但需确保您的Tushare积分账户支持更高频次的调用。
Step 3:让Hermes自动分析质量问题
当监控Agent发现异常时,可以触发Hermes进行深度分析:
python
# 异常分析: 当监控Agent检测到缺失率>5%时,自动调用以下分析
def analyze_data_gap(ts_code, start_date, end_date):
"""分析特定股票的数据缺口”
df = pro.daily(ts_code=ts_code, start_date=start_date, end_date=end_date)
# 计算实际交易日数量
trade_cal = pro.trade_cal(exchange='SSE', is_open='1',
start_date=start_date, end_date=end_date)
expected_days = len(trade_cal)
actual_days = len(df)
# 找出缺失日期
expected_dates = set(trade_cal['cal_date'].values)
actual_dates = set(df['trade_date'].values)
missing_dates = expected_dates - actual_dates
return {
'expected_days': expected_days,
'actual_days': actual_days,
'missing_rate': (expected_days - actual_days) / expected_days,
'missing_dates': sorted(list(missing_dates))[:10] # 前10个缺失日期
}
Step 4:配置告警推送
使用OpenClaw的--deliver参数,可将检查结果推送到指定的飞书群:
bash
openclaw cron add --name "data_monitor" \ --cron "0 16 * * 1-5" --tz Asia/Shanghai \ --message "执行数据完整性检查" \ --deliver feishu:oc_xxxxxxxxxxxx
龙马注:数据监控Agent的价值不是帮你“跑个python脚本”,而是7×24值守。市场收盘后自动运行数据巡检,发现异常时通过飞书告警;定期对比历史数据趋势,预判数据源稳定性。数据工程师可以安心下班,系统在值班。
24.3.4 与其他治理模块的联动
数据质量监控不是孤立的模块,它能与数据治理的其他环节形成紧密联动:
| 发现的问题 | 自动触发动作 |
|---|---|
| 数据缺失率超标 | 通知数据工程师修复;自动切换到备用数据源 |
| 复权因子异常 | 人工复核并重新生成清洗后数据 |
| 数据时效持续滞后 | 提高数据采集频次;增加积分配额告警 |
| 价格逻辑冲突 | 记录问题行并上报告警;修复后自动重跑受影响的回测任务 |
24.4 数据存储与版本管理
🎯 本节目标:掌握量化数据的存储方案设计,实现数据的完整版本控制和回测可重现。
预计时长:0.5小时
24.4.1 为什么需要数据版本管理
量化研究的一个核心要求是可重现性。当你优化策略时,如果数据发生了变化(例如数据源修正了历史价格),就无法确定策略绩效的提升是来自策略改进还是数据变更。引入数据版本控制后,每次回测都能精确对应到特定版本的数据集。DVC的核心哲学是将大型数据文件的存储与版本信息分离,让你能用Git来版本化一切——代码、元数据和流水线定义,同时将大型数据文件委托给更合适的后端存储。–
24.4.2 推荐存储方案:Parquet + DVC
传统量化存储方式(CSV、Excel、Pickle)在处理大规模历史数据时存在明显的性能瓶颈和存储冗余问题。针对这些痛点,推荐以下组合方案:Parquet作为存储格式 + DVC作为版本控制工具。Parquet列式存储格式的按需读取机制(仅加载所需列,跳过不相关数据的I/O)和多样化压缩算法(Snappy、Gzip等)使其大幅优于CSV,对百万级分钟线数据的查询和分析效率提升可达数倍。对于量化因子库或ETF成分股数据,Parquet的性能优势更为明显,且不同分区间的读取查询互不影响。
Step 1:配置Parquet存储结构
python
import pandas as pd
import os
from dvc import api as dvc_api
def save_to_parquet(df, ts_code, data_type='daily', base_path='./data'):
"""将数据保存为Parquet格式,按股票代码和数据类型分区存储”
save_path = f"{base_path}/{data_type}/ts_code={ts_code}/"
os.makedirs(save_path, exist_ok=True)
file_path = f"{save_path}/data.parquet"
df.to_parquet(file_path, index=False)
print(f"数据已保存至:{file_path}")
def load_from_parquet(ts_code, data_type='daily', base_path='./data'):
"""加载Parquet格式数据”
file_path = f"{base_path}/{data_type}/ts_code={ts_code}/data.parquet"
if os.path.exists(file_path):
return pd.read_parquet(file_path)
else:
print(f"未找到数据文件:{file_path}")
return pd.DataFrame()
Step 2:安装并初始化DVC
bash
# 安装DVC(建议使用pip安装) pip install dvc # 在项目根目录初始化DVC cd your_quant_project git init dvc init # 初始化DVC,创建.dvc目录和配置 # 添加数据存储远程仓库(以S3为例,也可使用本地路径) dvc remote add -d myremote s3://my-quant-bucket/dvc-store # 或使用本地存储:dvc remote add -d myremote /mnt/dvc_storage
Step 3:版本化管理数据
bash
# 将数据文件加入DVC追踪 dvc add data/daily # 提交到Git(仅提交元文件) git add data/daily.dvc .gitignore git commit -m “首次添加日线数据集v1.0 # 推送数据到远程存储 dvc push
龙马注:推荐的分区策略——建议数据文件按天分区存储,便于增量更新和快速时间范围查询。目录结构示例: daily_data/year=2024/month=01/day=02/。每日数据更新时只需写入当天的文件,无需重写全量数据集,极大提高了更新效率。Step 4:增量更新与元数据追踪
利用分区存储的优势,每次只更新最新交易日的数据,大幅提升更新效率。同时记录每个数据文件的元数据,便于追踪数据版本变化:
python
def update_data_incremental(ts_code, last_update, data_type='daily'):
"""增量更新数据,仅拉取缺失交易日”
end_date = pd.Timestamp.now().strftime('%Y%m%d')
new_data = pro.daily(ts_code=ts_code, start_date=last_update, end_date=end_date)
if not new_data.empty:
old_data = load_from_parquet(ts_code, data_type)
old_data['trade_date'] = pd.to_datetime(old_data['trade_date'], format='%Y%m%d')
new_data['trade_date'] = pd.to_datetime(new_data['trade_date'], format='%Y%m%d')
updated_data = pd.concat([old_data, new_data]).drop_duplicates('trade_date')
save_to_parquet(updated_data, ts_code, data_type)
# 记录元数据
record_data_version(ts_code)
return load_from_parquet(ts_code, data_type)
def record_data_version(ts_code, version_note=''):
\"\"\"记录数据版本信息\"\"\"
version_file = './data/versions.csv'
version_entry = {
'ts_code': ts_code,
'timestamp': pd.Timestamp.now(),
'file_hash': compute_file_hash(f'./data/daily/ts_code={ts_code}/data.parquet'),
'note': version_note
}
if os.path.exists(version_file):
versions = pd.read_csv(version_file)
versions = pd.concat([versions, pd.DataFrame([version_entry])], ignore_index=True)
else:
versions = pd.DataFrame([version_entry])
versions.to_csv(version_file, index=False)
def restore_data_version(ts_code, version_timestamp):
\"\"\"根据时间戳恢复历史数据版本\"\"\"
versions = pd.read_csv('./data/versions.csv')
target_version = versions[(versions['ts_code'] == ts_code) & (versions['timestamp'] == version_timestamp)]
if not target_version.empty:
# DVC checkout指定版本
import subprocess
subprocess.run(['dvc', 'checkout', f'data/daily/ts_code={ts_code}/data.parquet.dvc',
'--rev', target_version['file_hash'].values[0]])
#### Step 5:版本间切换与回测可重现
通过DVC的`checkout`功能,你可以随时在数据集的历史版本之间切换,实现回测结果在不同数据版本上的对比和精准回溯:
```bash
# 查看数据版本历史
dvc list .
# 切换到特定版本
git checkout v1.0
dvc checkout
版本管理最佳实践:
- 定期快照:每月初对所有数据进行快照并标记版本标签
- 变更审计:每次数据更新自动记录变更日志,方便追溯问题数据源头
- 环境一致性:
dvc.lock文件记录所有数据文件的版本哈希,保证多人协作或重跑回测时数据版本一致
第24章 参考资料与扩展阅读
- Tushare Pro官方文档 —— Token获取、接口说明、积分规则 https://tushare.pro/document/2
- Tushare数据字段说明和清洗规范 —— 日线行情、复权因子使用 https://tushare.pro/document/2?doc_id=27
- Tushare量化数据获取与清洗完整教程(2026新版) https://developer.aliyun.com/article/1731584
- ml4t-data:金融数据统一管理库 —— 多数据源适配、Parquet存储 https://pypi.org/project/ml4t-data/
- DVC官方文档 —— 数据版本控制完整指南 https://dvc.org/doc
- Pandas官方文档:缺失值处理、数据清洗 https://pandas.pydata.org/docs/user_guide/missing_data.html
- Parquet格式在量化交易中的应用(VectorBT系列) https://jishuzhan.net/article/1910245538458566657
第五篇综合任务(第24章完成后)
任务:完成以下所有检查项,并记录输出。
- 注册Tushare账号、获取Token并完成初始化
- 使用Tushare获取贵州茅台(600519.SH)过去3年的日线数据
- 应用完整的数据清洗流程(缺失值处理→异常值检测→后复权计算→逻辑校验)
- 将清洗后的数据保存为Parquet格式
- 创建OpenClaw Cron定时任务进行每日数据完整性检查
- (可选)安装DVC并完成数据版本初始化
完成后,保存数据清洗脚本,命名为chapter24_data_cleaning.py。
顾问审校意见
沈飞(量化顾问):
“数据治理是整个量化体系的基石。本章给出的Tushare注册、数据清洗、Parquet存储、DVC版本控制方案,完全覆盖了从入门到生产级的数据管理需求。需要特别强调两点:
第一,复权处理必须统一使用后复权价格。前复权会让历史价格偏低,在回测中容易引入前视偏差。后复权才能真实反映资产的长期回报。
第二,数据版本管理不是可选,是必需。我曾经因为数据源修正了历史复权因子,导致策略回测结果出现差异——花了三天时间才排查清楚原因。从那以后,每一次数据更新都记录版本。本章的 record_data_version函数虽然简单,但足以满足个人量化需求。”
龙马(技术顾问):
“24.3节的透明监控配置非常实用。我补充一个配置细节:Cron任务的超时时间需要合理设置。数据质量检查如果涉及全市场5000+股票,可能需要几分钟才能完成,建议在Cron命令中添加 --timeout 600(10分钟超时),避免因数据拉取时间过长导致任务中断。
另外,关于数据存储路径,建议使用环境变量配置(如 QUANT_DATA_ROOT),而不是硬编码在代码中。这样在多环境部署时更灵活,也便于后续迁移。”























暂无评论内容