ta / 回测边界
ta 能直接做回测吗:不能,但它缺的不是算法
把 ta 算出来的列接到一个「RSI < 30 就买入」的规则上,跑出一张收益曲线—— 这件事技术上五分钟就能做到。难的是判断那条曲线有没有意义。
ta 的职责边界很清楚:它只把 OHLCV 变成特征列。信号逻辑、成交假设、成本模型、样本外划分、 基准对比全都不在它的范围内。这一页不提供任何收益结论,只把「从指标列到可评估策略」 之间必须补齐的步骤逐条列出来,并指出三个最容易踩的泄漏点。
职责分工
从数据到策略评估,ta 负责哪些环节
| 流水线环节 | 谁负责 | ta 提供了什么 | 缺了会怎样 |
|---|---|---|---|
| 行情数据准备 | 你 / 数据源 | 什么都不提供(无行情接口) | 连输入都没有 |
| 指标计算 | ta | 43 个指标类、84 条输出列 | 只有这一段由 ta 负责 |
| 信号生成 | 你 | 只给数值,不给阈值判断或交叉信号 | 把指标数值直接当买卖信号是最常见的误用 |
| 持仓与调仓 | 你 | 不提供 | 没有仓位概念、没有再平衡逻辑 |
| 成交假设 | 你 | 不提供 | 不建模手续费、印花税、滑点、成交量冲击 |
| 绩效评估 | 你 / 回测框架 | 不提供 | 没有收益、回撤、夏普等任何统计 |
| 风险与合规 | 你 | 不提供 | 没有仓位上限、止损、敞口控制 |
一句话:ta 只做第 2 行。如果你看到某份教程用 ta 直接跑出收益曲线,那么第 3–7 行一定是教程作者自己写的——那些部分的对错,ta 不负责任,也不能拿来证明 ta 有效。这一页讨论的前提是你能把指标正确算出来,而这部分的口径请先看预热窗口与 NaN、数值验证与数据契约三页。
缺口清单
从指标列到可评估策略,必须补齐哪些步骤
| 必须补齐的一步 | 为什么不能省 | 最低限度的做法 |
|---|---|---|
| 信号时点对齐 | 指标在第 t 根 K 线收盘后才能算出,最早只能在 t+1 开盘或收盘成交 | 把信号整体后移一根 K 线,或用 shift(1) 显式表达 |
| 预热期处理 | 不同指标起点不同(13–47 行),如果第一个信号日落在预热期里,那一天的指标是 NaN 或 0 | 取所有使用指标的最长预热作为回测起点 |
| 交易成本 | 不扣成本的曲线只是数学练习,不是策略评估 | 至少建模手续费与印花税;A 股还要考虑最低佣金 |
| 滑点与成交假设 | 收盘价成交是理想假设,实际成交价与信号价不同 | 给出滑点区间做敏感性分析,而不是取一个乐观值 |
| 样本外划分 | 在同一段数据上反复调参数得到的曲线没有预测意义 | 先划定样本内/样本外,样本外只看一次 |
| 基准对比 | 上涨行情里任何多头策略看起来都不错 | 对标买入持有或相同市场的指数 |
| 多次试验的记录 | 试了 50 组参数却只报告其中一组,等于伪造 | 记录全部试过的参数组合与结果 |
这七条与 ta 无关,与「用指标做决策」有关。本站把它们列在这里,是因为「我用 ta 算出了 RSI,然后跑了个回测」这个句式里,真正决定结论是否成立的恰好是这七条,而不是 RSI 算得准不准。
泄漏点
ta 相关的信息泄漏点有哪些:三个具体形态
| 泄漏点 | 具体机制(已核验源码) | 后果 |
|---|---|---|
| 累计收益的锚点依赖 | CumulativeReturnIndicator 的实现是 (close / close.iloc[0] - 1) × 100——永远以序列第一行为基准 | 同一根 K 线的累计收益值,会因为你把数据起点往前挪一天而改变。若在不同窗口上分别计算再拼接,等于混入了不属于该时点的信息 |
| 预热期回填 | 用 fillna=True 时头部若干行是用不完整窗口算出来的(例如 20 日均线的前 19 行) | 头部样本的统计含义与后续不同;把这些行当作正常样本会引入「用不足信息算出的值」 |
| 指标与成交同日 | 指标用当日收盘价计算,若同一天就以该价格成交,等于假设自己能预知收盘价 | 最常见、也最容易被忽略的未来函数;至少要把成交推到下一根 K 线 |
| 收益率单位混淆 | daily_return() 与 daily_log_return() 都乘以了 100,返回的是百分点而不是小数 | 把 1.23 当成 1.23% 还是 123% 会直接改变仓位与风险计算 |
| 复权口径不一致 | 价格用复权、成交量不复权,或两个指标用了不同复权段的数据 | 量价类指标(OBV、MFI、VWAP)会出现隐性偏差 |
第一条和第四条来自源码核验,不是经验之谈。cumulative_return 的锚点依赖尤其隐蔽:它看起来只是一个普通特征列,但它的数值定义依赖于「你的数据从哪里开始」——这在滚动窗口或分段回测里会变成信息泄漏。要避免,就自己按固定基准日重算,或干脆不要在回测里用它。
A 股约束
A 股做指标策略还要多考虑什么
| A 股的额外约束 | 对指标策略的具体影响 | 处理方向 |
|---|---|---|
| T+1 交收 | 当日买入的股票当日不能卖出,「信号出现当天买、第二天卖」这种高频切换在 A 股不成立 | 回测成交逻辑必须按 T+1 建模,否则换手率会被系统性高估 |
| 涨跌停 | 涨停时买不进、跌停时卖不出;指标给出的信号在涨跌停板上无法执行 | 在成交假设里加入涨跌停过滤,不能只按收盘价撮合 |
| 停牌 | 停牌期间没有成交,行情序列出现缺口;如果数据源用 0 填充成交量,还会触发 ta.utils.dropna() 删行 | 识别停牌区间并单独处理;不要用会把 0 当缺失值的清洗函数 |
| 复权与前复权跳变 | 前复权价格会随最新除权事件整体变化,历史段被改写 | 固定复权口径并记录基准日;不要在回测中途换口径 |
| 交易成本结构 | 佣金(含最低收费)+ 印花税(卖出)+ 过户费 | 按你的实际券商费率建模;不要用一个笼统的「万分之几」 |
| 指数与个股差异 | 个股有涨跌停、停牌,指数没有 | 个股策略与指数策略不能共用一套成交假设 |
| 交易时段与集合竞价 | 盘中最高/最低价往往拿不到,开盘集合竞价与连续竞价的成交条件也不同 | 用日线 OHLCV 回测时,不要把当日最高价/最低价当成可成交价 |
这些约束都在 ta 之外——ta 只处理数字,不认识交易制度。把它们列出来是因为很多「指标策略」的漂亮结果,恰恰来自「按信号当天的收盘价无限量成交」这个在 A 股不可能实现的假设。另外要提醒的是,A 股的长期停牌与退市制度会让「幸存者偏差」变得很现实:如果你只拿当前还在交易的标的做回测,实际上已经预先筛掉了历史上消失的那一批。
验证流程
指标算完之后,最小验证流程是什么
一个可复现的最小验证流程(不含收益结论)
- 定基准日与样本区间:先决定样本内/样本外的分界点,之后不再改。记录每次试验的参数。
- 算指标并对齐起点:取所有使用指标的最长预热行数,把回测起点定在预热之后。
- 信号后移:
signal = signal.shift(1)——用第 t 根 K 线的指标,在第 t+1 根 K 线成交。这一步是区分「能做」和「看起来能做」的分水岭。 - 接入成交假设:手续费、印花税、滑点区间、涨跌停与停牌过滤、T+1 约束。
- 跑一次就不再调:样本外只跑一次。如果效果不好,回去改假设而不是改参数。
- 写清楚没做什么:把上面省掉的步骤逐条列进结论里,比写一个漂亮的夏普值更有价值。
这套流程里没有一个数字来自 ta——ta 的贡献只是把行情变成了几列特征。本站不提供、也不建议任何具体的交易策略或标的;上面六步的目的只是让「指标算完了」和「策略验证过了」这两个状态不被人为地混在一起。
还有一个容易被忽略的前提:你的样本是否够长。本机实测 43 个指标里最长预热 47 行,再加上样本内/样本外的划分,实际可用区间会被两端各吃掉一段。如果数据只有一两年,把预热、样本内、样本外都扣完之后,剩下的验证段可能短到不足以下结论——这一点在动手之前就该算清。各指标的预热长度见预热窗口页的实测表。
说法对照
关于 ta 与回测,六种常见说法哪些不成立
| 常见说法 | 实际情况 |
|---|---|
| 「ta 内置了策略」 | 没有。ta 只有指标计算,仓库里没有策略、没有回测模块、没有绩效统计 |
| 「ta 能回测」 | 不能。它不产生信号、不含成本模型、不做样本外划分 |
| 「指标算出来就能下单」 | 指标只是特征列;从特征到可执行信号之间还隔着一整套假设 |
| 「这个策略用了 ta,所以结果可信」 | ta 只影响指标数值的准确性,不影响成交假设、样本外划分、成本模型这些更关键的部分 |
| 「回测收益高说明指标有效」 | 回测收益取决于整套假设,在样本内反复调参几乎总能得到好看的结果 |
| 「ta 的 ATR 可以直接当止损距离用」 | ATR 前 13 行是 0.0 而不是 NaN,直接把 0 当止损距离会得到无保护仓位;必须先处理表头 |
| 「先用技能看一下,再拿 ta 复现就行」 | 两条路线的数据源与指标实现不同,数值不保证一致;跨库对不上时应先统一数据口径与预热约定 |
| 「指标数量越多,策略越稳」 | 84 条输出列里有大量同族相关列(布林带一个类就 7 列),列多不等于信息多;真正影响结论的是信号时点、成本假设与样本外划分 |
最后一条是本站实测发现的具体风险,不是理论担忧:AverageTrueRange 与 ADXIndicator 用数值 0 表示「还没算出来」,任何以它们为分母或阈值基础的计算都会在样本头部产生异常值。这类问题不会报错,只会静默地影响结果。想把口径先对齐,可以先看数值验证页;想让特征列一次性到位,看批量特征页;想比较“不写代码”的路线,导航栏的「对比」页里列了逐技能前置条件。
FAQ
关于 ta 与回测的常见问题
ta 能直接做回测吗?
为什么指标算出来之后不能马上做策略?
ta 有未来函数问题吗?
CumulativeReturnIndicator 以序列第一行为锚点,换起点结果就变;②fillna=True 会用不完整窗口算出头部值;③如果你用当日收盘指标在当日收盘成交,那是你的回测逻辑引入了未来数据,不是 ta。预热期对回测有什么影响?
A 股回测和美股有什么不同?
ta 的 daily_return 返回的是小数还是百分比?
DailyReturnIndicator 算了 (close/close.shift(1) - 1) 之后又乘以 100,所以返回的是百分点(例如 1.23 表示 +1.23%),不是 0.0123 这样的小数。同一模块的 daily_log_return 与 cumulative_return 也都乘了 100。用它做风险计算前先确认单位。