故障排查 · Webhook

TradingView Webhook 不触发怎么办?
完整调试流程图,一层一层排查

2026-07-08·9 分钟

Alert 设好了,图表上条件明明已经满足,结果下游什么反应都没有——或者有反应,但交易所没有真的下单。TradingView webhook 不触发这个问题可能卡在五个不同的环节,瞎猜是哪一层只会白白浪费好几个小时。

这篇文章是一套分层排查流程:套餐够不够格、Alert 到底有没有触发、TradingView 有没有真的发出去、你的服务器有没有真的收到、 交易所有没有真的接受下单。从最上面开始一层一层查——大部分人其实卡在第 0 层或第 1 层,只是自己还没意识到。

多数人卡住的地方,其实是最后才想到查的
实际情况里,两个最常见的卡点,反而是大家最后才会想到去查的:Alert 过期(第 0 层)、触发频率设置搞混(第 1 层)。 这两种问题从表面看起来一模一样——「我设好了,它就是不触发」——但其实跟你的服务器、跟交易所账户完全无关。

五层排查流程

从上到下照着走,每一步都会告诉你要继续往下查,还是问题已经找到了。

1
第 0a 层——你的 TradingView 套餐本身有没有 webhook 功能?
免费(Basic)套餐 →Basic 套餐完全不提供 webhook 通知功能——这不是 bug,是套餐本身就没有这个功能。需要升级到 Essential 以上。
Essential / Plus / Premium / Ultimate 套餐 →你的套餐有 webhook 功能,继续下一项检查。
2
第 0b 层——Alert Manager 里这个 alert 的状态显示什么?
红色「Stopped — Expired」 →Alert 有存活期限上限(默认 2 个月,Premium/Ultimate 可以开启永不过期选项)。过期的 alert 就是停了——直接删除重建,编辑一个已过期的 alert 没办法让它复活。
绿色「Active」 →继续下一项检查。
3
第 1 层——图表上条件明明满足,但 Alert Manager 完全没有任何触发记录?
从来没触发过 →先检查 Frequency 设置和 repainting 问题——碰其他任何东西之前先看下面第 1 层的说明。
至少触发过一次(去查记录) →Alert 本身运作正常,继续往下查发送这一层。
4
第 2 层——这个 alert 有没有出现 webhook 发送错误提示?
有错误提示 →直接看错误文字内容,通常会直接写出原因(端口不对、私有 IP、非 HTTPS、消息过大)。见下方第 2 层检查清单。
没有错误提示 →TradingView 那端没有标示任何失败,问题比较可能在你的服务器或网络端。
5
第 3 层——从外部能不能连到你自己的 webhook URL?
从另一台机器用 curl 完全连不上 →这是网络问题,不是 TradingView 的问题——防火墙、隧道挂了、端口错、DNS 没配好,先修这个。
curl 能打通,但 TradingView 发来的 request 就是收不到 →很可能是 IP 白名单挡住了 TradingView 的来源 IP,或者服务器响应超过 3 秒被 TradingView 判定超时取消。
服务器日志显示 request 进来了并回了 200 →送达这一段全程确认无误,剩下的问题出在交易所那一端。
6
第 4 层——服务器收到信号了,但交易所端没有出现任何下单
交易所拒单或者悄悄忽略 →检查 API key 交易权限、数量精度/步长、最小下单量、持仓模式(单向 vs 双向)——见下方第 4 层说明。
3 秒
服务器必须在此时限内响应
80 / 443
仅接受这两个端口
2 个月
Alert 默认存活上限
15 次 / 3 分钟
超过就自动停用

第 0 层——这个 alert 本身有没有资格发 webhook?

在动你的服务器或 Pine 脚本之前,先确认这个 alert 在结构上根本就有能力发 webhook。这里有两道独立的关卡, 任何一道卡住都足以解释「怎么设都没反应」。

套餐资格

Webhook 通知功能是按订阅套餐分级的。免费的 Basic 套餐完全没有 webhook 通知功能——不是被限制, 是这个功能本身就不存在于这个套餐里。截至 2026 年 7 月查证,TradingView 的套餐对比表如下:

套餐WebhookPrice + Technical alert 数Alert 存活期限
Basic(免费)无3 + 01 个月
Essential有20 + 202 个月
Plus有100 + 1002 个月
Premium有400 + 400(另加 2 个 watchlist)可开启永不过期
Ultimate有1,000 + 1,000(另加 15 个 watchlist)可开启永不过期

TradingView 套餐对比表,截至 2026 年 7 月查证,实际数字请以 tradingview.com/pricing 当下显示为准。

还有一道独立的账户层面关卡
Webhook alert 还需要你的 TradingView 账户开启两步验证(2FA)——这跟套餐高低是两回事。 Basic 套餐开了 2FA 也不会因此解锁 webhook(因为这个功能套餐本身就不提供),但在付费套餐上, 忘记开 2FA 会是另一个让 webhook alert 被挡住的独立原因。

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 月查证:

text
52.89.214.238
34.212.75.30
54.218.53.128
52.32.178.7
不要把这份清单当成永久不变
TradingView 并没有公开承诺这 4 个 IP 永远不会改变。更稳妥的做法是验证 TradingView 每次 HTTPS webhook request 附带的 SSL 证书,证书上的 CN = webhook-server@tradingview.com 可以确认请求来源。 如果你的框架能检查客户端证书,这会比写死 IP 更可靠。

URL 指向 localhost 或任何私有/内部 IP,是官方明确记载的失败案例——TradingView 的服务器 没办法直接连到你的电脑。本地开发阶段需要用公网隧道(比如 ngrok)架在服务器前面。

实际怎么测试

先直接打你自己的接口,把「我的服务器到底有没有在监听」和「TradingView 的 request 有没有送到」这两件事分开验证:

bash
curl -X POST https://api.tvsbot.com/webhook/<your-webhook-token> \
  -H "Content-Type: application/json" \
  -d '{"secret":"INVALID-SECRET-DO-NOT-USE","strategy":"<TVSBot 策略名称>","action":"buy","symbol":"BTCUSDT","exchange":"binance","market_type":"futures","qty_type":"margin_usdt","qty":10}'

上面以 TVSBot 的 webhook 为例(网址最后一段是策略页的 webhook token;自建接收端就换成你自己的 URL 和 payload)。 secret 是故意填的无效值,所以这条 curl 只测「连得到、认得 token、payload 合法」,不会下单;请不要换成你真的 secret 来测。 真正的 webhook secret 只在 TradingView 的 alert 窗口填,不要写进 Pine 源代码,也不要贴到公开的地方。

看响应就知道卡在哪一层(TVSBot 先验 payload 格式、再比 secret,所以格式错时会先看到 400):

curl 结果代表什么
401,内容是「secret 錯誤」最理想:路由通了、token 找得到、payload 格式合法;secret 是故意填错的,所以没有执行任何下单。(响应里的文字就是繁体的「secret 錯誤」)
401,内容是「invalid webhook token」网址最后一段的 webhook token 不对(复制错,或已经重新生成)。
400payload 格式不对:不是合法 JSON,或缺必填字段、字段值不合法;响应里的 issues 会列出前几个出错的字段。
429请求太频繁被限流,等 Retry-After 秒后再试。
连不上/超时网络或防火墙问题,跟 TradingView 完全无关。

能拿到 401「secret 錯誤」说明你的服务器没问题,问题在上游(IP 白名单、超时,或者 TradingView 那端)。

  • 服务器在远低于 3 秒的时间内响应(任何状态码都可以)——重的工作放在响应之后,不是之前
  • 防火墙或安全组允许 TradingView 来源 IP 的入站流量,或者改用 SSL 证书验证取代 IP 白名单
  • Webhook URL 指向公网地址,不是 localhost 或私有 IP
  • 直接对自己接口的 curl 测试很快有响应(自建接口返回 200;打 TVSBot 并故意带无效 secret 则是 401)

第 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 安全指南 详细列出了该开哪些权限、哪些绝对不要开。

TVSBot 怎么帮你把问题定位出来
TVSBot 收到 webhook 会立刻响应,实际下单逻辑改成后台异步处理,就是为了避免交易所端较慢的往返 拖到 TradingView 的 3 秒超时。每一笔信号——原始 payload、处理日志、交易所响应——都会被记录下来 并可以在 dashboard 上重放,让你直接看到某笔信号卡在哪一层,而不用靠猜。Dry-run 模式可以让你 在真正动用资金之前,用模拟成交把整条链路先测一遍。
  • API key 已开启交易权限(不是只读)
  • 下单数量符合该交易所该品种的精度/步长
  • 下单量高于该交易所该品种的最小名义金额/数量
  • 账户持仓模式(单向 vs 双向)符合自动化程序的假设
  • 交易所端 API key 的 IP 限制(如果有设置)已包含你服务器的 IP

如果还是查不出来

把这五层都排查一遍之后,你至少已经把问题缩小到某一侧——TradingView 的 alert 设置、网络路径,或者交易所账户。 光是这样就能把「反正就是不会动」变成一个具体、可以修复的问题。如果需要从零开始的完整设置教程, 可以参考我们的 TradingView webhook 完整教程。

图表上 alert 触发了,但我的服务器什么都没收到,该从哪里查起?
先从第 2 层开始:检查这个 alert 有没有出现 webhook 发送错误提示。 如果显示没有错误,再到第 3 层用 curl 直接测试你的接口,确认 request 到底有没有送到你的服务器。
为什么 webhook 用了一段时间之后就突然不动了?
先检查 Alert Manager 有没有显示红色Stopped — Expired状态。Alert 默认最长存活 两个月(只有 Premium 和 Ultimate 能开启永不过期),另外还有一条规则会自动停用超过一年没触发、 也没被编辑过的 alert。
Once Per Bar 和 Once Per Bar Close 到底差在哪?
Once Per Bar 一满足条件就马上触发,不等 K 线结束——这让它容易受 repainting 影响, 因为脚本数值在 K 线收盘前可能还会变动。Once Per Bar Close 会等 K 线真的收盘才触发, 对大多数交易逻辑来说是更安全的默认选择。
TradingView 会自动重试发送失败的 webhook 吗?
只有 5xx 服务器错误才会重试——5 秒后重发,最多重发 3 次(总共最多 4 次)。4xx 响应或超时都会 被视为已送达,完全不会重试,所以响应慢的接口可能会悄悄漏掉信号。
要怎么测试我的 webhook URL 到底能不能连通?
从外部机器用 curl,按 TradingView 会发送的方式和 payload 结构直接打过去。 如果 curl 很快拿到响应(自建接口是 200;打 TVSBot 并故意带无效 secret 则是 401),你的服务器没问题,剩下的问题在上游——IP 白名单、超时, 或者 TradingView 那端的 alert 设置。

Get started

想把今天学到的东西自动化跑起来?

TVSBot 把一个正常运作的 TradingView webhook 转成跨 7 家交易所的实时下单——非托管、后台异步处理信号、支持 dry-run 测试,每一笔信号都能在 dashboard 完整重放,清楚看到发生了什么。

免费开始使用