Webhook 与通知

本章详细介绍 Freqtrade 的 Webhook 通知机制,涵盖 Webhook 配置、消息格式、自定义回调以及对接第三方通知服务的方法,帮助读者构建灵活的外部通知系统。

Webhook 配置

基本配置

{
    "webhook": {
        "enabled": true,
        "url": "https://your-webhook-url.com/endpoint",
        "secret": "your_webhook_secret",
        "webhook_entry": {
            "value": "开仓信号触发"
        },
        "webhook_entry_fill": {
            "value": "开仓已成交"
        },
        "webhook_exit": {
            "value": "平仓信号触发"
        },
        "webhook_exit_fill": {
            "value": "平仓已成交"
        },
        "webhook_exit_cancel": {
            "value": "平仓已取消"
        },
        "webhook_status": {
            "value": "状态更新"
        }
    }
}

配置参数说明

参数类型默认值说明
enabledboolfalse是否启用 Webhook
urlstring-Webhook 回调地址
secretstring-签名密钥(可选)
webhook_entryobject-开仓信号通知
webhook_entry_fillobject-开仓成交通知
webhook_entry_cancelobject-开仓取消通知
webhook_exitobject-平仓信号通知
webhook_exit_fillobject-平仓成交通知
webhook_exit_cancelobject-平仓取消通知
webhook_statusobject-状态更新通知
webhook_protectionsobject-风控触发通知

消息格式

默认消息格式

Webhook 默认发送 POST 请求,Content-Type 为 application/json

{
    "type": "entry",
    "pair": "BTC/USDT",
    "side": "long",
    "trade_id": 123,
    "open_rate": 42000.00,
    "amount": 0.002,
    "stake_amount": 84.00,
    "stake_currency": "USDT",
    "open_date": "2024-01-15T08:00:00Z"
}

各类型消息字段

开仓消息 (entry)

{
    "type": "entry",
    "exchange": "binance",
    "pair": "BTC/USDT",
    "side": "long",
    "trade_id": 123,
    "open_rate": 42000.00,
    "amount": 0.002,
    "stake_amount": 84.00,
    "stake_currency": "USDT",
    "open_date": "2024-01-15T08:00:00Z",
    "enter_tag": "rsi_oversold"
}

开仓成交 (entry_fill)

{
    "type": "entry_fill",
    "exchange": "binance",
    "pair": "BTC/USDT",
    "side": "long",
    "trade_id": 123,
    "open_rate": 42150.00,
    "amount": 0.002,
    "stake_amount": 84.30,
    "stake_currency": "USDT",
    "open_date": "2024-01-15T08:00:00Z"
}

平仓消息 (exit)

{
    "type": "exit",
    "exchange": "binance",
    "pair": "BTC/USDT",
    "side": "long",
    "trade_id": 123,
    "open_rate": 42150.00,
    "close_rate": 43500.00,
    "amount": 0.002,
    "profit_ratio": 0.032,
    "profit_abs": 2.70,
    "stake_currency": "USDT",
    "exit_reason": "roi",
    "open_date": "2024-01-15T08:00:00Z",
    "close_date": "2024-01-15T14:00:00Z"
}

自定义回调

自定义消息格式

通过 value 字段自定义消息内容,支持模板变量:

{
    "webhook": {
        "enabled": true,
        "url": "https://hooks.example.com/trade",
        "webhook_entry": {
            "value": "{\"msg\": \"📈 开仓通知\",\"pair\": \"{pair}\",\"price\": {open_rate},\"side\": \"{side}\"}"
        },
        "webhook_exit_fill": {
            "value": "{\"msg\": \"✅ 平仓成交\",\"pair\": \"{pair}\",\"profit\": {profit_ratio:.2%},\"duration\": \"{trade_duration}\"}"
        },
        "webhook_status": {
            "value": "{\"type\": \"status\",\"content\": \"{status}\"}"
        }
    }
}

带签名的 Webhook

{
    "webhook": {
        "enabled": true,
        "url": "https://your-server.com/webhook",
        "secret": "your_hmac_secret",
        "webhook_entry": {
            "value": "{\"pair\": \"{pair}\", \"type\": \"entry\"}"
        }
    }
}

Freqtrade 使用 HMAC-SHA256 对请求体进行签名,签名放在 X-Webhook-Signature 请求头中。

自定义 HTTP 方法

{
    "webhook": {
        "enabled": true,
        "url": "https://api.example.com/trade",
        "webhook_entry": {
            "value": "action=entry&pair={pair}&rate={open_rate}"
        },
        "webhook_exit": {
            "value": "action=exit&pair={pair}&profit={profit_ratio}"
        }
    }
}

默认使用 POST 方法,可以通过自定义 value 改变请求行为。

对接第三方服务

钉钉机器人

{
    "webhook": {
        "enabled": true,
        "url": "https://oapi.dingtalk.com/robot/send?access_token=YOUR_TOKEN",
        "webhook_entry": {
            "value": "{\"msgtype\": \"markdown\", \"markdown\": {\"title\": \"开仓通知\", \"text\": \"#### 📈 开仓通知\n\n**交易对**: {pair}\n**价格**: {open_rate}\n**方向**: {side}\n**标签**: {enter_tag}\n**时间**: {open_date}\"}}"
        },
        "webhook_exit_fill": {
            "value": "{\"msgtype\": \"markdown\", \"markdown\": {\"title\": \"平仓通知\", \"text\": \"#### ✅ 平仓成交\n\n**交易对**: {pair}\n**成交价**: {close_rate}\n**盈亏**: {profit_ratio:.2%}\n**原因**: {exit_reason}\"}}"
        }
    }
}

企业微信机器人

{
    "webhook": {
        "enabled": true,
        "url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY",
        "webhook_entry": {
            "value": "{\"msgtype\": \"markdown\", \"markdown\": {\"content\": \"## 📈 开仓通知\n交易对: {pair}\n价格: {open_rate}\n方向: {side}\"}}"
        },
        "webhook_exit_fill": {
            "value": "{\"msgtype\": \"markdown\", \"markdown\": {\"content\": \"## ✅ 平仓成交\n交易对: {pair}\n盈亏: {profit_ratio:.2%}\n原因: {exit_reason}\"}}"
        }
    }
}

Slack Webhook

{
    "webhook": {
        "enabled": true,
        "url": "https://hooks.slack.com/services/T0000/B0000/YOUR_TOKEN",
        "webhook_entry": {
            "value": "{\"text\": \"📈 开仓: {pair} @ {open_rate} ({side})\"}"
        },
        "webhook_exit_fill": {
            "value": "{\"text\": \"✅ 平仓: {pair} 盈亏: {profit_ratio:.2%} ({exit_reason})\"}"
        }
    }
}

Discord Webhook

{
    "webhook": {
        "enabled": true,
        "url": "https://discord.com/api/webhooks/CHANNEL_ID/WEBHOOK_TOKEN",
        "webhook_entry": {
            "value": "{\"content\": \"📈 **开仓通知**\n交易对: {pair}\n价格: {open_rate}\n方向: {side}\", \"username\": \"Freqtrade Bot\"}"
        },
        "webhook_exit_fill": {
            "value": "{\"content\": \"✅ **平仓成交**\n交易对: {pair}\n盈亏: {profit_ratio:.2%}\n原因: {exit_reason}\", \"username\": \"Freqtrade Bot\"}"
        }
    }
}

Telegram Bot(通过 Webhook)

{
    "webhook": {
        "enabled": true,
        "url": "https://api.telegram.org/botYOUR_TOKEN/sendMessage",
        "webhook_entry": {
            "value": "chat_id=YOUR_CHAT_ID&text=📈+开仓%3A+{pair}+%40+{open_rate}+({side})"
        },
        "webhook_exit_fill": {
            "value": "chat_id=YOUR_CHAT_ID&text=✅+平仓%3A+{pair}+盈亏%3A+{profit_ratio:.2%25}+({exit_reason})"
        }
    }
}

对接对比表

平台配置复杂度消息格式优点缺点
钉钉简单Markdown国内访问快需要公网 IP
企业微信简单Markdown集成企业通讯消息频率限制
Slack简单JSON全球通用国内访问慢
Discord简单JSON富文本支持好需要科学上网
Telegram内置原生无需额外配置需要科学上网
自定义 API中等任意完全灵活需要自己开发

Webhook 安全

签名验证

如果配置了 secret,Freqtrade 会在请求头中添加签名:

import hmac
import hashlib
from flask import Flask, request

app = Flask(__name__)
WEBHOOK_SECRET = b"your_webhook_secret"

@app.route("/webhook", methods=["POST"])
def webhook_handler():
    # 获取签名
    signature = request.headers.get("X-Webhook-Signature")

    # 验证签名
    body = request.get_data()
    expected_sig = hmac.new(
        WEBHOOK_SECRET,
        body,
        hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected_sig):
        return "Invalid signature", 403

    # 处理消息
    data = request.json
    print(f"收到 {data['type']} 通知: {data['pair']}")

    return "OK", 200

HTTPS 要求

始终使用 HTTPS 端点接收 Webhook,避免消息在传输中被截获。