Реализация экрана торговли (Trading View) в мобильном приложении биржи

TRUETECH занимается разработкой, поддержкой и обслуживанием мобильных приложений iOS, Android, PWA. Имеем большой опыт и экспертизу для публикации мобильных приложений в популярные маркеты Google Play, App Store, Amazon, AppGallery и другие.
Разработка и поддержка любых видов мобильных приложений:
Информационные и развлекательные мобильные приложения
Новостные приложения, игры, справочники, онлайн-каталоги, погодные, фитнес и здоровье, туристические, образовательные, социальные сети и мессенджеры, квиз, блоги и подкасты, форумы, агрегаторы
Мобильные приложения электронной коммерции
Интернет-магазины, B2B-приложения, маркетплейсы, онлайн-обменники, кэшбэк-сервисы, биржи, дропшиппинг-платформы, программы лояльности, доставка еды и товаров, платежные системы
Мобильные приложения для управления бизнес-процессами
CRM-системы, ERP-системы, управление проектами, инструменты для команды продаж, учет финансов, управление производством, логистика и доставка, управление персоналом, системы мониторинга данных
Мобильные приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, платформы предоставления электронных услуг, платформы кешбека, видеохостинги, тематические порталы, платформы онлайн-бронирования и записи, платформы онлайн-торговли

Это лишь некоторые из типы мобильных приложений, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента.

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Реализация экрана торговли (Trading View) в мобильном приложении биржи
Сложная
~5 рабочих дней
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • image_mobile-applications_feedme_467_0.webp
    Разработка мобильного приложения для компании FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Разработка мобильного приложения для компании XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Разработка мобильного приложения для компании RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Разработка мобильного приложения для компании ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Разработка мобильного приложения для компании Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Разработка мобильного приложения для компании FLAVORS
    445

Реализация экрана торговли (Trading View) в мобильном приложении биржи

Экран торговли в биржевом приложении — один из самых технически плотных UI в мобильной разработке. Свечной график с сотнями точек данных, стакан котировок с обновлением в реальном времени, форма ордера с мгновенной валидацией, и всё это должно работать на 60 fps при WebSocket-потоке с 10 обновлениями в секунду. Именно здесь производительность отрисовки напрямую влияет на деньги пользователя.

Архитектура данных и real-time обновления

WebSocket и управление потоком данных

Биржевые данные приходят по WebSocket — подписка на пары, получение тиков и обновлений стакана. На iOS — URLSessionWebSocketTask (нативный, с iOS 13) или Starscream библиотека для более гибкого управления reconnect-логикой. На Android — OkHttp WebSocket или Ktor WebSocket client.

Критически важна стратегия throttling входящих данных. WebSocket может присылать 20–50 обновлений в секунду для активных пар. Обновлять UI на каждое — перегрузка main thread. Правильный подход: накапливаем обновления в ConcurrentQueue на background thread, применяем к UI с частотой 60fps (через CADisplayLink на iOS или Choreographer на Android).

// iOS: накопление обновлений
private var pendingOrderBookUpdates: [OrderBookUpdate] = []
private let updateQueue = DispatchQueue(label: "orderbook.updates")

func handleWebSocketMessage(_ update: OrderBookUpdate) {
    updateQueue.async { [weak self] in
        self?.pendingOrderBookUpdates.append(update)
    }
}

// CADisplayLink callback — на main thread, 60fps
@objc func applyPendingUpdates() {
    var updates: [OrderBookUpdate] = []
    updateQueue.sync { updates = pendingOrderBookUpdates; pendingOrderBookUpdates.removeAll() }
    guard !updates.isEmpty else { return }
    // Применяем batch updates к UI
    applyToOrderBook(updates)
}

Модель данных стакана

Order book — это sorted structure: bids (покупки) отсортированы по убыванию цены, asks (продажи) по возрастанию. SortedArray или TreeMap (Java) / AVLTree (Swift кастомная реализация) для O(log n) вставки и удаления при обновлениях. Обновление стакана — не полная замена, а patch: новый уровень, изменённый volume, удалённый уровень (volume = 0).

Для iOS стакана — NSFetchedResultsController-паттерн без CoreData: хранить bids: [(price: Decimal, size: Decimal)] и asks: [(price: Decimal, size: Decimal)], при изменении — diffing через DeepDiff или Swift's CollectionDifference для минимальных UITableView updates.

Свечной график

Кастомная отрисовка через Metal / Core Graphics

Стандартный UIKit / View слишком медленен для интерактивного свечного графика с 1000+ свечей. Варианты:

Core Graphics / UIKit Drawing. UIView.draw(_:) с UIGraphicsGetCurrentContext(). Каждая свеча — два прямоугольника (тело и тень) через context.fill(). Для 500 свечей в draw(_:) — 8–12 мс на iPhone 12, что вписывается в 16 мс frame budget. Не рекомендуется для 2000+ свечей или анимированных обновлений.

CALayer / CAShapeLayer. Каждая свеча — отдельный CALayer. Не делай так: 500 CALayer на экране — катастрофа для композитора. Один CALayer с кастомным drawing — правильно.

Metal. Для профессиональных trading-приложений с анимированным scalable графиком — MetalKit. MTLBuffer с vertex data для свечей, vertex shader рисует прямоугольники в пространстве экрана. 10 000 свечей — 1–2 мс render time. TradingView (веб) использует canvas с WebGL — тот же принцип.

Готовые библиотеки. Charts (Daniel Gindi) — популярная iOS/macOS библиотека, имеет CandleStickChartView. Не real-time, но для периодических обновлений подходит. LightweightCharts — официальная мобильная обёртка над TradingView Lightweight Charts (WebView-based). Последнее — самый быстрый путь до production-ready графика с техническими индикаторами.

Жесты и навигация по графику

Pinch для масштабирования, pan для перемещения по временной оси. UIPinchGestureRecognizer + UIPanGestureRecognizer одновременно через gestureRecognizer(_:shouldRecognizeSimultaneouslyWith:) -> true.

При масштабировании — visibleRange меняется, подгружаем исторические свечи для нового диапазона через REST API. Infinite scroll влево: при достижении leftEdge — запрос исторических данных, добавление в начало датасета без сброса текущей позиции (обновляем contentOffset на ширину добавленных свечей).

Crosshair при long press — UILongPressGestureRecognizer с minimumPressDuration = 0.1. При движении пальца — обновляем позицию crosshair и OHLCV-тултип с данными свечи под курсором. Hit-test по X-координате: candleIndex = Int((touchX - chartOriginX) / (candleWidth + candleSpacing)).

Форма ордера

Валидация и ввод цены/объёма

UITextField с inputView — кастомная цифровая клавиатура вместо системной. На ней — кнопки 25%, 50%, 75%, 100% от доступного баланса для быстрого ввода. Decimal для хранения, не Double.

Мгновенная валидация при вводе: минимальный объём, шаг цены (tick size), доступный баланс. Combine publisher(for: \.text) на UITextField с debounce(0.1) и map { Decimal(string: $0) }.

Предварительный расчёт стоимости ордера в реальном времени: total = price * amount с учётом комиссии. Обновляется при каждом изменении price или amount. NSDecimalNumber.multiplying(by:) для точности.

Buy/Sell переключение

Анимированный переход между buy и sell режимом: background цвет формы плавно меняется (зелёный ↔ красный), текст кнопки, иконки направления. На iOS — UIView.animate(withDuration: 0.2) с изменением backgroundColor. Haptic .impact(.medium) при переключении. В SwiftUI — withAnimation(.easeInOut(duration: 0.2)).

Подтверждение ордера

Bottom sheet с деталями ордера перед отправкой. UISheetPresentationController (iOS 15+) или кастомный bottom sheet. При подтверждении — кнопка переходит в loading state (UIActivityIndicatorView вместо текста), блокируется повторное нажатие. После ответа API — success animation (зелёная галочка с scale animation) или error с конкретным текстом ошибки из API.

Производительность и оптимизация

UITableView для стакана

Order book — UITableView с бесконечным potential height. UITableView.performBatchUpdates() для анимированного добавления/удаления/обновления строк. При 10 обновлениях/сек — batching изменений: не вызываем performBatchUpdates на каждый тик, собираем за 100 мс и применяем разом.

Ячейка стакана — кастомный UITableViewCell с UILabel-ами для цены, объёма и depth bar (визуальная полоса пропорциональная объёму на уровне). Depth bar — UIView с constraint на width, обновляемый через UIView.animate. Не перерисовываем всю ячейку — только меняем constant constraint.

Профилирование

Xcode Instruments > Time Profiler для поиска hot spots в цикле обновлений. Core Animation instrument для frame drops. Целевые метрики: <16 мс на обработку WebSocket batch, <5 мс на обновление UI, 0 dropped frames при скролле стакана.

На Android — Android Profiler в режиме CPU+Memory+Network одновременно. systrace для анализа длинных frames в Choreographer.

Offline и reconnect

При потере соединения: overlay «Нет подключения» поверх графика (не заменяем весь экран), последние известные данные остаются видимыми. При восстановлении: автоматический reconnect WebSocket с exponential backoff (1с, 2с, 4с, 8с, max 30с), REST запрос актуального snapshot стакана и последних свечей, seamless resume без сброса позиции графика.

Срок: 5 дней. За это время: WebSocket интеграция с throttling, свечной график на Core Graphics или LightweightCharts, order book с batch updates, форма ордера с валидацией и подтверждением. Кастомный Metal-рендеринг графика с индикаторами и расширенная аналитика — дополнительно 5–10 дней.