TradingView 到幣安自動下單:alert 到成交完整流程
把 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 驗證訊號,再上實盤。
免費開始使用