Ручной экспорт CSV с каждой биржи — потеря времени и источник ошибок. Один наш клиент тратил 20 часов в месяц на выгрузку с пяти площадок: Binance, Coinbase, Kraken, OKX и Bybit. После внедрения автоматизации время сократилось до пяти минут — экономия 240 часов в год. API-форматы меняются, пользователи забывают скачать данные, а бухгалтерия получает неполную картину. Автоматический импорт через API решает эти проблемы: транзакции синхронизируются в фоне, без вашего участия. Система поддерживает шесть популярных бирж, обрабатывает rate limits и пагинацию, нормализует данные в единую схему RawTransaction. Достигается 99,9% точности синхронизации. Автоматизация — необходимость для любого активного трейдера или криптокомпании. Сроки внедрения — от 3 до 4 недель, стоимость рассчитывается индивидуально.
Почему автоматический импорт транзакций с бирж — стандарт де-факто?
Ручной экспорт CSV перестаёт быть viable вариантом при росте объёмов. Даже для 100 сделок в день вероятность пропуска — 2–3 месяца. Автоматический импорт гарантирует полноту благодаря retry-механизмам и мониторингу. На одном проекте мы обнаружили, что 15% транзакций не попадали в бухгалтерию из-за смены формата CSV на бирже — автоматический импорт через API устойчив к таким изменениям, снижая количество ошибок до 0,1%.
Какие проблемы решает автоматический импорт транзакций с бирж?
Пользователи часто забывают экспортировать CSV, особенно при частых сделках. Автоматический импорт гарантирует, что ни одна сделка не потеряется. Каждая биржа выдает CSV в своем формате, поля различаются — наши импортеры нормализуют данные в единую структуру RawTransaction. Биржи лимитируют количество запросов, система использует очередь с экспоненциальной задержкой и параллельные запросы в рамках лимитов. Автоматизация исключает опечатки при переносе данных в учетную систему. В результате автоматический импорт в 240 раз быстрее ручного CSV: для трейдера с 1000+ сделок в день ручная выгрузка занимает несколько часов, а наша система обрабатывает всё за минуты.
Как мы строим систему импорта?
Используем TypeScript, Node.js, Bull Queue для очередей и PostgreSQL для хранения. Каждая биржа реализует интерфейс ExchangeImporter:
interface ExchangeImporter { importTransactions(apiKey: string, secretKey: string, since: Date): Promise<RawTransaction[]>; } Binance API — автоматический импорт транзакций
class BinanceImporter implements ExchangeImporter { private client: Binance; async importTransactions(apiKey: string, secretKey: string, since: Date): Promise<RawTransaction[]> { this.client = new Binance({ apiKey, secretKey }); const results = await Promise.all([ this.getSpotTrades(since), this.getConversions(since), this.getStakingHistory(since), this.getSavingsInterest(since), this.getFlexibleEarnings(since), this.getDustConversions(since), ]); return results.flat(); } private async getSpotTrades(since: Date): Promise<RawTransaction[]> { const symbols = await this.client.exchangeInfo().then(info => info.symbols.map(s => s.symbol) ); const trades: RawTransaction[] = []; for (const symbol of symbols) { const symbolTrades = await this.client.myTrades({ symbol, startTime: since.getTime(), limit: 1000, }); trades.push(...symbolTrades.map(t => this.normalizeBinanceTrade(t))); await sleep(100); } return trades; } private normalizeBinanceTrade(trade: any): RawTransaction { const baseAsset = trade.symbol.replace(/(USDT|BTC|ETH|BNB)$/, ""); const quoteAsset = trade.symbol.slice(baseAsset.length); return { id: trade.id.toString(), timestamp: new Date(trade.time), type: trade.isBuyer ? "buy" : "sell", assetIn: trade.isBuyer ? baseAsset : quoteAsset, amountIn: trade.isBuyer ? parseFloat(trade.qty) : parseFloat(trade.quoteQty), assetOut: trade.isBuyer ? quoteAsset : baseAsset, amountOut: trade.isBuyer ? parseFloat(trade.quoteQty) : parseFloat(trade.qty), fee: parseFloat(trade.commission), feeCurrency: trade.commissionAsset, exchange: "BINANCE", txId: trade.orderId.toString(), }; } } Coinbase Advanced Trade API
class CoinbaseImporter implements ExchangeImporter { async importTransactions(apiKey: string, secret: string, since: Date): Promise<RawTransaction[]> { const results = await Promise.all([ this.getFills(apiKey, secret, since), this.getConversions(apiKey, secret, since), this.getRewards(apiKey, secret, since), ]); return results.flat(); } private async getFills(apiKey: string, secret: string, since: Date): Promise<RawTransaction[]> { let cursor: string | undefined; const fills: any[] = []; do { const response = await this.request(apiKey, secret, "/brokerage/orders/historical/fills", { start_sequence_timestamp: since.toISOString(), cursor, }); fills.push(...response.fills); cursor = response.cursor; } while (cursor); return fills.map(this.normalizeCoinbaseFill); } } Сравнение ручного CSV и автоматического импорта
| Критерий | Ручной CSV | Автоматический импорт |
|---|---|---|
| Время на синхронизацию | 2-3 часа в неделю | 5 минут в месяц |
| Ошибки | до 10% пропусков | <0.1% ошибок |
| Масштабирование | трудоёмко | автоматически |
| Поддержка бирж | 1-2 | 6+ |
Как работает шедулер синхронизации?
Синхронизация запускается по расписанию с помощью Bull очереди. Шедулер проверяет активных пользователей, у которых последняя синхронизация была более 3 часов назад, и ставит задачи в очередь.
@Injectable() class ExchangeSyncScheduler { @Cron("0 */4 * * *") async syncActiveUsers() { const users = await this.db.getUsersWithApiKeys({ lastSyncBefore: new Date(Date.now() - 3 * 60 * 60 * 1000), isActive: true, }); for (const user of users) { await this.syncQueue.add("sync-exchange", { userId: user.id, since: user.lastSyncAt, }, { attempts: 3, backoff: { type: "exponential", delay: 5000 }, }); } } } class ExchangeSyncWorker { async processJob(job: Job<SyncJobData>) { const { userId, since } = job.data; const exchangeConnections = await this.db.getUserExchanges(userId); for (const connection of exchangeConnections) { try { const importer = this.importerFactory.create(connection.exchange); const transactions = await importer.importTransactions( connection.apiKey, connection.secretKey, since ); const normalized = transactions.map(tx => this.normalizer.normalize(tx)); const classified = await this.classifier.classifyBatch(normalized, userId); await this.db.upsertTransactions(userId, classified); await this.db.updateLastSync(userId, connection.exchange); } catch (err) { if (err instanceof ApiKeyExpiredError) { await this.notifyUserApiKeyExpired(userId, connection.exchange); } throw err; } } } } Типичные ошибки при интеграции с биржевыми API
- Истечение API-ключа без уведомления — система отправляет алерт.
- Неправильная обработка пагинации: некоторые биржи возвращают курсор, другие — offset. Наш импортер унифицирует этот процесс.
- Rate limits: превышение лимита приводит к блокировке ключа. Мы используем экспоненциальную задержку и параллельные запросы в пределах лимитов.
- Неучтённые типы транзакций: например, конвертации и стейкинг. Наши импортеры собирают все типы операций.
Поддерживаемые биржи
| Биржа | Метод | Ограничения |
|---|---|---|
| Binance | REST API (HMAC) | Rate limits, нужен запрос по каждой паре |
| Coinbase | OAuth 2.0 или API Key | Лимиты на history |
| Kraken | REST API | History ограничен |
| OKX | REST API | Хорошее API |
| Bybit | REST API | Нужны права на history |
| KuCoin | REST API | Пагинация по-своему |
Как настроить автоматический импорт: пошаговая инструкция
- Получить API-ключи на каждой бирже, задав минимальные права (чтение истории сделок).
- Подключить ключи в нашей системе через защищённый интерфейс. Ключи шифруются и хранятся в vault.
- Выбрать временной диапазон для синхронизации (например, с первого дня регистрации на бирже).
- Настроить расписание синхронизации: по умолчанию каждые 4 часа, но можно задать любой интервал.
- Проверить данные через дашборд: отображаются последние импортированные транзакции, ошибки и статус подключений.
Что входит в работу?
- Документация API — описание всех эндпоинтов, форматов данных и процедуры получения ключей.
- Исходный код импортеров — каждая биржа как отдельный модуль с тестами.
- Система мониторинга — уведомления об ошибках, сбоях API, истечении ключей.
- Консультация по безопасности — рекомендации по хранению API-ключей, настройке прав.
Получите консультацию по интеграции — обсудим ваши биржи, объем данных и необходимый функционал. Свяжитесь с нами для оценки вашего проекта.







