Интеграция TradingView Advanced Charts в торговую платформу

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Интеграция TradingView Advanced Charts в торговую платформу
Средний
~3-5 дней
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1288
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    902
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1122
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    859

Интеграция TradingView Advanced Charts в торговую платформу

TradingView Advanced Charts (ранее Charting Library) — это профессиональная библиотека графиков для встраивания в торговые платформы. Это тот же чарт что на самом TradingView.com, но лицензируемый для использования в собственных продуктах. Требует платной лицензии и реализации data feed на стороне биржи.

Типы лицензий

Лицензия Для кого Стоимость
Startup Стартапы до $1M ARR Бесплатно
Standard Коммерческие проекты $15,000/год
Enterprise Крупные платформы По запросу

Startup лицензия реальна и доступна — нужно заполнить форму на tradingview.com/charting-library. Условие: атрибуция TradingView на графике.

UDF Data Feed протокол

TradingView не тянет данные сам — ваша платформа должна реализовать UDF (Unified Data Format) API:

Endpoints

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,           # 2 знака после запятой
        "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]
    }

WebSocket Streaming

Для real-time обновления последней свечи и new ticks:

// 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. Маппинг:

TV_RESOLUTION_MAP = {
    '1': '1m',
    '5': '5m',
    '15': '15m',
    '30': '30m',
    '60': '1h',
    '240': '4h',
    'D': '1d',
    'W': '1w',
    'M': '1M'
}

Самая частая ошибка при интеграции: несоответствие timestamp format. TradingView history endpoint ожидает UNIX seconds, callback onRealtimeCallback — milliseconds. Перепутать легко, отладить сложно.