教學 新手

Webhook 入門教學:即時接收交易訊號與市場數據完整指南|2026

Sentinel Team · 2026-03-06
Webhook 入門教學:即時接收交易訊號與市場數據完整指南|2026

Webhook 入門教學:即時接收交易訊號與市場數據完整指南|2026

核心關鍵字: Webhook、交易訊號、Flask、HMAC 驗證、即時數據、TradingView、事件驅動

快速導覽: Webhook 原理 | Flask 實作 | 安全性強化 | TradingView 整合 | 常見問題


每秒問 100 次?這就是 Polling 的悲劇

想像一下,你是個交易員,想知道某個幣種的價格變動。你會怎麼做?

方法 A(Polling): 每 5 秒打開交易所 App 刷新一次。一天 86,400 秒,你刷新了 17,280 次。但實際上價格只變動了 50 次。你浪費了 99.7% 的請求。

方法 B(Webhook): 交易所「有事才通知你」。價格變動時,你的手機響一聲。精準、即時、零浪費。

這就是 Webhook 的魅力——事件驅動,而非輪詢驅動


Webhook 是什麼?郵差比喻

Webhook 就像一位聰明的郵差

| 傳統 API(Polling) | Webhook |

|:---|:---|

| 你每天去郵局問:「有我的信嗎?」 | 郵差直接把信送到你家門口 |

| 沒信也要跑一趟 | 有信才來,沒信不來 |

| 你負責主動詢問 | 對方負責主動推送 |

在交易場景中:


Webhook vs API 輪詢:數據對決

| 比較項目 | API 輪詢 | Webhook |

|:---|:---|:---|

| 延遲 | 取決於輪詢頻率(5秒~5分鐘) | 即時(毫秒級) |

| 伺服器負載 | 高(大量無效請求) | 低(僅事件發生時) |

| 複雜度 | 需管理輪詢邏輯、頻率、錯誤重試 | 需設定接收端點、驗證安全性 |

| 可靠性 | 可能錯過短暫事件 | 可能遺失(需重試機制) |

| 適用場景 | 歷史數據查詢、非即時需求 | 即時交易、價格警報、訂單狀態 |

交易場景的真實成本

假設你管理 100 個交易對,每秒輪詢一次:

API 輪詢:100 對 × 60 秒 × 60 分 × 24 小時 = 864 萬次請求/天
Webhook:僅在價格變動時觸發,可能只需 1 萬次

成本差異:864 倍。


實作範例:Flask 接收交易訊號

以下是一個完整的 Python Flask 伺服器,接收來自交易所的 Webhook 交易訊號:

from flask import Flask, request, jsonify
import json
from datetime import datetime

app = Flask(__name__)

@app.route('/webhook/trading-signal', methods=['POST'])
def receive_trading_signal():
    """
    接收交易訊號 Webhook
    
    預期 Payload 格式:
    {
        "symbol": "BTCUSDT",           # 交易對
        "signal": "BUY",               # 訊號類型:BUY 或 SELL
        "price": 45000.50,             # 觸發價格
        "timestamp": "2024-01-15T10:30:00Z",  # 訊號產生時間
        "source": "TradingView",       # 訊號來源
        "strategy": "Golden_Cross",    # 策略名稱(選填)
        "timeframe": "1h"              # 時間週期(選填)
    }
    
    回傳格式:
    {
        "status": "success",
        "message": "Signal received",
        "received_at": "2024-01-15T10:30:01Z"
    }
    """
    try:
        # 解析 JSON 資料
        data = request.get_json()
        
        # 記錄接收時間
        received_at = datetime.utcnow().isoformat()
        
        # 提取關鍵資訊
        symbol = data.get('symbol')
        signal = data.get('signal')
        price = data.get('price')
        source = data.get('source')
        
        # 驗證必要欄位
        if not all([symbol, signal, price]):
            return jsonify({
                "status": "error",
                "message": "Missing required fields: symbol, signal, price"
            }), 400
        
        # 記錄接收到的訊號
        print(f"[{received_at}] 收到來自 {source} 的訊號:")
        print(f"  交易對: {symbol}")
        print(f"  訊號: {signal}")
        print(f"  價格: {price}")
        
        # 這裡可以整合你的交易策略
        # 例如:呼叫交易所 API 執行下單
        # execute_trade(symbol, signal, price)
        
        return jsonify({
            "status": "success",
            "message": "Signal received and processed",
            "received_at": received_at
        }), 200
        
    except Exception as e:
        print(f"處理 Webhook 時發生錯誤: {str(e)}")
        return jsonify({
            "status": "error",
            "message": str(e)
        }), 400

if __name__ == '__main__':
    # ⚠️ 生產環境請使用 HTTPS 並設定適當的 host/port
    # 建議使用 Gunicorn + Nginx 部署
    app.run(host='0.0.0.0', port=5000, debug=False)

本地測試與部署

本地測試(使用 ngrok):

# 安裝 ngrok
pip install pyngrok

# 啟動 Flask 伺服器
python webhook_server.py

# 另開終端機,暴露本地端口
ngrok http 5000

# 取得公開 URL,例如:https://abc123.ngrok.io/webhook/trading-signal

生產環境部署檢查清單:


🔒 Webhook 安全性強化

警告:未經保護的 Webhook 端點是重大安全漏洞!

Webhook 最大的風險是偽造請求。任何人知道你的 URL 就能發送假訊號,可能導致:

安全威脅與防護措施

| 威脅類型 | 攻擊方式 | 防護措施 |

|----------|----------|----------|

| 偽造請求 | 攻擊者猜測或洩漏 URL | HMAC 簽名驗證 |

| 中間人攻擊 | 攔截並修改請求內容 | 強制 HTTPS/TLS |

| 重放攻擊 | 重複發送舊的合法請求 | 時間戳驗證 + Nonce |

| DDoS 攻擊 | 大量請求癱瘓服務 | 速率限制、IP 白名單 |

| 資訊洩漏 | 請求內容被竊聽 | 請求加密、敏感資料脫敏 |

原理:HMAC 簽名驗證

  1. 發送方用密鑰對 Payload 生成簽名
  2. 接收方用相同密鑰驗證簽名
  3. 簽名不符 → 拒絕請求

實作範例:安全的 Webhook 接收

import hmac
import hashlib
import time
from flask import Flask, request, jsonify

app = Flask(__name__)

# ========== 安全設定 ==========
# ⚠️ 生產環境請使用強密碼並儲存在環境變數
WEBHOOK_SECRET = "your-webhook-secret-key-here"  # 與發送方共享的密鑰
ALLOWED_IPS = ['123.45.67.89', '98.76.54.32']    # 發送方 IP 白名單
MAX_TIMESTAMP_DIFF = 300                          # 時間戳最大差異(5分鐘)

def verify_signature(payload_body, signature):
    """
    驗證 HMAC-SHA256 簽名
    
    使用 hmac.compare_digest 防止時序攻擊(Timing Attack)
    這種攻擊透過測量比較時間來猜測簽名內容
    
    參數:
        payload_body: 原始請求 body(bytes)
        signature: 請求標頭中的簽名
    
    回傳:
        True 如果簽名有效,False 否則
    """
    expected_signature = hmac.new(
        WEBHOOK_SECRET.encode('utf-8'),
        payload_body,
        hashlib.sha256
    ).hexdigest()
    
    # 防止時序攻擊:使用常數時間比較
    return hmac.compare_digest(f"sha256={expected_signature}", signature)

def verify_timestamp(timestamp_str):
    """
    驗證時間戳,防止重放攻擊
    
    參數:
        timestamp_str: Unix 時間戳字串
    
    回傳:
        True 如果時間戳在有效範圍內
    """
    try:
        request_time = int(timestamp_str)
        current_time = int(time.time())
        time_diff = abs(current_time - request_time)
        
        return time_diff <= MAX_TIMESTAMP_DIFF
    except ValueError:
        return False

def verify_ip(client_ip):
    """
    驗證請求來源 IP
    
    參數:
        client_ip: 客戶端 IP 位址
    """
    return client_ip in ALLOWED_IPS

@app.route('/webhook/secure-signal', methods=['POST'])
def receive_secure_signal():
    """
    安全接收交易訊號 Webhook
    
    驗證流程:
        1. IP 白名單檢查
        2. 時間戳驗證(防重放)
        3. HMAC 簽名驗證
        4. 處理請求
    """
    # 1. IP 白名單檢查
    client_ip = request.remote_addr
    if not verify_ip(client_ip):
        return jsonify({"error": "Unauthorized IP"}), 403
    
    # 2. 時間戳驗證
    timestamp = request.headers.get('X-Webhook-Timestamp')
    if not timestamp or not verify_timestamp(timestamp):
        return jsonify({"error": "Invalid or expired timestamp"}), 401
    
    # 3. 簽名驗證
    signature = request.headers.get('X-Webhook-Signature')
    if not signature:
        return jsonify({"error": "Missing signature"}), 401
    
    # 取得原始 body(尚未解析 JSON)
    payload_body = request.get_data()
    
    if not verify_signature(payload_body, signature):
        # 記錄可疑請求
        app.logger.warning(f"Invalid signature from IP: {client_ip}")
        return jsonify({"error": "Invalid signature"}), 401
    
    # 4. 驗證通過,處理資料
    data = request.get_json()
    app.logger.info(f"Valid webhook received: {data}")
    
    # 執行交易邏輯...
    # execute_trade(data)
    
    return jsonify({
        "status": "success",
        "message": "Signal processed"
    }), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, ssl_context='adhoc')  # 啟用 HTTPS

其他安全措施

| 措施 | 說明 | 實作建議 |

|:---|:---|:---|

| HTTPS 強制 | 所有 Webhook 必須使用 TLS 加密 | 使用 Let's Encrypt 免費憑證 |

| IP 白名單 | 只接受來自已知發送方的 IP | 在防火牆層級設定 |

| 速率限制 | 限制單一來源的請求頻率 | Flask-Limiter 套件 |

| 請求日誌 | 記錄所有請求便於稽核 | 使用結構化日誌(JSON) |

| 自動封鎖 | 多次失敗後暫時封鎖 IP | 使用 fail2ban 或類似工具 |

進階安全:使用 mTLS

對於極高安全性需求,可實作雙向 TLS(mTLS):

from flask import Flask
import ssl

app = Flask(__name__)

# 設定 mTLS
context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
context.load_cert_chain('server.crt', 'server.key')
context.load_verify_locations('ca.crt')
context.verify_mode = ssl.CERT_REQUIRED  # 要求客戶端憑證

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, ssl_context=context)

TradingView Webhook 整合

TradingView 是全球最受歡迎的圖表平台,支援透過 Webhook 發送價格警報:

設定步驟

  1. 取得 Sentinel Webhook URL
   https://sentinel.yourdomain.com/webhook/{your-api-key}
  1. 在 TradingView 設定 Alert
   {
     "symbol": "{{ticker}}",
     "price": {{close}},
     "signal": "BUY",
     "timeframe": "{{interval}}",
     "timestamp": "{{time}}"
   }
  1. 測試觸發

TradingView Webhook 變數參考

| 變數 | 說明 | 範例 |

|------|------|------|

| {{ticker}} | 交易對 | BTCUSDT |

| {{close}} | 收盤價 | 45000.50 |

| {{open}} | 開盤價 | 44800.00 |

| {{high}} | 最高價 | 45200.00 |

| {{low}} | 最低價 | 44700.00 |

| {{volume}} | 成交量 | 1234.56 |

| {{interval}} | 時間週期 | 1h |

| {{time}} | 時間戳 | 2024-01-15T10:30:00Z |


Sentinel Webhook 整合

Sentinel 程式化交易系統原生支援 Webhook 接收,讓你能即時響應市場變化:

支援的 Webhook 來源

| 來源 | 說明 | 延遲 |

|------|------|------|

| TradingView | 價格警報、技術指標觸發 | < 1 秒 |

| 交易所 API | 訂單狀態更新、資金費率變動 | < 100ms |

| 自定義訊號 | 你的量化模型、機器學習預測 | 依來源 |

| 新聞情緒 | 即時新聞事件觸發 | < 5 秒 |

設定流程

  1. 取得 Sentinel Webhook URL
   https://sentinel.yourdomain.com/webhook/{your-api-key}
  1. 在訊號源設定 Webhook
  1. 設定安全驗證
  1. 定義響應策略
   {
     "symbol": "BTCUSDT",
     "action": "open_long",
     "leverage": 5,
     "position_size": "10%",
     "stop_loss": "2%",
     "take_profit": "6%"
   }

實際應用場景

| 場景 | Webhook 來源 | Sentinel 動作 |

|:---|:---|:---|

| 突破交易 | TradingView 價格警報 | 自動開倉 |

| 資金費率套利 | 交易所資金費率更新 | 調整倉位 |

| 風險控制 | 自定義風險模型 | 強制平倉 |

| 新聞交易 | 新聞 API 情緒分析 | 暫停交易 |

| 技術指標交叉 | 多時間框架指標 | 加減碼 |


結論:從輪詢到事件驅動

Webhook 是現代交易系統的基礎設施。它讓你:

即時響應 — 毫秒級延遲,不錯過任何機會

節省成本 — 減少 99% 以上的無效 API 請求

簡化架構 — 無需複雜的輪詢邏輯

提升可靠 — 事件驅動,邏輯更清晰


準備好接收你的第一個交易訊號了嗎?

Sentinel 程式化交易系統讓 Webhook 整合變得簡單:

立即開始使用 Sentinel →


相關閱讀

延伸閱讀