TradingView Webhook 不触发怎么办?
完整调试流程图,一层一层排查
Alert 设好了,图表上条件明明已经满足,结果下游什么反应都没有——或者有反应,但交易所没有真的下单。TradingView webhook 不触发这个问题可能卡在五个不同的环节,瞎猜是哪一层只会白白浪费好几个小时。
这篇文章是一套分层排查流程:套餐够不够格、Alert 到底有没有触发、TradingView 有没有真的发出去、你的服务器有没有真的收到、 交易所有没有真的接受下单。从最上面开始一层一层查——大部分人其实卡在第 0 层或第 1 层,只是自己还没意识到。
五层排查流程
从上到下照着走,每一步都会告诉你要继续往下查,还是问题已经找到了。
第 0 层——这个 alert 本身有没有资格发 webhook?
在动你的服务器或 Pine 脚本之前,先确认这个 alert 在结构上根本就有能力发 webhook。这里有两道独立的关卡, 任何一道卡住都足以解释「怎么设都没反应」。
套餐资格
Webhook 通知功能是按订阅套餐分级的。免费的 Basic 套餐完全没有 webhook 通知功能——不是被限制, 是这个功能本身就不存在于这个套餐里。截至 2026 年 7 月查证,TradingView 的套餐对比表如下:
| 套餐 | Webhook | Price + Technical alert 数 | Alert 存活期限 |
|---|---|---|---|
| Basic(免费) | 无 | 3 + 0 | 1 个月 |
| Essential | 有 | 20 + 20 | 2 个月 |
| Plus | 有 | 100 + 100 | 2 个月 |
| Premium | 有 | 400 + 400(另加 2 个 watchlist) | 可开启永不过期 |
| Ultimate | 有 | 1,000 + 1,000(另加 15 个 watchlist) | 可开启永不过期 |
TradingView 套餐对比表,截至 2026 年 7 月查证,实际数字请以 tradingview.com/pricing 当下显示为准。
Alert 到期与休眠机制
Alert 不是永久有效的。默认最长存活期限是两个月;Premium 和 Ultimate 套餐可以开启「永不过期」选项让 alert 一直存活。 过期的 alert 会在 Alert Manager 显示红色Stopped — Expired状态,之后就不会再触发——只能删除重建。
还有一条独立的规则值得知道:如果同时满足以下三个条件,alert 会被自动停用——创建超过一年、超过一年没触发过、并且超过一年没被编辑过。如果你的 alert 已经放着很久没动过,在怀疑是技术问题之前先检查这一点。
- 已确认套餐是 Essential 以上(Basic 没有 webhook 通知功能)
- 已检查 Alert Manager,状态是绿色 Active,不是红色 Stopped — Expired
- TradingView 账户已开启 2FA
- 如果 alert 已创建超过一年,已确认没有因为一年没动而被自动停用
第 1 层——Alert 到底有没有真的触发?
这一层最容易搞混,因为 TradingView 有两套完全不同的触发频率系统,很多人会把两者当成同一回事: 创建 alert 对话框里的Frequency下拉菜单,跟 Pine alert() 函数的 freq 参数。这两者的选项并不一样。
| 设置 | 出现在哪里 | 含义 |
|---|---|---|
| Once only(只触发一次) | 仅 UI 下拉菜单 | 条件完全符合设置参数时只触发一次 |
| Once per bar(每根 K 线一次) | UI 下拉菜单,或代码里的 alert.freq_once_per_bar | 每根 K 线都检查,条件满足就触发——不等 K 线收盘 |
| Once per bar close(K 线收盘才触发) | UI 下拉菜单,或代码里的 alert.freq_once_per_bar_close | 同样的检查,但要等 K 线真的收盘才触发 |
| Once per minute / every time | 仅 UI 下拉菜单 | 每分钟重新检查一次条件 |
| alert.freq_all | 仅 alert() 函数 | alert() 每次被调用都触发,没有每根 K 线的次数限制 |
alert() 函数的 freq 参数只接受三个值(once_per_bar / once_per_bar_close / all)——代码层面没有对应「Once only」或「Once per minute」的选项。
如果你的 Pine 脚本用的是 alert() 函数,触发频率是在代码里决定的,只有三个可能的值。 没有办法让 alert() 调用表现得像「Once only」或「Once per minute」——这两个选项只存在于 UI 设置、以 alertcondition() 为基础的指标 alert 里。把这两套心智模型搞混, 是「webhook 应该触发却没触发」最常见的原因之一。
Repainting 会让一个正常运作的 alert 看起来像坏了
依赖当前 K 线 high/low/close、或跨周期取数据的脚本,在实时 K 线还在形成时数值可能会浮动。 如果你的 Frequency 没设成Once Per Bar Close,alert 可能会在一个之后还会变动的数值上触发, 结果看起来像误触发,或者像「应该触发却没触发」,但其实跟你事后看到的画面对不上。 把 Frequency 设成 Once Per Bar Close 是这类问题的标准解法。
策略 alert 有自己的规则
如果 alert 挂在 strategy(策略)而不是 indicator(指标)上,还有几条额外规则。策略默认只在 K 线收盘时才重新计算—— 所以就算 alert() 在策略里填了 alert.freq_all 或 alert.freq_once_per_bar,实际上也只会在收盘时触发一次,除非你明确开启 calc_on_every_tick = true。另外,策略的下单成交 alert 只会在实时成交时通知—— 历史 K 线上本来会成交的单子完全不会产生通知,所以只用历史数据测试,永远看不到实时 alert 触发的画面。
还有一个容易犯的错:alertcondition() 只能在 indicator 里用。放进 strategy 一样能编译通过, 但完全不会有任何效果,也不会报错告诉你原因。
- Alert Manager 的触发记录里至少有一次过去的触发
- Frequency 设置符合你真正想要的行为(Once per bar vs. Once per bar close vs. Once per minute)
- 如果代码里用了 alert(),已确认 freq 值是三个合法选项之一
- 如果是策略 alert,已确认 calc_on_every_tick 的设置符合你想要的触发时机
- 已用 Once Per Bar Close 排除 repainting 的可能性
第 2 层——Request 有没有真的离开 TradingView 的服务器?
如果 Alert Manager 确认 alert 有触发,下一个问题是 TradingView 有没有成功把 webhook request 发出去。 URL 和 payload 有几个严格的技术规格要求:
| 规格 | 内容 |
|---|---|
| 端口 | 只接受 80 和 443——其他端口一律直接拒绝 |
| 协议 | 非 HTTPS / TLS 配置错误会被列为明确的发送失败原因 |
| IPv6 | 目前 webhook URL 不支持 IPv6 |
| 消息大小 | 手动输入在 Message 字段的消息上限 4,000 字符;通过 alert() 或 alert_message 参数上限 40,960 字符——request body 大小限制与此相同 |
| Content-Type | 自动判断:消息若为合法 JSON 则为 application/json,否则为 text/plain |
送达机制不是大家常以为的「全都会重试」。如果你的服务器返回5xx错误, TradingView 会在 5 秒后重发,最多重发 3 次(总共最多发 4 次)。但4xx响应或超时, 会被视为已送达直接丢弃——这两种情况都不会自动重试。另外还有一条硬性频率限制: 同一个 alert 在 3 分钟内触发超过 15 次,系统会自动停用它。
- Webhook URL 用的是端口 80 或 443(没用自定义端口)
- URL 是 HTTPS 且证书有效
- URL 指向公网的 IPv4 主机名,不是 IPv6
- Alert 消息在对应的大小上限内(4,000 或 40,960 字符)
- 没有不小心在 3 分钟内触发超过 15 次
第 3 层——你的服务器有没有真的收到?
大部分真正的「webhook 不触发」案例其实卡在这里:alert 触发了、TradingView 发出了 request, 但这个 request 从来没有到达你的应用程序。这里有两个 TradingView 端的限制要注意。
第一,你的服务器必须在3 秒内响应,否则 request 会被取消——而且按照上面的送达规则, 超时不会被重试。如果你的接口在响应之前先做了很慢的同步操作(下单、等交易所 API 响应), 这是在高负载下悄悄漏掉信号的常见原因。正确做法是立刻响应 webhook,实际下单逻辑改成后台异步处理。
第二,如果你设置了 IP 白名单,TradingView 目前发 webhook 用的是一组固定 IP——截至 2026 年 7 月查证:
52.89.214.238
34.212.75.30
54.218.53.128
52.32.178.7CN = webhook-server@tradingview.com 可以确认请求来源。 如果你的框架能检查客户端证书,这会比写死 IP 更可靠。URL 指向 localhost 或任何私有/内部 IP,是官方明确记载的失败案例——TradingView 的服务器 没办法直接连到你的电脑。本地开发阶段需要用公网隧道(比如 ngrok)架在服务器前面。
实际怎么测试
先直接打你自己的接口,把「我的服务器到底有没有在监听」和「TradingView 的 request 有没有送到」这两件事分开验证:
curl -X POST https://your-domain.com/webhook/your-token \
-H "Content-Type: application/json" \
-d '{"secret":"your-secret","symbol":"BTCUSDT","side":"buy"}'如果这个 curl 拿到很快的 200,你的服务器没问题,问题在上游(IP 白名单、超时, 或者 TradingView 那端)。如果 curl 自己都连不上,那是网络或防火墙问题,跟 TradingView 完全无关。
- 服务器在远低于 3 秒的时间内响应(任何状态码都可以)——重的工作放在响应之后,不是之前
- 防火墙或安全组允许 TradingView 来源 IP 的入站流量,或者改用 SSL 证书验证取代 IP 白名单
- Webhook URL 指向公网地址,不是 localhost 或私有 IP
- 直接对自己接口的 curl 测试返回 200
第 4 层——收到了,但交易所端没有出现任何下单
如果服务器日志确认 payload 送到了、代码也处理过了,最后一层就是交易所本身拒单或者忽略了这笔下单。 这一段 TradingView 完全管不到——纯粹是你的服务器跟交易所 API 之间的事。手上没有具体错误码的情况下, 常见的嫌疑对象是:
| 原因 | 要检查什么 |
|---|---|
| API key 权限 | key 需要开启交易权限;只读 key 或没开合约交易权限的 key 会让每一笔单都被拒 |
| 数量精度 | 交易所要求下单数量符合该品种的特定步长;原始信号数量没对齐精度就会被拒 |
| 最小下单量 | 每个品种都有最小名义金额或最小数量,小额测试信号经常低于这个门槛 |
| 持仓模式不对 | 账户设成双向持仓(hedge mode),但自动化程序假设是单向持仓(one-way)时,反向/平仓单可能行为异常 |
| 交易所端 IP 白名单 | 如果你在交易所端把 API key 限制到特定 IP,你的自动化服务器 IP 也要在清单上——这跟 TradingView 端的白名单是两回事 |
如果下单成交的名义金额跟你预期不一样,而不是直接被拒单,那通常不是这一层的问题——可以看 qty_type 语义陷阱 这篇,那是另一个非常常见的具体案例。如果怀疑的是 API key 本身,我们的 Binance API key 安全指南 详细列出了该开哪些权限、哪些绝对不要开。
- API key 已开启交易权限(不是只读)
- 下单数量符合该交易所该品种的精度/步长
- 下单量高于该交易所该品种的最小名义金额/数量
- 账户持仓模式(单向 vs 双向)符合自动化程序的假设
- 交易所端 API key 的 IP 限制(如果有设置)已包含你服务器的 IP
如果还是查不出来
把这五层都排查一遍之后,你至少已经把问题缩小到某一侧——TradingView 的 alert 设置、网络路径,或者交易所账户。 光是这样就能把「反正就是不会动」变成一个具体、可以修复的问题。如果需要从零开始的完整设置教程, 可以参考我们的 TradingView webhook 完整教程。
图表上 alert 触发了,但我的服务器什么都没收到,该从哪里查起?
为什么 webhook 用了一段时间之后就突然不动了?
Once Per Bar 和 Once Per Bar Close 到底差在哪?
TradingView 会自动重试发送失败的 webhook 吗?
要怎么测试我的 webhook URL 到底能不能连通?
Get started
TVSBot 把一个正常运作的 TradingView webhook 转成跨 7 家交易所的实时下单——非托管、后台异步处理信号、支持 dry-run 测试,每一笔信号都能在 dashboard 完整重放,清楚看到发生了什么。
免费开始使用