TradingView 策略回测完整教学:五个会骗人的数字
你在 TradingView 图表上把一支 Pine Script 套上来——Pine Script 也就是 TradingView 内置、用来写指标与策略的脚本语言。Add Alert 按下去却找不到 Any alert() function call,Strategy Tester 面板也是灰的。回测跑不起来,看不到胜率也看不到净利。
没有人先跟你讲的是:只有以 strategy(...) 开头的脚本才会有 Strategy Tester,indicator(...) 开头的不会。这件事跟你的方案、跟你付了多少钱无关——是 Pine 官方文档的第 0 条规则,但几乎没人讲。
这篇不谈「策略应该怎么设计」——那是另一件事,我们写过[散户量化的三大陷阱:过拟合、幸存者偏差、未来函数](/blog/zh-Hans/quant-for-retail)。这篇只做三件事:把回测跑起来、把面板上的数字看懂、把 strategy() 几个会偷偷改变结果的默认值摊开来对照官方文档。
strategy() 页面(查证日期 2026 年 9 月 15 日)。TradingView 平台功能能不能用哪个方案,对照 tradingview.com/pricing 的方案比较表;付费层级随时可能改,实际动手前建议自己再去看一次当下版本。落差一:你手上写的是 indicator,还是 strategy?
Pine 脚本只有两种身分:indicator(...) 只做视觉呈现,strategy(...) 才会下模拟单、产生绩效表格。这件事在官方文档写得非常直白,但 AI 生的 Pine 常常搞混——你跟它说「帮我写一个 RSI 反转的策略」,它给你的第一行却是 indicator("RSI 反轉")。这种脚本连 Strategy Tester 都打不开。
最快的分辨方法是看文件第一个可运行函数:只有 strategy() 才有 Strategy Tester。同一个脚本里不会同时有两个声明,你只需要看那一行。
| 问题 | 答案 |
|---|---|
| 第一行写 indicator()? | 没有 Strategy Tester 面板。想回测必须改写成 strategy() |
| 第一行写 strategy()? | 图表下方会多出 Strategy Tester 分页;点下去就能看到绩效表 |
| 两种都不是(没写)? | Pine v6 要求声明,会直接编译错 |
怎么判断这支脚本能不能被回测(查证日期 2026 年 9 月,Pine Script v6)
把 indicator() 改成 strategy() 不是换个字这么简单——后者多了一堆跟资金、杠杆、手续费有关的参数(后面第五节会逐个讲),但这些**都有默认值**。你什么都不填,Pine 也会跑,只是跑出来的数字是 TradingView 官方定义的预设情境,不是你自己的实际情境。
落差二:Basic 方案能不能跑回测?可以,但这几件事会挡住你
免费的 Basic 方案是可以打开 Strategy Tester 的——你可以套自己写或别人分享的 strategy() 脚本、可以看到 Overview 分页的绩效数字、可以看 List of Trades。这一步不需要付钱。
挡住你的通常不是「打不开」而是这三件事:
| Basic(免费) | Premium 以上 | ||
|---|---|---|---|
| 打开 Strategy Tester、看 Overview 数字 | |||
| Bar Magnifier(用更小时间框架的数据模拟成交) | |||
| Pine 计算时间上限 | 20 秒 | 40~100 秒 | |
| 每张图同时挂的指标数量 | 2 | 25~50 | |
| webhook 通知(把信号自动 POST 到别的服务) |
Basic 与 Premium 对回测体验的差异(截至 2026 年 9 月,来源 tradingview.com/pricing 与 Pine v6 strategy() 官方 reference)
Bar Magnifier 这一项特别有感——官方 strategy() reference 对 use_bar_magnifier 这个参数的原文写着 「Only Premium and higher-tier plans have access to this feature」。Basic 用户没付钱,这个 checkbox 开了也不会生效。
1 小时线的一根 K 棒,内部可能已经触价止损又拉回,Basic 模式看不到这个过程、只会用开高低收算。想长期做自动化交易,Premium 这一阶通常是门槛——webhook 也就是把 alert 触发时的内容自动 POST 到你自己服务器或第三方服务的那条通道,Basic 一开始就没有。我们在[五个方案对回测与 webhook 的实际差异](/blog/zh-Hans/tradingview-plans-webhook-comparison)那篇拆开讲过,这里不重复。
Strategy Tester 面板:四个分页分别在给你什么
把脚本加上图表之后,画面下方的 Strategy Tester 面板会列出几个分页,各自服务不同的决策——搞错要看哪一个,会直接看漏东西。下面这几个是你多半会用到的核心分页(实际列出的分页与名称可能随 TradingView 版本微调):
| 分页 | 在给你的东西 | 什么时候看它 |
|---|---|---|
| Overview | Net Profit、Percent Profitable、Profit Factor、Max Drawdown 等总结 | 第一眼判断这支策略值不值得继续看 |
| Performance Summary | 把每个指标拆成 All / Long / Short 三栏;含 Sharpe、Sortino 等 | 决定要只跑多、只跑空、还是双向 |
| List of Trades | 每一笔进出场的时间、价位、获利、run-up、drawdown | 找出让 Max Drawdown 爆掉的元凶是哪一笔 |
| Properties | 当下这次回测用的所有 strategy() 参数,含没改的默认值 | 回测完存证;半年后回头对照当时设置 |
Strategy Tester 内核分页与用途(Pine Script v6,查证日期 2026 年 9 月)
常见的看漏是 Properties 这一页。绝大多数人只看 Overview 就下结论,但 Overview 的数字是用当下 Properties 的设置跑出来的结果。你如果没点进 Properties 对照,就不知道那个 68% 胜率背后预设是什么——initial_capital 100 万、每笔固定 1 张、零手续费、零滑价。这些是 Pine 的默认值,不是你的真实情境。第五节会逐个列出来。
Overview 那五个粗体字,每个都可以被造假
Overview 页面用最大字放五个总结数字。这五个数字有各自的陷阱,顺着念过去很容易被漂亮的曲线带跑。
Net Profit(净利):所有已结束交易的损益总和,减去手续费与滑价。绝对金额本身没有意义——当 default_qty_type 是 percent_of_equity 时,本金越大跑出来的 Net Profit 越大,两个不同本金的结果不能直接比。这个数字要跟旁边的 Net Profit % 一起看,或者把 initial_capital 先调到你要真跑的金额再算一次。
Percent Profitable(胜率):获利交易数 ÷ 总交易数。胜率高不等于赚钱——如果每次赢 10 元、每次输 100 元,胜率 80% 你还是亏的。这是为什么下一个数字更重要。
Profit Factor(获利因子):所有获利交易的总和 ÷ 所有亏损交易的总和。1 代表打平、大于 1 才有意义。实务判断标准:1.2 以下通常撑不过真实环境的滑价与手续费,2.0 以上要先怀疑自己是不是没设 commission 或滑价(第五节)。
Max Drawdown(最大回撤):**回测期间**权益曲线从最高点跌到最低点的最大幅度。这是「历史上发生过的最坏」,不是「未来可能发生的最坏」——样本外可能出现更深的回撤。看这个数字要自问:如果我真的在那个时间点看到账户跌这么多,我会不会关掉策略?会的话这支策略在你身上还没真正被回测过。
Total Closed Trades(总交易次数):策略在这段历史上完成了几笔交易。这个数字太小的时候(比如 10 次以下),前面四个数字全部没有统计意义——一次运气好的顺风就可以让胜率、Profit Factor 全部漂亮。判断粗略经验值:**个位数不看,两位数存疑,三位数以上才有点依据**。
五个 strategy() 默认值,会直接改变你的回测结果
strategy() 这个声明函数有三十几个参数,全部有默认值。你什么都不填也能编译过、也能跑出漂亮的绩效表——但那些数字是**用官方默认值算出来的**。这是新手最容易被骗的地方。以下五个是影响最大的:
(一)跟资金与仓位有关的三个
| 参数 | 官方默认值 | 现实怎么设 |
|---|---|---|
initial_capital | 1000000 | 改成你要真跑的金额,跟交易所余额一致 |
default_qty_type | strategy.fixed | 多数人要的是 strategy.percent_of_equity |
pyramiding | 0(拒绝加仓) | 确认你不需要加仓;需要就设 2、3 等数字 |
Pine Script v6 strategy() 的资金/仓位默认值(查证日期 2026 年 9 月 15 日)
(二)跟成本有关的两个
| 参数 | 官方默认值 | 现实怎么设 |
|---|---|---|
slippage | 0(tick) | 加密永续抓 1~3 tick,波动大的抓更多 |
commission_value | 0 | 抓交易所实际 taker 费率,去该所页面查 |
Pine Script v6 strategy() 的成本默认值(查证日期 2026 年 9 月 15 日)
strategy() reference 对 pyramiding 的原文写着 「If the value is 0, only one entry order in the same direction can be opened, and additional entry orders are rejected」——预设 0 是「同方向只允许一笔进场、后续同方向 entry 会被拒绝」。所以你如果在脚本里调用两次 strategy.entry("Long", strategy.long),第二次不会加仓,而是直接被丢掉。回测结果如果比你预期少了一大半交易,通常就是这个。想加仓必须主动设 pyramiding = 2 之类的具体数字。还有一个容易忽略的参数:risk_free_rate。Pine v6 reference 对它的原文写着 「It is used to calculate the Sharpe and Sortino ratios. Optional. The default is 2.」——预设 2 意即 2%。这个预设假设的是股票市场常用的年化无风险利率,你如果拿来看加密货币的策略,Sharpe 与 Sortino 会偏低。这个值该不该改要看你想跟什么基准比较,动之前先确认你知道它会影响哪两个数字。
request.security 的 lookahead 陷阱是另一件事
如果你的策略用到多时间框架(例如小时线脚本里调用日线数据),还有一组会让回测数字漂亮到不真实的默认值。这件事已经有专门的文章讲:[request.security 的 lookahead 陷阱:回测漂亮实盘对不上](/blog/zh-Hans/request-security-lookahead-trap)。
一句话总结:Pine v6 的 request.security 有个参数叫 lookahead,官方 reference 对它的原文写着 「The default is barmerge.lookahead_off starting from Pine Script® v3.」——**预设本来就是安全的(不会偷未来)**。所以那篇文章解的其实是「有人主动打开了 lookahead_on」或「历史数据聚合本身的延迟对不上」的变体问题,不是默认值的锅。这是第五节那个表格没放进来的第六个参数,因为它的默认值不会造成问题,只有主动去改才会。
Heikin Ashi、Renko 这类非标准图表:官方明讲「不建议」
Strategy Tester 是可以在 Heikin Ashi、Renko、Point & Figure 这些非标准图表上跑的,但结果会误导。这句话不是我说的:
strategy() 页面的 Remarks 段机制原因是这些图表的 K 棒价格是**合成出来的**。以下对照一下差别:
| 图表类型 | K 棒价格从哪来 | 回测适不适合 |
|---|---|---|
| 标准蜡烛图(Candles) | 当根 K 棒真实的 open / high / low / close | 适合 |
| Heikin Ashi | 由上一根与当根的价格平均出来,不是真实成交 | 官方不建议 |
| Renko / Kagi / Line Break | 由价格移动门槛自动堆积出的合成 K 棒 | 官方不建议 |
| Point & Figure | 只在特定价格变化时添加一格,没有时间轴的 K 棒 | 官方不建议 |
非标准图表为什么会给你不真实的回测(Pine Script v6,查证日期 2026 年 9 月)
Pine 的 strategy.entry() 会拿合成价当作进场价,跟你真的在市场上会成交的价格对不上。回测看起来平顺,实盘会发现信号同样时间出现但成交价差很多。
补救办法:strategy() 有一个 fill_orders_on_standard_ohlc 参数,设成 true 会强迫用标准 OHLC 价格成交(即使图表是 Heikin Ashi)。但这个设置只解决成交价,不解决信号本身是从合成 K 棒判读来的问题——真要做严肃的回测,直接换回标准蜡烛图比较干脆。
诚实的一段:回测是回头看,不是明天
到这里你已经有能力把面板上的数字看懂,也知道哪些默认值要改。但这件事必须在这里讲清楚——回测本质上是**用过去发生过的事情**,逼近**未来可能发生的事情**,两者永远不会完全一致。这不是 TradingView 的技术限制,是回测这件事本身的限制。
所以就算你把上面所有默认值都改到接近实盘、你的 Profit Factor 到 1.8、Max Drawdown 只有 12%——策略上线第一周就爆亏 15% 完全可能发生。那不代表你做错,只是回测数字从来没有保证过那件事。
真正该做的是把回测结果纪录好——期间、标的、参数、初始资金、手续费与滑价假设,全部写下来——然后把上线后每笔真实交易的结果对回这份纪录。实盘跟回测差得越远,代表这支策略对环境的假设越脆弱。这件事没有捷径。
每次上线一支新策略之前,把这五件事写下来存盘,半年后你回头问「这支怎么变这样」时,这份纪录是唯一能对答案的东西。
- 回测期间——几年到几年,横跨过哪几种市场(牛、熊、盘整)
- 标的——哪个交易所、哪根 K 棒周期、哪个交易对
- strategy() 的非预设参数——把你主动改过的参数与值列出来
- Bar Magnifier 有没有开——受限于方案时,明讲「没开」
- 手续费与滑价假设——commission_value 与 slippage 各自设了多少
常见问题
Basic 方案跑回测,数字可以用吗?
AI 帮我生的 Pine,回测看起来很赚,能直接接自动下单吗?
Profit Factor 到 3 以上,这是好事吗?
回测跟实盘差很多,是 TradingView 有问题吗?
回测结果可以写进博客或社区吗?
Get started
回测跑顺了、想把信号自动接到交易所,TVSBot 用你自己的 API key、先 dry-run、风控自己设——把 Pine 信号变真实下单这一段,不用另外写服务器。
免费开始使用