# Справочник по кэшированию 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).

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

```python
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:

```python
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. Как очищать кэш

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

```python
# Полная очистка глобального кэша (память + диск)
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()`.

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

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

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

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

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

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

```python
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 настройка

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

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

```python
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. Связанные материалы

- [Zone Analysis Guide](zone_analysis.md) — раздел «Кэширование и персистентность»
- [Best Practices](best_practices.md) — хранение артефактов и переиспользование
- [Миграция global swings](../migration/global_swings_migration.md) — Шаг 3: очистка кэша при миграции
- [API: bquant.core.config](../api/core/config.md) — `get_cache_config()`, `CACHE_CONFIG`
