VIZANIXРазработка торгового ПО
Архитектура ботовДанные6 мин чтения

Как хранить рыночные данные, не замедляя бота

Записывать всё — это то, что делает систему честной. Записывать синхронно — это то, что заставляет её пропускать рынок. Лечение скучное, и сделать его правильно стоит рано.

Инженеры Vizanix · об авторе

МАТЕРИАЛ
6 минвремя чтения
РАЗДЕЛ
Архитектура ботов
ОПУБЛИКОВАНО
2026-08-31
ГЛАВ
5
ЧИТАТЬ ДАЛЬШЕ
3
ЯЗЫК
написано на русском
Инженерный разбор, а не пересказ документации.
STORAGEPARQUETWALRETENTIONBATCHING

Смешивают две разные задачи. Хранение рыночных данных для исследования — задача пропускной способности. Хранение операционного состояния работающего бота — задача задержки. Им нужны разные решения, и одно решение на обе делает исследование медленным либо торговлю опоздавшей.

Три пути, три инструмента

ПутьТребованиеРазумный выбор
Горячий — торговый циклМикросекунды, без аллокацийКольцевые буферы в памяти. Без базы.
Тёплый — операционное состояние и телеметрияДолговечность, запросы, секунды приемлемыSQLite с WAL или Postgres при нескольких процессах
Холодный — исследовательский архивПропускная способность и сжатие, минуты приемлемыФайлы Parquet с разбиением по символу и дате

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

Никогда не пишите с горячего пути

Сканер, блокирующийся на записи на диск, перестал быть сканером. Паттерн — ограниченная очередь и поток-писатель, и очередь обязана быть ограниченной, иначе медленный диск превращается в неограниченный рост памяти.

python
# Ограничена намеренно: потерять телеметрию лучше, чем застопорить цикл.
queue: asyncio.Queue = asyncio.Queue(maxsize=50_000)

def record(event):
    try:
        queue.put_nowait(event)
    except asyncio.QueueFull:
        metrics.increment("telemetry_dropped")     # видимо, а не молча

async def writer():
    while True:
        batch = [await queue.get()]
        while len(batch) < 1000 and not queue.empty():
            batch.append(queue.get_nowait())
        await asyncio.to_thread(flush, batch)      # одна транзакция на пачку

Счётчик потерянных событий важен. Система, тихо отбрасывающая телеметрию под нагрузкой, выглядит здоровой ровно в тех условиях, данные о которых нужны больше всего.

Батчить по-настоящему

Одна вставка на событие — самая частая причина того, что слой хранения не справляется. Тысяча вставок в одной транзакции не в тысячу раз быстрее, но достаточно близко, чтобы менять границу возможного.

Наш сигнальный движок хранит 5,76 миллиона оценок за пятнадцать суток — каждую оценку со значениями факторов, а не только сработавшие. Это примерно 384 тысячи строк в сутки: ничем не примечательно при батчинге и невозможно по одной на пути оценки.

Индексируйте под те запросы, которые выполняются

Не под воображаемые. На практике для торговой системы это:

  • Последние N строк по одному символу — (symbol, id DESC)
  • Всё в диапазоне времени — (ts)
  • Недоставленные или сбойные элементы — частичный индекс по колонке статуса
  • Агрегация по дням для отчётности — обычно закрывается индексом по времени

Четыре индекса покрывают почти всё. Каждый дополнительный замедляет каждую запись, а на тёплом пути именно записи вам и не хватает.

Политика хранения, решённая заранее

Объём растёт быстрее ожидаемого, а решение удалять всегда принимается под давлением. Задайте политику до того, как это станет срочным:

  1. Сырые события стакана: дорого, полезно только для микроструктурного исследования. Держите заданное окно, если точно не нужно больше.
  2. Свечи: дёшево и полезно бессрочно. Держите.
  3. Оценки и решения: журнал аудита. Держите столько, сколько может понадобиться, чтобы объяснить сделку.
  4. Сделки и снимки эквити: держите вечно. Они малы и они и есть запись.

Наш конвейер свечей ведёт скользящий архив за семь суток с автоматическим доливом 1450 пар «монета — таймфрейм». Старые данные удаляются по расписанию, а не когда заполнится диск, — в этом разница между регламентной работой и инцидентом.

Статья описывает инженерную практику. Это не инвестиционная рекомендация. Vizanix разрабатывает программное обеспечение и не обещает торговую доходность.

Блог

Читать дальше

Эксплуатация · 7 мин

Мониторинг торгового бота: всё, кроме P&L

P&L рассказывает, что произошло. Он не рассказывает, исправна ли машина, которая это произвела, — а к моменту, когда P&L покажет сломанного бота, тот ломается уже давно.

Хотите такое у себя?

Мы пишем о том, что строим. Если нужно построить — напишите, разбор бесплатный.

Бриф

Получить оценку проекта

Четыре вопроса и контакт. Предоплата для разговора не нужна — если задача не наша, скажем сразу.

01Что вам нужно
02Биржа
03Рынок
04Стратегия
05Контакты

Проще написать напрямую? Telegram @vx_ceo

Обсудить систему