При разработке торговой платформы перед инженерами встаёт выбор: написать кастомный графический движок с нуля (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 день.







