# Переход на глобальный расчёт свингов

## Зачем переходить?

**Проблема:** локальный (per_zone) расчёт свингов не учитывает пивоты за пределами зоны и искажает метрики покрытия:
- `find_peaks`: свинги присутствуют только в 18.9% зон.
- `pivot_points`: свинги присутствуют только в 8.1% зон.
- `zigzag`: покрытие достигает лишь 62.2% зон.

**Решение:** глобальный режим вычисляет свинговые точки один раз на всём датасете и затем нарезает их по зонам.
- **70–90%** зон получают свинговые метрики (+20–50 п.п. к покрытию).
- **Быстрее**: одна прогонка стратегии вместо N запусков для каждой зоны.
- **Стабильнее**: нет артефактов на границах зон и пересчёта адаптивных порогов.

## Шаги миграции

### Шаг 1. Режим по умолчанию

**По умолчанию** используется `global`. Явно указывать не нужно:

```python
result = (
    analyze_zones(data)
    .with_strategies(swing='zigzag')
    .build()
)  # автоматически global
```

Для возврата к локальному расчёту используйте `.with_swing_scope('per_zone')`:

```python
result = (
    analyze_zones(data)
    .with_strategies(swing='zigzag')
    .with_swing_scope('per_zone')
    .build()
)
```

### Шаг 2. Используйте глобальные свинговые точки (при необходимости)

```python
for zone in result.zones:
    swings = zone.get_zone_swings()  # Возвращает List[SwingPoint]
    print(f"Zone {zone.zone_id}: {len(swings)} swing points")
```

Метод `get_zone_swings()` автоматически захватывает соседние пивоты, чтобы амплитуды и длительности свингов были корректными.

### Шаг 3. Очистите кэш результатов

```bash
rm -rf ~/.cache/bquant/zone_analysis_*.pkl
# или полная очистка:
rm -rf ~/.cache/bquant/*.pkl
```

Переход на глобальный режим увеличил версию кэша до `CACHE_VERSION = 2`. Старые результаты будут автоматически проигнорированы, но ручная очистка гарантирует отсутствие конфликта форматов.

## Ломающие изменения

Режим `global` используется **по умолчанию**. Для прежнего поведения (локальный расчёт) явно укажите `.with_swing_scope('per_zone')`.

## Диагностика и советы

- **Предупреждение про инвалидацию кэша?** Это ожидаемо при первом запуске с новой версией схемы.
- **Глобальный режим кажется медленнее?** На небольшом числе зон (≲10) локальный режим может быть быстрее. На десятках и сотнях зон глобальный режим выигрывает за счёт одного расчёта стратегии.
- **Некоторые зоны всё ещё без свингов?** Такое возможно для однобарных зон или диапазонов без внутренних пивотов. Проверьте ширину зоны и параметры стратегии.

## Производительность

- Рекомендуемый объём данных: до 1 млн баров.
- Бенчмарк: глобальный режим укладывается в ≤1.5× времени per_zone на датасете 100k баров и ~100 зон.
- Память: ≈264 байта на одну точку `SwingPoint`.

## Следующие шаги

- Подробное руководство: `docs/user_guide/zone_analysis.md` (раздел «Global vs Per-Zone Swing Calculation»).
- API-справка: `docs/api/analysis/zones/models.md` (описание `SwingPoint`, `SwingContext` и `ZoneInfo`).
- Пример использования: `examples/zone_analysis_global_swings.py` (минимальный сценарий глобального режима).
