Справочник по кэшированию BQuant

💡 Для кого этот документ?

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

1. Обзор архитектуры кэширования

BQuant использует двухуровневую систему кэширования:

Уровень

Назначение

Расположение

Memory

Быстрый доступ, LRU-эвикция при переполнении

RAM процесса

Disk

Долговременное хранение между запусками

~/.cache/bquant/

Менеджер кэша (CacheManager) объединяет оба уровня: при get() сначала проверяется память, при промахе — диск. При записи данные сохраняются и в память, и на диск (если включён дисковый кэш).

Компоненты

  • bquant.core.cache — общий менеджер (CacheManager), MemoryCache, DiskCache, get_cache_manager(), clear_cache(), cache_stats().

  • bquant.analysis.zones.cache.ZoneAnalysisCache — специализированная обёртка для результатов анализа зон (версионирование, формирование ключей).

2. Где хранится кэш

Директория по умолчанию

~/.cache/bquant/

Файлы zone analysis: zone_analysis_<hash>.pkl (pickle).

Переопределение через конфигурацию

from bquant.core.config import CACHE_CONFIG, get_cache_config

# Текущая конфигурация
config = get_cache_config()
# {'enable_memory_cache': True, 'enable_disk_cache': True, 'memory_size': 100, ...}

Параметр cache_dir в CACHE_CONFIG (bquant.core.config) по умолчанию None — используется Path.home() / ".cache" / "bquant".

3. Кэширование Zone Analysis

Включение и отключение

Кэш включён по умолчанию. Управление через fluent API:

from bquant.analysis.zones import analyze_zones

# С кэшем (по умолчанию)
result = analyze_zones(df).detect_zones(...).build()

# Отключить кэш (для экспериментов, отладки)
result = analyze_zones(df).with_cache(enable=False).detect_zones(...).build()

# Кэш с TTL 2 часа
result = analyze_zones(df).with_cache(ttl=7200).detect_zones(...).build()

Формирование ключа кэша

Ключ определяется однозначно и включает:

  1. CACHE_VERSION (сейчас 2) — при изменении схемы результата.

  2. Хеш данных — OHLCV-колонки (open, high, low, close).

  3. Подпись конфигурации — индикатор, детекция, swing_scope, кластеризация, регрессия, валидация.

  4. Подпись свингов — пресет, стратегия, авто-пороги и т.п.

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

Автоматическая инвалидация по версии

При чтении из кэша проверяется cache_version в сохранённых метаданных:

  • Если cached_version < CACHE_VERSION → запись помечается как устаревшая, удаляется, возвращается None (пересчёт).

  • В лог пишется: "Cache invalidated due to schema upgrade (v1 v2). Recalculating...".

Ручная очистка при обновлении библиотеки не обязательна — устаревшие записи игнорируются автоматически.

4. Когда нужно очищать кэш

Ситуация

Действие

Изменение параметров пайплайна (индикатор, стратегии, пресет, scope)

Не требуется — новый ключ, новые записи

Обновление BQuant с изменением схемы результата

Не требуется — автo-инвалидация по версии

Подозрение на битые/устаревшие файлы

Очистить вручную

Освобождение места на диске

Очистить вручную

Отладка (исключить влияние кэша)

Отключить кэш .with_cache(enable=False) или очистить

5. Как очищать кэш

Программно (в коде)

# Полная очистка глобального кэша (память + диск)
from bquant.core.cache import clear_cache
clear_cache()

# Инвалидация только для конкретного датасета (требует доступ к pipeline)
from bquant.analysis.zones import analyze_zones
# ... построить pipeline с enable_cache=True ...
# pipeline.invalidate_cache(df)  # требует экземпляр ZoneAnalysisPipeline

Примечание: invalidate_cache(df) — метод ZoneAnalysisPipeline, вызывается после build() через возвращённый pipeline. Через fluent API напрямую вызывать нельзя; для полной очистки используйте clear_cache().

Вручную (в терминале)

# Очистить все файлы кэша zone analysis
rm -rf ~/.cache/bquant/zone_analysis_*.pkl

# Очистить весь кэш BQuant
rm -rf ~/.cache/bquant/*.pkl

# Удалить директорию кэша полностью
rm -rf ~/.cache/bquant

6. Настройка кэша

Глобальная конфигурация (bquant.core.config)

CACHE_CONFIG = {
    'enable_memory_cache': True,
    'enable_disk_cache': True,
    'memory_size': 100,        # макс. записей в памяти (LRU)
    'default_ttl': 3600,       # время жизни по умолчанию (секунды)
    'cache_dir': None,         # None = ~/.cache/bquant
    'auto_cleanup': True,
    'cleanup_interval': 300,
}

Изменение требует правки bquant/core/config.py или подмены до инициализации менеджера.

Per-pipeline настройка

result = (
    analyze_zones(df)
    .with_cache(enable=True, ttl=7200)  # 2 часа
    .detect_zones(...)
    .build()
)

7. Статистика и диагностика

from bquant.core.cache import cache_stats, get_cache_manager

# Общая статистика
stats = cache_stats()
# {'memory': {'entries': 5, 'hits': 120, 'misses': 10, 'hit_rate': 92.3, ...},
#  'disk': {'entries': 5, 'cache_dir': '/home/user/.cache/bquant'}}

# Очистка истекших записей
manager = get_cache_manager()
cleaned = manager.cleanup()
# {'memory_cleaned': 2, 'disk_cleaned': 1}

8. Особенности Zone Analysis Cache

Содержимое ключа

  • version — CACHE_VERSION.

  • data — хеш OHLCV.

  • config — хеш ZoneAnalysisConfig (indicator, zone_detection, clustering, regression, validation, swing_scope).

  • swing — хеш конфигурации свингов (preset, стратегии, авто-пороги).

Рекомендации

  • Исследования и A/B-тесты: .with_cache(enable=False) — чтобы не смешивать результаты разных параметров.

  • Продакшен и отчёты: оставить кэш включённым, задать ttl под частоту обновления данных.

  • Lambda и callable в правилах детекции: кэш может не работать (callable не сериализуется в ключ) — в таких случаях отключать кэш.

9. Связанные материалы