TradingView 接 Binance 自動下單:五關排錯指南
将 TradingView 信号接入 Binance(TradingView to Binance)自动下单,alert 触发了、webhook(即 TradingView 触发 alert 时向一个网址 POST 数据的机制)也发了,账户却没动静。问题大多不在两头——我们已经检查过 alert 和 API key(交易所用来验证你身份的密钥),而在中间那段链路:频率、payload、身份验证、错误码、成交回报,五关任何一关漏掉,下单都会静默消失。这篇把每一关的设置和「错误去哪看」一次讲清楚。本文不涵盖 Pine Script(即 TradingView 的策略编程语言)怎么写、API key 怎么申请,以及 OKX、Bitget、Bybit 的拒单细节。
关卡 1:TradingView alert webhook 频率——三个接口不共用选项
TradingView 有三个地方可以控制 alert 频率:Create Alert 对话框、Pine Script(TradingView 的策略编程语言)的 alertcondition()、Pine Script 的 alert()。三者的选项名称和默认值互不相通,混用是「alert 看起来有在跑、信号却比预期少」的第一嫌疑。
UI 下拉菜单有四个选项:Once only(只触发一次)、Once per bar(每根 K 线触发)、Once per bar close(收线时触发)、Once per minute or every time(每分钟或每次触发)。Pine 的 alert() 用三个常量当 freq 参数:alert.freq_all、alert.freq_once_per_bar、alert.freq_once_per_bar_close;alertcondition() 没有频率参数,只在收线时最多触发一次。
最容易忽略的是默认值:alert() 若没带 freq 参数,代码层面的默认是 alert.freq_once_per_bar——不是「每次都送」。同一个策略,UI 建的 alert 和 Pine 建的 alert,频率行为可以完全不同。我们建议排错时先确认你的 alert 是在哪个接口建的。
| 接口 | 频率选项 | 默认/限制 |
|---|---|---|
| Create Alert UI | Once only / Once per bar / Once per bar close / Once per minute or every time | 依你选的选项 |
| Pine alertcondition() | 无频率参数 | 只在收线触发,每次收线最多一次 |
| Pine alert() | freq_all / freq_once_per_bar / freq_once_per_bar_close | 未带 freq 时默认 freq_once_per_bar |
TradingView Help Center(Alerts)与 Pine Script Reference(alert()、alertcondition())。查证日期 2026 年 10 月。
关卡 2:webhook payload——TVSBot 读的字段
webhook 就是 TradingView 触发 alert 时向一个网址 POST 一笔数据的机制。TVSBot 给每个用户一条专属 URL:/webhook/{user_webhook_token},token 是注册后产生的随机字符串;payload(送出去的 JSON)里还要再带一个 secret 字段做第二层验证,两层缺一,交易所会直接挡住请求。
TradingView alert 设定里的 message 字段,就是你送出的 JSON 原文。TVSBot 读取的必填字段:
| 字段 | 取值/意思 |
|---|---|
| secret | 第二层验证,跟 URL token 配对 |
| strategy | 策略槽位名称 |
| action | buy / sell / close |
| symbol | BTCUSDT——没有底线 |
| exchange | binance / okx / bitget / bybit |
| market_type | spot / futures |
| order_type | market / limit |
| qty_type | usdt / margin_usdt / base(语见下一段) |
| qty | 数量 |
TVSBot 读取的必填字段。查证日期 2026-10-14。
qty_type 有五种:fixed、usdt、percent、margin_pct、margin_usdt。最容易搞错的是 usdt 和 margin_usdt——同样写 qty: 20,一个是 $20 的仓位,一个是 $20 保证金再乘杠杆。完整拆解在这篇 qty_type 陷阱。
可选字段里两个要注意:spot 单会忽略 leverage;futures 的 margin_mode 默认 cross。把 sl_pct / tp_pct 放进 payload,止损止盈会挂在交易所端——关卡 5 会讲为什么这很重要。
| 字段 | 取值 | 说明 |
|---|---|---|
| secret | 字符串 | 第二层验证,与 URL token 同时比对 |
| strategy | 字符串 | TVSBot 策略槽位名称 |
| action | buy / sell / close | 信号方向 |
| symbol | BTCUSDT(无底线) | 交易对 |
| exchange | binance / okx / bitget / bybit | 目标交易所 |
| market_type | spot / futures | 现货或合约 |
| order_type | market / limit | 市价或限价 |
| qty_type + qty | fixed / usdt / percent / margin_pct / margin_usdt | 下单数量语义,见正文 |
| leverage | 1–125 | futures 用;spot 忽略;超风控上限自动降 |
| sl_pct / tp_pct | 0.1–50 | 交易所端止损/止盈百分比 |
TVSBot 官方文件(webhook payload 规格)与数据库 migration。查证日期 2026-10-14。
关卡 3:401 与 400——身份验证和 schema 的第一道拦截
请求送进 TVSBot 之后,第一关是双重验证:URL token 加 payload secret,两层都要对。secret 错回 401;payload 缺字段或类型错回 400,而且会附上详细错误——这是最常见的「静默失败」,很多人只看 HTTP 有没有 200,没看响应体。如果连 401 都收不到(alert 根本没送出去),先走webhook 没反应那篇的排错流程,再回来对这关。
通过验证和 schema 之后,TVSBot 回 200 加 queued——意思是「收下进队列」,不是「下单成功」。真正的下单结果在 Telegram 通知和 dashboard,不在 HTTP 响应里。
我们发现另外两个是设计行为,不是 bug:每个用户的 webhook 有 QPS(每秒请求数)上限——根据 TVSBot 后端代码,默认是每 60 秒 60 次(相当于每秒 1 次),这是 per-token 的限制;同时还有 per-IP 限制,每 30 秒 30 次。同一组 strategy、symbol、action 在 60 秒内重复送,TVSBot 会当成重送丢掉。所以「连发两次只开一单」是正常的。
{
"secret": "...",
"strategy": "BTC突破",
"action": "buy",
"symbol": "BTCUSDT",
"exchange": "binance",
"market_type": "futures",
"order_type": "market",
"qty_type": "margin_usdt",
"qty": 20,
"leverage": 3,
"sl_pct": 2,
"tp_pct": 4
}
送出之后的三种结果:
- secret 错 → HTTP 401
- 字段缺或类型错 → HTTP 400(附详细错误)
- 通过验证 → HTTP 200:
{"received": true, "queued": true, "message": "..."}
关卡 4:Binance 拒单——错误码在说什么
TVSBot 收下了、队列也排完了,Binance 还是可以拒你的单。我们建议第一嫌疑先看 API key 权限:-2015 的官方消息原文是 Invalid API-key, IP, or permissions for action——key 没勾 Spot/Futures Trading 权限、或 IP 白名单没放行你的 server,都会撞这个码。API key 怎么勾权限、IP 白名单怎么放,这篇拆得很细,这里不重复。
第二嫌疑是 symbol 的过滤器:Binance 官方 API 文件列出 LOT_SIZE、MIN_NOTIONAL、PRICE_FILTER 三种 order validation filter(即交易所对每张表的量精度、最低名义价值、价格精度规则)。qty 精度不对、名义价值太低、价格位数错,交易所都会拒;具体错误码以回传的 msg 为准,官方文件没有把每个 filter 绑死一个固定码。
| 错误码/消息 | 意思 | 处理 |
|---|---|---|
| -2015 Invalid API-key, IP, or permissions for action | key 权限不足或 IP 白名单没放行 | 检查 key 勾了交易权限、IP 白名单包含 TVSBot server |
| LOT_SIZE / MIN_NOTIONAL / PRICE_FILTER 拒单 | qty 精度、最低名义价值、价格精度不符该 symbol 规则 | 照交易所回传的 msg,对该 symbol 的 filter 参数调整 qty 与价格 |
Binance 官方 API 文件(error codes 与 order validation filters 章节)。查证日期 2026 年 10 月;-2015 为官方原文,filter 类错误以交易所回传 msg 为准。
关卡 5:200 加 queued 不是成交——成交回报在哪看
再讲一次:HTTP 200 加 queued 只表示 TVSBot 收下这笔信号进队列。下单成功、部分成交、被拒、失败,这四种状态(filled、partial、rejected、failed)在 Telegram 通知和 dashboard 才看得到。
Signals 页面每一笔信号都有 processing_log(即这笔信号从收到 webhook 到下单结果的逐步记录)。排错时先打开它,比猜快。
futures 还有一个默认行为要知道:TVSBot 假设你的 Binance 账户是 One-way Mode(单向持仓模式,同一时间一个方向一个仓位)。如果你的账户开在 Hedge mode(双向持仓),Binance 会拒掉信号——不是 payload 的错,是账户设定跟默认不符。两种模式差在哪,这篇有讲。
| 状态 | 意思 | 在哪看 |
|---|---|---|
| filled | 完全成交 | Telegram 通知、Signals 页面 |
| partial | 部分成交 | 同上,processing_log 有细节 |
| rejected | 被交易所或 TVSBot 规则拒单 | processing_log 记了拒单原因 |
| failed | 下单流程失败 | processing_log 记了失败步骤 |
TVSBot 后端与 dashboard 代码(signals 路由与策略页)。查证日期 2026-10-14。
TVSBot 不做的事
两件事我们先讲清楚,免得你把期待放错地方。第一,Pine 端的止盈止损只在你 TradingView 还在跑、alert 还在触发时有效——TradingView 断线或 alert 没触发,Pine 端不会替你平仓。
第二,200 加 queued 是「收下」不是「成交」,最终成交以交易所为准;被拒的单就是被拒了,状态会完整记在 processing_log,不会自动重试到成功为止。
TradingView to Binance 五关卡排错清单
信号没到账户时,照顺序从上往下查。每一行的「去哪看」就是该关卡的排错入口。
| 关卡 | 典型症状 | 去哪看 |
|---|---|---|
| 1 alert 频率 | alert 有跑但信号比预期少 | TradingView alert 设定(UI 选项或 Pine freq) |
| 2 payload 字段 | 400 加详细错误 | HTTP 响应体的错误字段 |
| 3 身份验证 | 401,或重送被丢 | URL token 与 secret、60 秒去重窗口 |
| 4 Binance 拒单 | 200 queued 后订单被拒 | -2015 权限问题、filter 的 msg |
| 5 成交回报 | queued 但状态不是 filled | Telegram 通知、Signals 页 processing_log |
本文五关卡的排错路径对照。
常见问题
webhook 回 200 了,为什么账户没动?
URL token 和 secret 的差别是什么?
同一个信号 60 秒内送了两次,会开两单吗?
futures 单一直被拒,payload 看起来也没错?
TradingView 断线时,止损还在吗?
Get started
TVSBot 用你自己的 API key 接 TradingView alert 到 Binance,先 dry-run 验证信号,再上实盘。
免费开始使用