Розробка торгового терміналу для криптовалют

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка торгового терміналу для криптовалют
Складний
від 2 тижнів до 3 місяців
Часті запитання

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

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

Останні роботи

  • 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

Розробка торговельного терміналу для криптовалют

Терміналу криптовалютної торгівлі — це інтерфейс, через який трейдер взаємодіє з ринком: бачить графіки, стакан, стрічку угод, керує ордерами та позиціями. Розробка серйозного терміналу — це багатомісячний проект, що вимагає глибокого розуміння як вимог UX трейдерів, так і технічних особливостей роботи з біржевими даними в реальному часі.

Ключові компоненти терміналу

Система графіків — серце терміналу. Відображення OHLCV свічок, технічних індикаторів, обсягів. TradingView Lightweight Charts — стандартний вибір для користувацьких рішень. Для повнофункціональних терміналів — TradingView Advanced Charts через Data Feed API або повністю користувацька реалізація на Canvas/WebGL.

Стакан ордерів — стакан заявок у реальному часі. Візуалізація рівнів bid/ask, depth chart (кумулятивний обсяг), групування за тиком. Критично: оновлення повинні відбуватися без перерисування всього компонента — лише змінені рядки.

Форма ордера — форма виставлення ордерів. Підтримка типів: market, limit, stop-limit, trailing stop. Розрахунок розміру у % від депозиту, у базовій/котираній валюті, за кількістю лотів.

Панель позицій/ордерів — керування відкритими позиціями та активними ордерами. Швидке закриття, зміна параметрів ордерів.

Стрічка угод — стрічка останніх угод з підсвічуванням крупних угод.

Портфель/Баланс — зведена інформація за рахунком: залишки, коефіцієнт маржі, P&L.

Архітектура frontend

// Структура React-додатку терміналу
interface TerminalLayout {
  left: {
    symbolSearch: SymbolSearchPanel;
    watchlist: WatchlistPanel;
  };
  center: {
    chart: ChartPanel;
    orderBook: OrderBookPanel;
    tradeFeed: TradeFeedPanel;
  };
  right: {
    orderForm: OrderFormPanel;
    positions: PositionsPanel;
    orders: OrdersPanel;
    balance: BalancePanel;
  };
  bottom: {
    orderHistory: OrderHistoryPanel;
    alerts: AlertsPanel;
  };
}

Змінний розмір розташування через react-grid-layout або react-mosaic — трейдери хочуть налаштовувати розміщення панелей.

Керування станом WebSocket

Терміналу отримує дані з кількох потоків WebSocket одночасно. Управління цим станом — нетривіальне завдання:

// Zustand сховище для ринкових даних
import { create } from 'zustand';

interface MarketDataStore {
  orderBook: OrderBook | null;
  trades: Trade[];
  currentPrice: number | null;
  
  updateOrderBook: (diff: OrderBookDiff) => void;
  addTrade: (trade: Trade) => void;
}

export const useMarketDataStore = create<MarketDataStore>((set, get) => ({
  orderBook: null,
  trades: [],
  currentPrice: null,

  updateOrderBook: (diff) => set((state) => {
    if (!state.orderBook) return state;
    
    const newBids = new Map(state.orderBook.bids);
    const newAsks = new Map(state.orderBook.asks);
    
    for (const [price, qty] of diff.bids) {
      if (qty === 0) newBids.delete(price);
      else newBids.set(price, qty);
    }
    for (const [price, qty] of diff.asks) {
      if (qty === 0) newAsks.delete(price);
      else newAsks.set(price, qty);
    }
    
    return {
      orderBook: { bids: newBids, asks: newAsks, timestamp: diff.timestamp }
    };
  }),

  addTrade: (trade) => set((state) => ({
    trades: [trade, ...state.trades].slice(0, 1000), // останні 1000 угод
    currentPrice: trade.price,
  })),
}));

Продуктивність: віртуалізація та WebWorkers

Стакан ордерів з 200+ рівнями, який оновлюється 10 разів на секунду — серйозне навантаження на DOM. Рішення:

Віртуалізація списку (react-virtual, tanstack/virtual) — рендеримо лише видимі рядки. 500 рядків у DOM → 20 видимих рядків.

Web Workers для обчислень — важкі обчислення (агрегація стакану, розрахунок індикаторів) виносяться в Worker, щоб не блокувати потік UI:

// orderbook.worker.ts
self.onmessage = (e: MessageEvent) => {
  const { type, data } = e.data;
  
  if (type === 'PROCESS_DIFF') {
    const processed = applyDiff(data.currentBook, data.diff);
    const aggregated = aggregateByTick(processed, data.tickSize);
    self.postMessage({ type: 'BOOK_UPDATED', data: aggregated });
  }
};

requestAnimationFrame регулювання — оновлюємо DOM не частіше 60 разів на секунду, буферизуючи вхідні оновлення.

Backend: сервіс Gateway

Терміналу не підключається безпосередньо до бірж — це архітектурна помилка для виробничих систем. Проміжний сервіс Gateway:

  • Мультиплексує одне з'єднання біржевого WebSocket для багатьох клієнтів
  • Кешує поточний стан стакану
  • Автентифікує підключення клієнтів
  • Обмежує rate limits
from fastapi import FastAPI, WebSocket
from starlette.websockets import WebSocketDisconnect
import asyncio

app = FastAPI()

class MarketDataGateway:
    def __init__(self):
        self.subscribers: dict[str, list[WebSocket]] = {}
        self.book_cache: dict[str, OrderBook] = {}

    async def subscribe(self, symbol: str, ws: WebSocket):
        if symbol not in self.subscribers:
            self.subscribers[symbol] = []
            asyncio.create_task(self.connect_to_exchange(symbol))
        
        self.subscribers[symbol].append(ws)
        
        # Відправляємо поточний снимок новому підписнику
        if symbol in self.book_cache:
            await ws.send_json(self.book_cache[symbol].to_dict())

    async def broadcast(self, symbol: str, data: dict):
        dead_connections = []
        for ws in self.subscribers.get(symbol, []):
            try:
                await ws.send_json(data)
            except Exception:
                dead_connections.append(ws)
        
        for ws in dead_connections:
            self.subscribers[symbol].remove(ws)

Інтеграція TradingView

TradingView Advanced Charts (платна ліцензія) — стандарт для професійних терміналів. Користувацький адаптер DataFeed:

const dataFeed: IDatafeedChartApi = {
  onReady: (callback) => {
    callback({
      supported_resolutions: ['1', '5', '15', '60', '240', 'D', 'W'],
      supports_marks: true,
      supports_time: true,
    });
  },

  getBars: async (symbolInfo, resolution, periodParams, onHistoryCallback) => {
    const candles = await api.getCandles(
      symbolInfo.name,
      resolution,
      periodParams.from,
      periodParams.to
    );
    onHistoryCallback(candles.map(toTradingViewBar), { noData: candles.length === 0 });
  },

  subscribeBars: (symbolInfo, resolution, onRealtimeCallback) => {
    wsGateway.on(`candle:${symbolInfo.name}:${resolution}`, onRealtimeCallback);
  },
};

Мобільна версія

Повнофункціональний терміналу на мобільному — інша UX-задача. Основні паттерни:

  • Проведення між розділами (chart/orderbook/orders) замість мультипанельного розташування
  • Bottom sheet для форми ордера
  • Спрощений стакан (лише 10-20 рівнів)
  • Push-сповіщення для сигналів про ціну та виконання ордерів

React Native з WebView для графіка TradingView або нативна реалізація через react-native-canvas для простих графіків.

Продуктивність та SLA

Вимоги до продуктивності:

Метрика Ціль
Затримка оновлення стакану < 100ms від біржі до UI
Затримка подання ордера < 200ms
FPS рендерування графіку 60 fps
Час початкового завантаження < 3 сек
Повторне з'єднання WebSocket < 2 сек

Моніторинг затримки на стороні клієнта через performance.now() та відправка метрик до аналітики — необхідна частина виробничого моніторингу.