只会 Python,也能看懂金融数据:回测入门第 1 课
很多人第一次接触回测,会被这些词吓到:
OHLCV、复权、收益率、滑点、未来函数……
其实它们没有那么难。今天先搞懂金融数据,后面学 Backtrader 会轻松很多。
一、股票数据到底长什么样?
最常见的是一根 K 线:
| 字段 | 含义 |
|---|---|
| Open | 开盘价 |
| High | 最高价 |
| Low | 最低价 |
| Close | 收盘价 |
| Volume | 成交量 |
这五个字段合起来就是 OHLCV。
例如:
日期:2024-01-02
开盘:100
最高:105
最低:98
收盘:103
成交量:500000
它表示这一天价格从 100 开始,最高涨到 105,最低跌到 98,最后收在 103。
二、收益率怎么算?
最简单的收益率:
今天收益率 = 今天收盘价 / 昨天收盘价 - 1
例如:
昨天收盘价:100
今天收盘价:105
收益率:105 / 100 - 1 = 5%
用pandas计算:
df["return"] = df["close"].pct_change()
注意:第一天没有前一天价格,所以收益率通常是空值。
df = df.dropna()
三、信号、订单、成交,不是一回事
这是回测里非常重要的区别。
假设你的策略是:
收盘价突破 20 日均线,就买入。
这里其实分成三步:
- 信号:今天收盘后发现突破。
- 订单:策略决定买入。
- 成交:订单真正被市场执行。
在 Backtrader 中,next() 里发出的市价单,通常会在下一根 K 线的开盘价成交。
也就是说:
今天收盘产生信号
下一交易日开盘成交
不能直接假设“今天收盘发现信号,今天收盘就能买到”。
否则就可能产生“未来函数”。
四、什么是未来函数?
简单说:
你在回测时使用了当时还不知道的信息。
例如:
# 错误思路
如果明天会上涨,今天就买入
现实中你不可能提前知道明天的收盘价。
常见的未来函数包括:
- 使用未来几天的最高价;
- 用全量数据计算指标;
- 用今天收盘价生成信号,并假设今天收盘价成交;
- 用测试集数据反复调参数。
回测结果特别好时,第一件事不是庆祝,而是检查有没有偷看未来。
五、手续费和滑点会吃掉收益
假设策略每次交易赚 0.3%,但:
- 买入手续费 0.1%;
- 卖出手续费 0.1%;
- 滑点 0.1%。
一买一卖之后,利润可能已经所剩无几。
所以回测不能只看“理论收益”,还要考虑:
- 手续费;
- 印花税;
- 滑点;
- 最小交易单位;
- 资金是否足够;
- 是否真的能成交。
六、用 Python 检查金融数据
读取 CSV:
import pandas as pd
df = pd.read_csv(
"data.csv",
parse_dates=["datetime"]
)
df = df.sort_values("datetime")
df = df.set_index("datetime")
检查数据是否正常:
print(df.head())
print(df.isna().sum())
print(df.index.is_unique)
print(df.index.is_monotonic_increasing)
简单检查 K 线逻辑:
assert (df["high"] >= df[["open", "close"]].max(axis=1)).all()
assert (df["low"] <= df[["open", "close"]].min(axis=1)).all()
如果这些检查失败,说明数据可能存在问题。
七、复权是什么?
股票可能会分红、拆股。
比如一只股票从 100 元拆成 50 元,价格看起来突然跌了 50%,但这不一定是真实亏损。
复权数据会尽量把这些公司行为调整进去,让历史价格更适合计算收益。
常见选择:
- 前复权:适合观察当前价格下的历史走势;
- 后复权:适合观察历史持有收益;
- 不复权:更接近当时真实成交价格。
关键不是“哪种一定最好”,而是:
- 你必须知道自己使用的是什么数据,并保持前后一致。
八、给初学者的检查清单
开始做回测前,先确认:
- 日期是否升序排列?
- 日期是否重复?
- 是否有缺失值?
- OHLC 数据是否合理?
- 使用的是前复权还是后复权?
- 成交量单位是否一致?
- 手续费和滑点是否加入?
- 是否误用了未来数据?
- 信号和成交之间是否有合理延迟?
最后总结
金融数据可以先记住三句话:
- OHLCV 描述一根 K 线。
- 信号、下单、成交是三个不同过程。
- 回测必须模拟成本,并警惕未来函数。
先把数据看懂,再学习 Backtrader。不要一上来就调几十个指标,数据基础打牢,后面的策略代码才不会越写越乱。
&spm=1001.2101.3001.5002&articleId=166128971&d=1&t=3&u=d95095d692af4c6c8e2009488b553d64)
6372

被折叠的 条评论
为什么被折叠?



