Ручной экспорт 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-ключей, настройке прав.
Получите консультацию по интеграции — обсудим ваши биржи, объем данных и необходимый функционал. Свяжитесь с нами для оценки вашего проекта.







