При разработке торговой платформы перед инженерами встаёт выбор: написать кастомный графический движок с нуля (3–6 месяцев) или встроить готовое решение. TradingView Advanced Charts — фактический стандарт для отображения финансовых данных, используемый Binance, Coinbase и другими топовыми биржами. Наша команда имеет многолетний опыт интеграции TradingView (более 50 проектов) и знает все подводные камни. В этом материале разберём ключевые этапы интеграции и типичные ошибки, которые стоят времени и бюджета. Самая частая ошибка — путаница с временными метками: history endpoint ожидает секунды, а real-time колбэки — миллисекунды. Эта деталь приводит к пропускам данных на графике и неделям отладки. Например, один из проектов потерял бы $200 000 на тестовом контуре из-за неверного преобразования времени, но проблема была обнаружена до выхода в продакшн.
Как подготовить Datafeed для TradingView?
TradingView не тянет данные самостоятельно — ваша платформа должна реализовать UDF API. Этот протокол описан в официальной документации TradingView и состоит из четырёх эндпоинтов: /config, /symbols, /search и /history. Ниже — рабочий пример на FastAPI.
from fastapi import FastAPI, Query from datetime import datetime app = FastAPI() @app.get("/config") def get_config(): """Описание возможностей data feed""" return { "supported_resolutions": ["1", "5", "15", "30", "60", "240", "D", "W"], "supports_group_request": False, "supports_marks": False, "supports_search": True, "supports_timescale_marks": False, "exchanges": [{"value": "", "name": "All", "desc": "All exchanges"}], "symbols_types": [{"name": "crypto", "value": "crypto"}] } @app.get("/symbols") async def get_symbol_info(symbol: str = Query(...)): """Информация о конкретном символе""" return { "name": symbol, "ticker": symbol, "description": f"{symbol} / USDT", "type": "crypto", "session": "24x7", "exchange": "YourExchange", "listed_exchange": "YourExchange", "timezone": "Etc/UTC", "pricescale": 100, "minmov": 1, "volume_precision": 8, "has_intraday": True, "has_daily": True, "has_weekly_and_monthly": True, "supported_resolutions": ["1", "5", "15", "30", "60", "240", "D"], "currency_code": "USDT" } @app.get("/search") async def search_symbols(query: str, limit: int = 30): """Поиск символов""" symbols = await db.search_trading_pairs(query, limit) return [ { "symbol": s.symbol, "full_name": s.symbol, "description": s.description, "exchange": "YourExchange", "type": "crypto" } for s in symbols ] @app.get("/history") async def get_history( symbol: str, resolution: str, from_ts: int = Query(alias="from"), to_ts: int = Query(alias="to"), countback: int = None ): """OHLCV исторические данные — основной endpoint""" candles = await db.get_candles( symbol=symbol, resolution=resolution, from_time=datetime.fromtimestamp(from_ts), to_time=datetime.fromtimestamp(to_ts) ) if not candles: return {"s": "no_data"} return { "s": "ok", "t": [int(c.time.timestamp()) for c in candles], "o": [c.open for c in candles], "h": [c.high for c in candles], "l": [c.low for c in candles], "c": [c.close for c in candles], "v": [c.volume for c in candles] } Почему важна правильная обработка временных меток?
Самая частая ошибка при интеграции — путаница с единицами времени. TradingView history endpoint ожидает UNIX-таймстампы в секундах, а колбэк onRealtimeCallback — в миллисекундах. Если перепутать, график будет показывать пропуски или некорректные бары. В продакшене мы видели проекты, где эта ошибка отнимала недели отладки. В одном из случаев неверное преобразование времени привело к ошибке в ордерах на $200 000 — вовремя заметили на тестовом контуре.
Как настроить WebSocket стриминг?
Для получения обновлений последней свечи и новых тиков необходимо реализовать WebSocket-подписку.
// datafeed.js — реализация TradingView Datafeed Interface const Datafeed = { subscribeBars(symbolInfo, resolution, onRealtimeCallback, subscriberUID) { const ws = new WebSocket('wss://api.yourexchange.com/ws'); ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'candle_update' && data.symbol === symbolInfo.ticker) { onRealtimeCallback({ time: data.time * 1000, // TradingView ожидает миллисекунды open: data.open, high: data.high, low: data.low, close: data.close, volume: data.volume }); } }; ws.onopen = () => { ws.send(JSON.stringify({ action: 'subscribe', channel: 'kline', symbol: symbolInfo.ticker, interval: resolution })); }; this._subscribers[subscriberUID] = ws; }, unsubscribeBars(subscriberUID) { const ws = this._subscribers[subscriberUID]; if (ws) { ws.close(); delete this._subscribers[subscriberUID]; } } }; Настройка, лицензии и альтернативы
Инициализация виджета и кастомизация
import { widget } from '@tradingview/charting-library'; const chart = new widget({ container: 'chartContainer', library_path: '/charting_library/', locale: 'ru', datafeed: Datafeed, symbol: 'BTCUSDT', interval: '60', fullscreen: false, autosize: true, timezone: 'Etc/UTC', // Кастомизация темы theme: 'dark', overrides: { 'paneProperties.background': '#0f0f0f', 'paneProperties.backgroundType': 'solid', 'scalesProperties.textColor': '#aaaaaa', }, // Включённые features enabled_features: [ 'side_toolbar_in_fullscreen_mode', 'header_screenshot', 'pre_post_market_sessions' ], disabled_features: [ 'use_localstorage_for_settings', 'header_symbol_search', ], // Загрузка/сохранение конфигурации пользователя save_load_adapter: MySaveLoadAdapter }); Resolution маппинг
TradingView использует нестандартные значения resolution. Вот соответствие:
| Resolution TradingView | Интервал |
|---|---|
| 1 | 1m |
| 5 | 5m |
| 15 | 15m |
| 30 | 30m |
| 60 | 1h |
| 240 | 4h |
| D | 1d |
| W | 1w |
Типы лицензий
| Лицензия | Для кого | Стоимость |
|---|---|---|
| Startup | Стартапы до $1M ARR | Бесплатно |
| Standard | Коммерческие проекты | $15,000/год |
| Enterprise | Крупные платформы | По запросу |
Startup лицензия реальна и доступна — нужно заполнить форму на tradingview.com/charting-library. Условие: атрибуция TradingView на графике.
Сравнение: TradingView Advanced Charts vs ChartIQ
TradingView Advanced Charts выигрывает по скорости рендеринга в 2–3 раза за счёт WebGL, а также предлагает готовые индикаторы и инструменты рисования. ChartIQ лучше подходит для глубокой кастомизации, но требует больше времени на интеграцию. Экономия на разработке кастомного решения может составлять от $50 000 до $150 000 в зависимости от сложности. Для криптобирж TradingView — более зрелое и распространённое решение.
Чек-лист проверки интеграции
- [ ] Datafeed возвращает корректные OHLCV данные на /history
- [ ] WebSocket отправляет обновления в миллисекундах
- [ ] Маппинг resolution настроен правильно
- [ ] Поддерживаются все требуемые таймфреймы
- [ ] Поиск символов работает через /search
- [ ] Темная тема применена через overrides
- [ ] Сохранение пользовательских настроек работает
Закажите аудит вашего текущего datafeed — мы найдём и исправим все ошибки за 2 дня.
Что входит в работу
- Реализация UDF-совместимого Datafeed (конфигурация, символы, история)
- Настройка WebSocket стриминга для real-time данных
- Интеграция с брокерским API (торговля через TradingView)
- Кастомизация темы, индикаторов, разрешений
- Создание save/load adapter для сохранения настроек
- Документация по развёртыванию и поддержке
- Гарантия на 3 месяца после сдачи
Процесс работы
- Аналитика — обсуждаем требования, архитектуру datafeed, список символов, необходимые таймфреймы.
- Проектирование — проектируем REST API и WebSocket-каналы, согласовываем маппинг.
- Реализация — пишем бэкенд (Python/FastAPI или Node.js), фронтенд-обёртку.
- Тестирование — проверяем все эндпоинты, нагрузочное тестирование (до 1000 одновременных подписок).
- Деплой — развёртываем на вашем сервере или в облаке.
Сроки ориентировочно
От 2 до 4 недель в зависимости от сложности datafeed и необходимости кастомизации. Стоимость рассчитывается индивидуально — свяжитесь с нами для оценки вашего проекта. Наши инженеры сертифицированы по TradingView и имеют опыт интеграции для платформ с аудиторией 100k+ пользователей.
Получите консультацию по интеграции TradingView Advanced Charts — пишите, мы оценим ваш проект за 1 день.







