
数据格式转化:把原始数据变成策略能吃的菜
量化交易的第一步不是写策略,而是让数据变得可用。从交易所拿到的原始数据往往格式混乱,比如时间戳是字符串,价格是科学计数法,交易量单位不一致。用Python处理这些问题,核心是pandas。
时间格式转化
多数行情数据的时间列是字符串,像2024-01-15 09:30:00。策略需要的是datetime类型,才能做时间切片、重采样。用pd.to_datetime一行搞定:
import pandas as pd
df['timestamp'] = pd.to_datetime(df['timestamp'])
如果时间格式不标准,比如20240115 093000,加上format参数强制解析。记住,量化策略里所有时间必须统一到同一时区,通常用UTC避免夏令时混乱。

数值类型转化
原始数据里的价格可能带逗号,像1,234.56,或者交易量是字符串。用astype或pd.to_numeric转换:
df['price'] = df['price'].str.replace(',', '').astype(float)
df['volume'] = pd.to_numeric(df['volume'], errors='coerce')
errors='coerce'会把无法转换的值变成NaN,这样不会因为一个脏数据让整个策略崩溃。期货数据常有小数点后多位,确保用float64而不是float32,避免精度损失。
分类变量转化
股票代码、合约月份这类分类变量,用category类型能大幅节省内存。比如期货主力合约切换,把'IF2401'转成类别,策略里用cat.codes做映射,比字符串比较快几十倍。
数据检查:别让脏数据毁掉你的回测
数据检查不是可选项。回测赚钱、实盘亏钱,十有八九是数据问题。Python里几个关键检查点必须做。
缺失值检查
用df.isnull().sum()看每列缺多少。股票数据里偶尔停牌,期货数据里夜盘缺失,处理方式不同。股票停牌可以前向填充,期货夜盘缺失得直接删掉,否则策略会在不存在的价格上交易。
missing = df.isnull().sum()
print(missing[missing > 0])
如果缺失比例超过5%,考虑这个数据源是否可靠。用df.dropna()删掉缺失行,或者df.fillna(method='ffill')前向填充。注意,前向填充只适合价格,不适合成交量。
异常值检查
价格突然从100跳到10000,要么是数据错误,要么是拆股没复权。用分位数法:
q1 = df['price'].quantile(0.25)
q3 = df['price'].quantile(0.75)
iqr = q3 - q1
lower = q1 - 1.5 * iqr
upper = q3 + 1.5 * iqr
outliers = df[(df['price'] < lower) | (df['price'] > upper)]
期货数据里,涨跌停板外的价格一定是错的。检查high >= low,close在high和low之间,否则就是脏数据。
时间连续性检查
股票分钟数据应该每分钟都有,期货夜盘和日盘要分开。检查时间间隔:
df['time_diff'] = df['timestamp'].diff()
gaps = df[df['time_diff'] > pd.Timedelta(minutes=1)]
发现大缺口说明数据缺失,回测时要么跳过这段,要么用插值补上。插值只适合价格,成交量插值会严重高估策略容量。
转化与检查的实战流程
拿到一份期货tick数据,先转时间戳,再统一数值类型,然后检查缺失和异常。用pandas的pipe把步骤串起来,代码干净。
def clean_data(df):
df['timestamp'] = pd.to_datetime(df['timestamp'])
df['price'] = pd.to_numeric(df['price'], errors='coerce')
df['volume'] = pd.to_numeric(df['volume'], errors='coerce')
df = df.dropna(subset=['price', 'volume'])
df = df[(df['price'] > 0) & (df['volume'] >= 0)]
df = df.sort_values('timestamp').reset_index(drop=True)
return df
cleaned = raw.pipe(clean_data)
检查通过后,把数据存成parquet格式,比CSV快10倍,且保留数据类型。回测时直接读parquet,省去重复转化。
常见坑与避坑指南
股票除权除息日,价格会跳空,没复权的话策略会误判趋势。用adjust参数从数据源直接拿复权价。期货主力合约换月,价格不连续,得用价差拼接。
时间戳时区问题最隐蔽。交易所给的是本地时间,策略如果按UTC算,夜盘会错位。统一用tz_localize转UTC。
内存不够时,用dtype指定类型。float64改float32,int64改int32,能省一半内存。但价格用float32会丢精度,别省这个。
数据检查要自动化。写个pytest测试,每次新数据进来跑一遍,确保没有负价格、时间倒流、重复行。重复行用df.duplicated().sum()查,多了直接drop_duplicates。
量化交易里,数据质量决定策略上限。Python的pandas和numpy把转化和检查变成几行代码,但每一步都得想清楚为什么做。别让脏数据混进回测,否则赚的钱都是假的。