Webhook связывает серверный алерт с внешней системой. Он не открывает сделку сам: TradingView формирует POST, а ваш endpoint решает, принять событие, отклонить, записать, поставить в очередь или преобразовать в команду для другого API.
Как проходит запрос
- Условие алерта становится истинным.
- TradingView формирует текст Message с подстановками.
- Платформа отправляет HTTP POST на Webhook URL.
- Приемник проверяет формат и актуальность.
- Сохраняет уникальный event ID.
- Возвращает быстрый ответ.
- Фоновый worker выполняет дальнейшую работу.
Официальная инструкция TradingView по webhook задает ключевые ограничения: только порты 80 и 443, отмена запроса после трех секунд, отсутствие IPv6 и требование включенной двухфакторной аутентификации.
JSON или обычный текст
Content-Type выбирается по телу сообщения. Сам webhook использует стандартный HTTP POST; семантика метода описана в справочнике MDN.
| Message | Content-Type | Когда использовать |
|---|---|---|
| Валидный JSON | application/json |
Машинная обработка |
| Любой другой текст | text/plain |
Простое уведомление |
Пример стабильной схемы:
{
"version": 1,
"event_id": "{{ticker}}-{{interval}}-{{time}}-long",
"event": "entry_long",
"symbol": "{{exchange}}:{{ticker}}",
"interval": "{{interval}}",
"price": "{{close}}",
"occurred_at": "{{time}}",
"strategy": "ema-cross-v3"
}
Значения placeholders часто приходят строками. Валидатор должен явно преобразовывать цену и время, а не полагаться на неявные типы.
Как создать webhook в TradingView
- Включите 2FA в аккаунте.
- Создайте или откройте алерт.
- Выберите условие и частоту.
- В Notifications включите Webhook URL.
- Укажите HTTPS endpoint на порту 443.
- В Message вставьте валидный JSON.
- Сохраните алерт.
- Проведите тестовое событие.
- Проверьте Alert Log и Webhook status.
Перед webhook убедитесь, что само условие работает. Пошаговая диагностика есть в статье почему алерты TradingView не срабатывают.
Почему endpoint должен отвечать быстро
Трехсекундное окно включает сеть, TLS, обработку приложения и ответ. Вызов брокера, базы и внешней модели внутри HTTP request делает цепочку хрупкой.
Правильный приемник выполняет минимальную синхронную работу:
- ограничивает размер body;
- проверяет Content-Type;
- парсит JSON;
- валидирует обязательные поля;
- проверяет секрет и свежесть;
- сохраняет событие или кладет в очередь;
- отвечает 200/202.
Все остальное делает worker. Если downstream временно недоступен, очередь повторит обработку без повторной отправки со стороны TradingView.
Минимальная архитектура
| Компонент | Ответственность | Что не должен делать |
|---|---|---|
| HTTPS gateway | TLS, rate limit, размер запроса | Торговая логика |
| Webhook receiver | Валидация, dedup, быстрый ответ | Долгие внешние вызовы |
| Queue | Надежная передача и retry | Менять смысл события |
| Worker | Правила, API брокера, уведомления | Доверять входу без проверки |
| Audit log | Связь события, решения и результата | Хранить секреты в открытом виде |
Как защитить endpoint
TradingView предупреждает не включать логины и пароли в webhook body. Базовые меры:
Используйте HTTPS
Порт 443 защищает транспорт и соответствует ограничениям. Следите за сроком сертификата и полной цепочкой доверия.
Для endpoint применимы обычные правила защиты REST API: строгая проверка Content-Type и схемы, ограничение размера запроса, безопасные коды ошибок и отсутствие секретов в URL. Практический список мер опубликован в OWASP REST Security Cheat Sheet.
Сделайте URL непредсказуемым
Случайный path уменьшает фоновый шум, но не заменяет аутентификацию. URL может попасть в историю браузера, screenshot или конфигурацию.
Добавьте секрет приложения
Если поле сообщения контролируется вами, добавьте идентификатор ключа и секрет, который приемник сравнивает constant-time. Не используйте пароль от аккаунта. Предусмотрите ротацию и два одновременно действующих ключа на период перехода.
Ограничьте источники
TradingView публикует IPv4-адреса отправителей в официальной инструкции. Их можно allowlist на gateway, но список следует регулярно сверять. IP-фильтр применяйте вместе с секретом: инфраструктура и адреса могут меняться.
Не доверяйте symbol и price
Входные поля управляют дальнейшими действиями. Разрешайте только известные инструменты, интервалы, события и версии схемы. Перед заявкой получите свежую цену у брокера.
Защита от повторов
Сеть не гарантирует exactly once. Повтор может возникнуть из-за повторного алерта, ручного теста или retry вашей инфраструктуры.
Создайте event_id из стабильных компонентов или выдавайте ID в Pine-коде. Receiver сохраняет его в idempotency store:
- ID новый — принять и поставить в очередь;
- ID уже есть — вернуть успешный ответ, но не выполнять действие повторно;
- тот же ID с другим body — записать конфликт и остановить обработку.
Срок хранения idempotency key должен покрывать максимальное окно повторной доставки и ручного разбора.
Проверка актуальности
Сигнал может прийти с задержкой. Поле occurred_at сравнивается с серверным временем. Для стратегии задайте максимальный возраст, например 30 или 120 секунд в зависимости от таймфрейма.
Не отклоняйте только по цене из сообщения. Сначала проверьте время и статус сессии, затем получите свежий Bid/Ask у места исполнения. Причины расхождения источников разобраны в статье котировки TradingView и брокера.
Коды ответа и журнал
Практичная политика:
200или202— событие валидно и сохранено;400— JSON или схема неверны;401/403— секрет или источник не прошел проверку;413— body слишком большой;429— превышен rate limit;500/503— приемник не смог надежно сохранить событие.
Не возвращайте в response ключи, внутренний stack trace и подробности торгового счета.
Журнал связывает:
- request ID;
- event ID;
- время TradingView и приема;
- hash body;
- результат валидации;
- решение worker;
- запрос и ответ брокера без секретов;
- итоговое состояние.
Webhook и торговая заявка — разные сущности
Между entry_long и реальным ордером должны находиться проверки:
- разрешена ли стратегия;
- не устарел ли сигнал;
- открыт ли рынок;
- нет ли уже позиции или ожидающей заявки;
- находится ли цена в допустимом диапазоне;
- укладывается ли размер в риск;
- доступен ли официальный API;
- получен ли подтвержденный order ID.
Не давайте webhook-процессу универсальный ключ на вывод средств. Для торговли используйте отдельный API key без withdrawal и с IP allowlist, если брокер это поддерживает.
Как протестировать
Тест схемы
Отправьте локальный POST с правильным и неправильным JSON. Проверьте обязательные поля, неизвестную версию и слишком большое body.
Тест дубля
Дважды отправьте один event_id. Worker должен выполнить действие один раз.
Тест задержки
Передайте старое occurred_at. Событие должно сохраниться для аудита, но не стать заявкой.
Тест отказа downstream
Отключите тестовый API. Receiver все равно должен быстро принять событие, а очередь — повторить worker по политике.
Реальный алерт
Создайте безопасное условие без торгового действия. Сверьте Alert Log, gateway log, queue и audit record. Механика алерта подробно описана в статье как работают алерты TradingView.
Типовые ошибки
Сервер отвечает 200 до сохранения
При падении между ответом и записью событие теряется. Сначала надежно сохраните или поставьте в durable queue.
Торговый API вызывается синхронно
Задержка приводит к timeout. Перенесите вызов в worker.
Один endpoint принимает любую команду
Разделите схемы и allowlist действий. Не позволяйте произвольное имя метода или инструмента.
Нет версии JSON
Изменение полей ломает старые алерты незаметно. Версия позволяет валидировать и мигрировать формат.
Алерт изменен, но серверная копия старая
После правки Pine Script пересоздайте алерт. Иначе webhook продолжит получать старое сообщение или условие.
Вывод
Webhook TradingView — простой POST с жестким временем ответа, а не готовая автоматизация. Надежный endpoint быстро валидирует и сохраняет событие, защищается от повторов, а работу передает очереди. Торговая заявка появляется только после независимой проверки свежей цены, позиции и риска через официальный API места исполнения.
