API 參考 進階功能

Webhook API 文件

直接透過 HTTP 請求發送交易訊號,無需 TradingView。適合自行開發交易系統的進階用戶。

概述

Webhook API 讓你可以透過任何能發送 HTTP 請求的程式(Python、Node.js、Shell script 等)來觸發交易訊號,實現完全自動化的交易系統。

保證金與委託類型說明

  • 反向倉位保證金需求:若已持有反向倉位,收到進場訊號時實際所需保證金會較大。例如:持有 +1 多單收到 short_entry,系統需下 -2 口(出場 + 進場),保證金需求為 2 口。
  • 市價委託執行:所有委託均以市價單 (MKT) 執行,可能產生滑價,實際成交價格可能與觸發時價格有所差異。

適合使用場景

  • • 自己的量化策略系統
  • • Python/Node.js 回測框架
  • • 其他交易平台的訊號轉發
  • • 自動化腳本排程

Base URL

認證方式

認證透過 URL 中的 webhook_token 進行。每位用戶在 4pass 系統中都有一組專屬的 Token。

# URL 格式
{your_webhook_token}/order

安全性注意

  • • Webhook Token 等同於你的下單密碼,請妥善保管
  • 務必設定 IP 白名單,限制只有你的伺服器 IP 可以呼叫
  • • 若懷疑 Token 外洩,請立即至系統重新產生

下單 API

POST /webhook/{webhook_token}/order

發送交易訊號,系統會自動透過券商 API 下單。

Query Parameters

參數 類型 說明
simulation boolean 模擬模式。true = 不實際下單(預設),false = 實盤交易

Request Body (JSON)

欄位 類型 必填 說明
action string 必填 交易動作:
long_entry 做多進場
long_exit 做多出場
short_entry 做空進場
short_exit 做空出場
symbol string 必填 商品代碼,請至控制台「商品代碼」頁面查詢支援的代碼。
quantity integer 必填 下單口數(必須大於 0)。出場時會自動使用實際持倉數量。
timestamp string 正式交易必填 ISO 8601 時間戳 (如 2024-01-28T10:30:00Z)。TradingView 中使用 "{{timenow}}"。防止重放攻擊,請求須在 5 分鐘內。
secret string 正式交易必填 您的 Webhook Secret(設定頁面可查看)。驗證請求來源,防止 URL Token 外洩風險。

Request 範例

模擬模式 (simulation=true):

POST /webhook/abc123.../order?simulation=true
Content-Type: application/json

{
    "action": "long_entry",
    "symbol": "YOUR_SYMBOL",
    "quantity": 1
}

正式交易 (simulation=false) - 需要 timestamp 和 secret:

POST /webhook/abc123.../order?simulation=false
Content-Type: application/json

{
    "action": "long_entry",
    "symbol": "YOUR_SYMBOL",
    "quantity": 1,
    "timestamp": "{{timenow}}",
    "secret": "your-webhook-secret"
}

Response

欄位 類型 說明
status string submitted 已送出 / no_action 無動作(無持倉可出場)
order_id integer 系統訂單編號
user_email string 用戶 Email(部分遮罩)
message string 狀態訊息
// 成功回應
{
    "status": "submitted",
    "order_id": 12345,
    "user_email": "use***@example.com",
    "message": "Order submitted successfully. Fill status will be verified in background."
}
Try it out — 在此測試 API

可從 4pass 系統的 Webhook 設定頁面取得

驗證 API

GET /webhook/{webhook_token}/info

驗證 Webhook Token 是否有效,取得基本資訊。適合先測試 Token 是否正確。

Response 範例

{
    "valid": true,
    "user_email": "use***",
    "subscription_plan": "pro",
    "webhook_url": "/webhook/abc123.../order"
}
Try it out — 先驗證你的 Token

建議先用此 API 驗證 Token 是否有效

錯誤處理

HTTP 狀態碼 說明 解決方式
400 交易執行失敗、無交易憑證、或正式交易缺少 timestamp/secret 確認已設定 API 金鑰;正式交易需提供 timestamp 和 secret
401 timestamp 過期或 secret 驗證失敗 確認 timestamp 在 5 分鐘內,secret 與系統設定相符
409 重複請求(重放攻擊防護) 相同 payload 在有效期內只能發送一次
403 IP 不在白名單 / 方案限制 / 訂閱過期 檢查 IP 白名單、升級方案或續訂
404 Token 無效或帳戶未啟用 確認 webhook_token 正確
422 請求參數驗證失敗 檢查 JSON 格式與欄位:
action 必須是 long_entry/long_exit/short_entry/short_exit
quantity 必須是大於 0 的整數
symbol 必須是字串
429 超過每日委託上限 等待隔日或升級至專業方案
451 未同意服務條款 登入 4pass 系統並同意服務條款
500 伺服器內部錯誤 請聯絡技術支援
503 交易服務暫時無法使用 稍後重試(可能正在維護)

422 驗證錯誤範例

// 當 action 值不正確時
{
    "detail": [
        {
            "type": "literal_error",
            "loc": ["body", "action"],
            "msg": "Input should be 'long_entry', 'long_exit', 'short_entry' or 'short_exit'",
            "input": "invalid_action"
        }
    ]
}

範例程式碼

Python (模擬模式)

import requests

WEBHOOK_URL = "/webhook/YOUR_TOKEN/order"

def send_signal(action, symbol, quantity, simulation=True):
    response = requests.post(
        WEBHOOK_URL,
        params={"simulation": simulation},
        json={
            "action": action,
            "symbol": symbol,
            "quantity": quantity
        }
    )
    return response.json()

# 做多進場 (模擬模式)
result = send_signal("long_entry", "YOUR_SYMBOL", 1)
print(result)

Python (正式交易 - 需要 timestamp 和 secret)

import requests
from datetime import datetime, timezone

WEBHOOK_URL = "/webhook/YOUR_TOKEN/order"
WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET"  # 從 4pass 設定頁面取得

def send_real_signal(action, symbol, quantity):
    # 產生 ISO 8601 格式的 timestamp
    timestamp = datetime.now(timezone.utc).isoformat().replace("+00:00", "Z")
    
    response = requests.post(
        WEBHOOK_URL,
        params={"simulation": "false"},
        json={
            "action": action,
            "symbol": symbol,
            "quantity": quantity,
            "timestamp": timestamp,
            "secret": WEBHOOK_SECRET
        }
    )
    return response.json()

# 做多進場 (正式交易)
result = send_real_signal("long_entry", "YOUR_SYMBOL", 1)
print(result)

cURL (模擬模式)

curl -X POST "/webhook/YOUR_TOKEN/order?simulation=true" \
  -H "Content-Type: application/json" \
  -d '{"action": "long_entry", "symbol": "YOUR_SYMBOL", "quantity": 1}'

cURL (正式交易 - 需要 timestamp 和 secret)

# 使用當前時間作為 timestamp
curl -X POST "/webhook/YOUR_TOKEN/order?simulation=false" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "long_entry",
    "symbol": "YOUR_SYMBOL",
    "quantity": 1,
    "timestamp": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
    "secret": "YOUR_WEBHOOK_SECRET"
  }'

Node.js (模擬模式)

const WEBHOOK_URL = "/webhook/YOUR_TOKEN/order";

async function sendSignal(action, symbol, quantity, simulation = true) {
  const response = await fetch(
    `${WEBHOOK_URL}?simulation=${simulation}`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action, symbol, quantity })
    }
  );
  return response.json();
}

// 做多進場 (模擬模式)
sendSignal("long_entry", "YOUR_SYMBOL", 1).then(console.log);

Node.js (正式交易 - 需要 timestamp 和 secret)

const WEBHOOK_URL = "/webhook/YOUR_TOKEN/order";
const WEBHOOK_SECRET = "YOUR_WEBHOOK_SECRET";  // 從 4pass 設定頁面取得

async function sendRealSignal(action, symbol, quantity) {
  // 產生 ISO 8601 格式的 timestamp
  const timestamp = new Date().toISOString();
  
  const response = await fetch(
    `${WEBHOOK_URL}?simulation=false`,
    {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ 
        action, 
        symbol, 
        quantity,
        timestamp,
        secret: WEBHOOK_SECRET
      })
    }
  );
  return response.json();
}

// 做多進場 (正式交易)
sendRealSignal("long_entry", "YOUR_SYMBOL", 1).then(console.log);