Разработка мобильного приложения для криптотрейдинг-бота

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

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 1735 услуг
Разработка мобильного приложения для криптотрейдинг-бота
Сложная
от 1 недели до 3 месяцев
Часто задаваемые вопросы
Наши компетенции:
Этапы разработки
Последние работы
  • 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
    1054
  • 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

Разработка мобильного приложения для криптотрейдинг-бота

Торговый бот работает на сервере: открывает позиции, исполняет ордера, управляет рисками. Мобильное приложение — это не сам бот, а полноценный интерфейс управления им: мониторинг позиций в реальном времени, настройка стратегий, история сделок, push при критичных событиях. Разработка такого приложения объединяет несколько сложных задач одновременно.

Архитектура системы

Мобильное приложение не торгует напрямую с биржей. Схема всегда через бэкенд:

Мобильное приложение
        ↕ REST API + WebSocket
    Backend API (бот-сервер)
        ↕ Exchange API (Binance/Bybit)

Такая архитектура обязательна: биржевые API-ключи хранятся только на сервере, мобильное приложение аутентифицируется через JWT в собственный бэкенд. Прямые запросы с телефона к бирже исключены — ключи в приложении скомпрометируют при статическом анализе APK/IPA.

Аутентификация и безопасность

Пользователь логинится в приложение (email/пароль или OAuth), получает JWT + refresh token. JWT хранится в iOS Keychain / Android Keystore — не в SharedPreferences или UserDefaults, иначе доступен при бэкапе без шифрования.

Биометрическая аутентификация для открытия приложения и подтверждения критичных операций (например, остановки бота с закрытием позиций):

// iOS — биометрия через LocalAuthentication
import LocalAuthentication

func authenticateWithBiometrics() async throws {
    let context = LAContext()
    var error: NSError?
    guard context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) else {
        throw AuthError.biometricsNotAvailable
    }
    let success = try await context.evaluatePolicy(
        .deviceOwnerAuthenticationWithBiometrics,
        localizedReason: "Подтвердите остановку бота"
    )
    guard success else { throw AuthError.biometricsFailed }
}

Real-time данные

Два типа данных с разными требованиями к latency:

Данные бота (позиции, статус, PnL) — через WebSocket к собственному бэкенду. Бэкенд агрегирует данные от биржи и рассылает клиентам. Задержка 1–3 секунды приемлема.

Рыночные данные (цена актива, стакан) — можно напрямую из Binance WebSocket стримов (btcusdt@ticker, btcusdt@depth5). Задержка < 100 мс. Но прямое подключение к бирже из мобильного приложения — только для отображения, не для торговли.

На Flutter управление несколькими WebSocket соединениями:

@riverpod
class TradingHubNotifier extends _$TradingHubNotifier {
  WebSocketChannel? _botChannel;
  WebSocketChannel? _marketChannel;

  @override
  TradingHubState build() {
    ref.onDispose(() {
      _botChannel?.sink.close();
      _marketChannel?.sink.close();
    });
    return const TradingHubState.initial();
  }

  void connect(String botId, String jwtToken, String symbol) {
    _connectBot(botId, jwtToken);
    _connectMarket(symbol);
  }

  void _connectBot(String botId, String token) {
    _botChannel = WebSocketChannel.connect(
      Uri.parse('wss://api.mybot.com/bots/$botId/ws?token=$token'),
    );
    _botChannel!.stream.listen(
      (data) => _handleBotEvent(jsonDecode(data as String)),
      onError: (_) => Future.delayed(const Duration(seconds: 3), () => _connectBot(botId, token)),
      onDone: () => Future.delayed(const Duration(seconds: 3), () => _connectBot(botId, token)),
    );
  }

  void _connectMarket(String symbol) {
    _marketChannel = WebSocketChannel.connect(
      Uri.parse('wss://stream.binance.com:9443/ws/${symbol.toLowerCase()}@ticker'),
    );
    _marketChannel!.stream.listen(
      (data) => _handleMarketTick(jsonDecode(data as String)),
    );
  }
}

Reconnect — не optional. Мобильная сеть рвётся постоянно: смена WiFi на LTE, переход в тоннель. Exponential backoff с максимумом 30 секунд.

Главный экран: Dashboard

Три смысловых блока без лишнего:

Статус бота. Цветной индикатор + текстовый статус (Running / Stopped / Error). Кнопки Start/Stop. При ошибке — краткое сообщение («Недостаточно баланса для открытия позиции»).

Открытые позиции. Список карточек: пара, сторона, размер, цена входа, текущая цена, unrealized PnL в USDT и %. PnL обновляется при каждом рыночном тике без перестройки списка — только изменение данных в уже созданных ячейках. На iOS UICollectionView с UICollectionViewDiffableDataSource и NSDiffableDataSourceSnapshot для точечного обновления.

Метрики сессии. Суммарный реализованный PnL за сегодня, число сделок, win rate. Пересчёт при каждом position_closed событии.

Управление несколькими ботами

Пользователь может держать несколько ботов на разных парах и стратегиях. BotsListScreen — список ботов с компактными карточками (статус, текущий PnL, пара). Тап — переход на детальный экран конкретного бота.

При нескольких активных ботах WebSocket соединения держим только для открытого бота. При фоне — переходим на push-уведомления вместо WebSocket (FCM high priority data message).

Push-уведомления: типы и приоритеты

Три уровня важности:

Критичные (доставить немедленно, разбудить устройство):

  • Стоп-лосс сработал
  • Бот остановился с ошибкой
  • Биржевой API вернул 401 (невалидный ключ)

Информационные (показать в удобное время):

  • Тейк-профит достигнут, позиция закрыта с прибылью
  • Ежедневный отчёт

Тихие обновления (только обновить данные в фоне, без алерта):

  • Пересчёт статистики

На Android: критичные — FCM с priority: high, ttl: 60s, notification + data. Информационные — priority: normal. iOS: критичные — apns-priority: 10, apns-expiration: 60.

// Android — обработка push в FirebaseMessagingService
override fun onMessageReceived(message: RemoteMessage) {
    val eventType = message.data["event_type"] ?: return
    when (eventType) {
        "stop_loss_triggered" -> {
            showCriticalNotification(
                title = "Стоп-лосс сработал",
                body = "${message.data["pair"]}: -${message.data["loss_usdt"]} USDT",
                channelId = CRITICAL_CHANNEL_ID
            )
        }
        "position_closed" -> {
            showInfoNotification(
                title = "Позиция закрыта",
                body = "${message.data["pair"]}: +${message.data["pnl_usdt"]} USDT",
                channelId = INFO_CHANNEL_ID
            )
        }
        "background_sync" -> {
            // Обновить локальный кэш без показа уведомления
            syncBotState(message.data["bot_id"]!!)
        }
    }
}

Notification channels на Android — критичные в отдельном канале с IMPORTANCE_HIGH и вибрацией. Информационные — IMPORTANCE_DEFAULT. Пользователь может управлять каналами в настройках системы, не отключая все уведомления разом.

История сделок и статистика

Отдельный таб с полной историей: список с пагинацией (Jetpack Paging 3 / SwiftUI LazyVStack с .task-триггером для следующей страницы), фильтры по паре/периоду/результату.

Summary-метрики за период: Total PnL, Win Rate, Profit Factor, Max Drawdown. График equity curve (кумулятивный PnL) на fl_chart LineChart. График обновляется при переключении периода, не при каждом событии.

Настройки стратегий

Отдельный экран для каждой стратегии бота. Форма с числовыми полями и валидацией:

  • Take Profit / Stop Loss (диапазон 0.1–50%)
  • Размер ордера (минимум диктует биржа)
  • Торговые пары (multiselect с поиском, список из API биржи)
  • Cooldown между сделками (в минутах)

Критичное правило: изменение параметров при запущенном боте — с предупреждением и confirmation. Поля, которые нельзя менять на лету (тип стратегии, биржа) — заблокированы при status == RUNNING.

Типичные ошибки при разработке

Хранение JWT в открытом виде. SharedPreferences/UserDefaults доступны в бэкапах без шифрования. Только Keychain/Keystore.

Обновление всего списка при каждом рыночном тике. При 5+ открытых позициях и тике каждую секунду — постоянный rebuild всего списка. Нужно обновлять только изменившиеся ячейки: DiffableDataSource на iOS, key-параметр в LazyColumn на Android.

Игнорирование разрыва WebSocket. Соединение рвётся без события onError при смене сети. Нужен ping/pong: каждые 30 секунд отправляем ping, если за 10 секунд нет pong — считаем соединение мёртвым и переподключаемся.

Нет offline-режима. При отсутствии сети приложение показывает пустой экран. Минимум — кэшированные данные с меткой «данные от 14:30» и ProgressView при подключении.

Что входит в работу

  • Аутентификация (JWT + биометрия)
  • Dashboard с real-time позициями через WebSocket
  • Управление несколькими ботами
  • История сделок с пагинацией и фильтрами
  • Граф equity curve
  • Форма настроек стратегии с валидацией
  • Push-уведомления по трём уровням приоритета
  • Offline-режим с кэшированием

Сроки

Версия Состав Срок
MVP 1 бот, мониторинг, start/stop, push 10–14 дней
Полная Несколько ботов, стратегии, статистика, настройки 20–30 дней
С нуля + дизайн То же + UI/UX дизайн +5–7 дней

Стоимость рассчитывается индивидуально после анализа требований.