架構分析 · Webhook

TradingView Webhook 到 Telegram
一個 alert 只吃一個 URL,你要在哪一層 fan-out

2026-08-14·12 分鐘閱讀

你在 TradingView 上把 alert 設好了,webhook(也就是把訊號 HTTP POST 到你指定 URL 的那條通道)那格填的是自己交易所的 bot;接著發現只能填一個 URL——你想順便在 Telegram 收一則「進場了、成交價多少」的通知,卻找不到第二格可以填。

這件事沒有人先跟你講:TradingView 的 alert 一次只吃一個 webhook URL。想「TradingView Webhook 同時打進 Telegram 與交易所」就得在中間加一層——不管是你自己寫個 proxy、把 alert 直接指到 Telegram bot(不下單)、還是走一個中間服務把兩件事一起做掉。而中間層要不要真的下單,就牽涉到 API key(也就是授權下單/查詢用的一組金鑰)該由誰來保管。這篇不比較哪個做法比較好,也不評論你的策略。給你三件事:三種 fan-out 位置的取捨順序與去重會踩到什麼坑、以及只推 Telegram、不真下單的觀察期怎麼設。

先講結論:
「TradingView 一次能發到兩個地方」這件事不成立。Fan-out 一定發生在中間層——不是你的伺服器就是別人的伺服器。順序有機制上的正確答案(先確認交易所回單、再發 Telegram),不是憑口味挑;去重要靠中間層做,因為 TradingView 在 5xx 情境會自己重送最多 3 次。

為什麼「同時打到 Telegram 與交易所」不是 TradingView 該做的事

TradingView 的 alert 面板長這樣:條件、名稱、有效期限、通知管道(App、Email、Webhook)。Webhook 那格是一個文字輸入框,不是清單——你只能填一個 URL、一份 payload。這是產品設計,不是 bug。TradingView 選擇把「發到哪」交給你自己決定的一個端點,之後那個端點要怎麼展開,跟它沒關係。

所以「下單同時通知我」這件事,得在 webhook URL 那一頭自己接。訊息裡的「進場了、成交價多少、有沒有失敗」這些欄位,都要等到交易所回單之後才存在——alert 剛觸發那一刻它們還沒有值。fan-out 因此不是「TradingView 一次發兩份」的問題,而是「你在 webhook 收到訊號之後,怎麼在同一段流程裡把下單結果同時送到 Telegram」的問題。這個框錯了,後面的順序、去重、rate limit 都會跟著設錯。

1
TradingView alert 一次能填的 webhook URL 數
3 種
常見的 fan-out 位置(自寫 proxy/直發 TG/中間服務)
3 秒
TradingView 對 webhook 的逾時上限

三個可以放 fan-out 的位置,各自優化什麼

同樣是「下單同時通知我」,中間那層放哪裡差很多。這張表是給你比對用的,不用背——挑一個之後回頭看那一欄的取捨就好。

自己寫 proxyTradingView 直發 Telegram bot(不下單)走中間服務同時做兩件事
誰握你的交易所 API key你自己的伺服器沒人握(只發訊息,不下單)中間服務
誰扛 uptime你自己Telegram + 你的 bot server中間服務
去重誰做要自己寫(記住 dedup key)沒下單所以不會重複下,但訊息會來兩則中間服務內建
順序保證要自己寫(先下單再通知)不下單,沒有順序問題中間服務內建(下單結果為準)
適合誰會寫後端、想全掌握只想看訊號、還在觀察期要真下單但不想維運

第二種「TradingView 直發 Telegram bot」是最被低估的一種——你把 alert 的 webhook URL 直接指向https://api.telegram.org/bot<TOKEN>/sendMessage,在 alert message 裡把訊息內容寫成 chat_idtext 兩個 JSON 欄位,就會收到訊息但完全不下單。適合還在觀察策略準不準、還不敢真下單的階段;缺點是 TradingView 在 5xx 時會重送、你會收到重複訊息(Telegram 的 sendMessage 沒有 idempotency key)。

順序踩雷:先發 Telegram 才下單,就等於誤報成功

這是最容易寫壞的一段。假設你的中間層寫成「先發 Telegram 告訴用戶已收到、再去交易所下單」。訊息會這樣:「已收到訊號 BTCUSDT buy 0.01」。然後你的下單去撞到餘額不足、min notional、或 API key(授權下單/查詢用的一組金鑰)沒開合約權限——任何一個都會讓下單根本沒發生,但用戶已經以為「進場了」。

正確順序是把 Telegram 通知綁到「下單流程的最後一步」——先跑完 pre-checks、送去交易所 API、拿到 fill 或明確的錯誤訊息之後才推 Telegram。這個順序是機制上的正確答案,不是憑口味挑:因為 Telegram 訊息裡的每個欄位都需要下單後才存在(成交價、實際數量、剩餘餘額、失敗原因)。「舉例來說」,TVSBot 執行端的通知就是在 process_signal 跑完之後才進 _send_notificationbackend/app/services/orders.py),訊息裡的成交價、per-key ✓/✗ 結果、失敗時具體錯誤都是從交易所回單後才有的資料。

順序這件事有個例外
「Telegram 收到就代表已下單」這句只在你把訊息綁在下單成功後才成立。若你自己寫的 proxy 選擇先發一則「已收到、處理中」再發第二則「成交結果」,那也可以——只要你在第一則明講「僅代表 alert 收到」。真正錯的是「一則就報完成」但那則其實不知道下單有沒有成功。

去重踩雷:TradingView 會在 5xx 時重送,Telegram 會來兩則

TradingView 的官方 webhook 送達規格是接收端 3 秒內沒回應就取消、不重試;4xx 也不重試;只有 5xx 會等 5 秒後重送,最多 3 次(見我們的另一篇:TradingView Webhook 延遲有多嚴重?官方規格、常見成因與能修好的地方)。這代表:若你的中間層在下單當下遇到交易所短暫回 5xx,又把 5xx 直接透傳回 TradingView,同一個 alert 會被送 2 到 4 次。結果 Telegram 收到 2 到 4 則「成交」訊息,但實際部位只開了 1 個——其他次可能因為交易所自身的 idempotency 或 dedup 而 no-op。

解法是中間層自己做 dedup,不要把重送往下游傳。可用的鍵至少要包含 strategysymbolactionqty,最好加上時間窗(60 秒內同 hash 直接 skip)。同一份設計 TVSBot 執行端在 backend/app/routers/webhook.py 的第 4 步是這樣寫的:payload hash user_id|strategy|symbol|action|qty,60 秒內重複直接不執行。

3 秒
TradingView webhook 逾時上限(超過就取消、不重試)
最多 3 次
5xx 才會重送的次數(總共可能收到 4 份)
60 秒
TVSBot 中間層採用的 dedup 窗口長度

Rate limit 踩雷:Telegram Bot API 有秒級上限

Telegram Bot API 對 sendMessage 有秒級的速率限制——單一 chat 大約 1 條/秒,跨 chat 累計還有另一個上限,超過會回 429 並附 retry_after(實際數字請去 Telegram Bot API 官方 FAQ 那頁查證,他們保留隨時調整的權利)。單人自用大概撞不到,但如果你在跑「一策略多帳戶 fan-out」或「同時通知社群 100 個訂閱者」,就會在某次高頻 alert 上一次撞爆。

這件事會安靜地壞掉:Telegram 只回 429、不會補送,你不主動去看就不會知道有訊息丟了。可行的做法:在中間層加一個訊息佇列,超過秒級上限就往後排、記錄丟過幾則。或更務實地:把 Telegram 通知從「每筆訂單一則」改成「每小時彙整一則」,散戶自用完全夠。

只推 Telegram、不真下單的觀察期:dry-run 是給這件事用的

一個常被忽略的用法:把 Telegram 當「策略試跑板」。你想看新策略在真實市場上會發多少訊號、什麼時間、方向對不對——但還不敢接真錢。這時候你不是要「同時通知 + 下單」,你要的是「只通知,不下單」。

兩種做法都行。第一種:TradingView alert 直接指向 Telegram Bot API 的 sendMessage,中間不放任何下單邏輯。缺點如上一節寫的——重送與 rate limit 都由你自己扛,而且訊息裡沒有「這個訊號真的能被交易所吃嗎」的驗證(min notional、槓桿設定、可用餘額都沒查)。第二種:走中間服務但設成 dry-run。「舉例來說」,TVSBot 的每個策略有 dry_run 開關,開了之後訊號會走完整個 pre-check + 假下單流程、把「這筆理論上會下 0.03 BTC,模擬成交價 65,432」寫進 Telegram 通知,但完全不打到交易所——訂閱守門也會放行讓沒付費的用戶也能試(backend/app/services/orders.pyforce_dry_run 與策略層的 dry_run 兩處都指向同一段邏輯)。

1
你想「同時打到 Telegram 與交易所」的真正目的是什麼?
還在觀察策略,還不敢下真錢alert 直發 Telegram bot(不下單)或中間服務開 dry-run,兩種都不會動到交易所
已經想接真錢,只是要有通知把通知放在下單流程的最後一步,順序才對;去重與 rate limit 交給中間層
策略是要賣給訂閱者、要一次發很多人Telegram Bot API 的秒級上限一定會撞到,需要佇列或彙整;一次通知很多人跟一次通知你自己是不同架構

你不用真的自己寫 proxy——只要看得懂它在做哪四件事

你要不要自己寫這個中間層是取捨題。看清楚它在做什麼、再決定要不要接手就好。任何做「TradingView → Telegram + 交易所」fan-out 的中間層都會處理下面這四層。列出來給你當檢查表——你自己寫、還是選中間服務,都是看它有沒有把這四件事處理完。

  • 驗身分。Webhook URL 全世界都能打,一定要在 URL 或 payload 帶一組長 token 驗證。用 hmac.compare_digest 這種常數時間比對——直接 == 會被 timing attack 逐字元反推。
  • 限流。per-token 與 per-IP 各一個上限,攻擊者知道你的 URL 也不能把中間層打掛。
  • 去重。strategy + symbol + action + qty 算 hash,60 秒窗口內重複的訊號直接 skip。這一步擋掉 TradingView 5xx 重送與人為 replay。
  • 先下單、後通知。Telegram 訊息一定綁在下單流程的最後一步——這樣訊息裡的成交價、失敗原因才會是真的,而不是「我以為」。

誠實的一段:Telegram 不能當你的 kill switch

這一段是我們自己做過會後悔的:把 Telegram 當唯一的通知管道。Telegram 不保證即時、不保證送達、你也不會收到「這則訊息丟了」的通知——Telegram 沒有這個機制。任何自動化交易架構都保證不了 100% 送達——包括我們自己。如果你打算靠 Telegram 通知在下單失敗時「趕快去補救」,那條依賴是脆的:你可能因為手機沒訊號、Telegram 通知被系統批次靜音、或訊息本身在中間層 rate-limit 掉,就錯過整整一次事件。

真的要有可以在半夜叫醒你的通知,走 SMS 或電話輪詢(PagerDuty、Opsgenie 這類),不要押在 IM 上。Telegram 適合「事後對帳」與「例行通知」,不適合「異常必須被看到」的用途。反過來,這也代表 kill switch 這種真的要能立刻停單的按鈕不能只放在 Telegram bot 裡——它一定要有一個 web dashboard 版本,你手機 App 或朋友的電腦都能點得到。

常見問題

為什麼還要 fan-out?TradingView alert 不能一次送到多個地方嗎?
TradingView 的 alert 一次只吃一個 webhook URL,那格是文字輸入框、不是清單, 你能填的就是一個 URL、一份 payload。 要在同一次訊號裡把訊息送到 Telegram、也送到交易所, 只能由 webhook 那頭的中間層完成——這篇整個都在講那一層怎麼設計。
把 TradingView alert 的 webhook URL 直接指到 Telegram Bot API,這樣算作弊嗎?
完全不算,這是很多人第一步就這樣做的用法。 唯一要注意的是:TradingView 對 5xx 會重送最多 3 次, Telegram sendMessage 若在你重送期間偶爾回 5xx,你會收到 2 到 4 則相同訊息。 單人自用可以忍,要通知很多人就得在中間加一個能去重的 proxy。
如果我先發 Telegram「已收到訊號」再下單,會怎樣?
Telegram 訊息會誤報成功。用戶收到「已收到」之後假設「成交了」, 但你的下單可能撞到餘額不足、min notional、API key 權限不對,其中任何一個都會讓下單根本沒發生。正確做法是把 Telegram 綁在下單流程的最後一步—— 拿到交易所回單或明確錯誤訊息之後才推。或明講「僅代表 alert 收到」, 但那就是兩則訊息的架構了。
Telegram Bot API 的 rate limit 我怎麼知道自己會不會撞到?
單人自用(一策略一帳戶)基本上不會撞到;會撞的是「一策略多訂閱者」或「同時通知一個社群」的場景, 高頻 alert 一次會爆。 在中間層加訊息佇列或改成「每小時彙整一則」都可以, 具體秒級上限請以 Telegram Bot API 官方 FAQ 當下版本為準——這個數字他們保留隨時調整。
我要用 TVSBot 的話,Telegram 通知還要自己設嗎?
不用。你在 dashboard 拿一組綁定 code,到 Telegram 對 bot 發/start <code>就綁好, 之後下單結果會自動推。也支援 /balance/positions/status三個查詢指令(見backend/app/services/telegram.py)。 Kill switch 還是要在 web dashboard 上按, 不是靠 Telegram——這是上一節那段誠實話的落地。

Get started

想把今天學到的東西自動化跑起來?

把 TradingView alert 指過來,下單同時把成交結果推到你的 Telegram——TVSBot 用你自己的 API key、內建 60 秒去重、先下單再通知、支援 dry-run 觀察期。

免費開始使用