# Руководство по стратегиям свингов BQuant

Это руководство описывает доступные стратегии расчёта свингов в пайплайне анализа зон. Вы узнаете, чем отличаются ZigZag, FindPeaks и PivotPoints, как настраивать параметры и в каких сценариях каждая стратегия даёт наилучший результат.

## 🧭 Как выбрать стратегию

| Стратегия | Ключевая идея | Когда использовать | Основные параметры |
| --- | --- | --- | --- |
| `zigzag` | Фильтрация движений по процентному порогу (swing threshold) | Анализ трендов средней и большой длительности, волновые паттерны | `threshold`, `backstep`, `retrace` |
| `find_peaks` | Поиск локальных экстремумов по проминенции / ширине | Выявление резких импульсов, волатильные активы | `prominence`, `width`, `distance` |
| `pivot_points` | Комбинация свингов по свечам (high/low) | Классический технический анализ, ручная верификация уровней | `min_bars`, `max_bars`, `sensitivity` |

> 💡 **Совет:** Начните с ZigZag в глобальном режиме (`with_swing_scope('global')`) и адаптивного порога (`with_auto_swing_thresholds(True)`). Это даёт стабильную базу для отчётов и исследовательских ноутбуков.

## ⚙️ Общая конфигурация

```python
from bquant.analysis.zones import analyze_zones

builder = (
    analyze_zones(price_df)
    .detect_zones('zero_crossing', indicator_col='macd_hist')
    .with_swing_scope('global')
)

result = (
    builder
    .with_swing_strategy('zigzag', threshold=0.025, backstep=3)
    .analyze()
    .build()
)
```

`with_swing_strategy()` можно вызывать несколько раз: каждая стратегия получит собственный `SwingContext`, но анализатор объединит метрики в `ZoneInfo.swing_metrics`.

## ZigZagSwingStrategy

### Настройка ключевых параметров

- `threshold` — минимальное процентное изменение для фиксации свинга. Для дневных данных используйте диапазон 1–3%, для минутных — 0.3–1%.
- `backstep` — количество баров, в течение которых точка может быть пересмотрена, если появился более высокий/низкий экстремум.
- `retrace` — коэффициент частичного отката, при котором новый свинг считается подтверждённым.

```python
result = (
    builder
    .with_swing_strategy('zigzag', threshold=0.02, backstep=5, retrace=0.4)
    .analyze()
    .build()
)
```

### Адаптивные пороги

```python
result = (
    analyze_zones(price_df)
    .with_swing_scope('global')
    .with_swing_strategy('zigzag')
    .with_auto_swing_thresholds(True)  # рассчитывает threshold на историческом диапазоне
    .build()
)
```

- Адаптивный режим анализирует волатильность цены и подбирает `threshold` автоматически.
- Кэширование настроено на параметры стратегии, поэтому при смене индикатора или актива расчёт запускается заново.

## FindPeaksSwingStrategy

### Контроль проминенции и ширины

- `prominence` определяет минимальную высоту пика относительно соседей.
- `width` (или пара `width`, `rel_height`) контролирует, насколько «широким» должен быть экстремум.
- `distance` задаёт минимальное расстояние между пиками (в барах), предотвращая переизбыток свингов.

```python
result = (
    builder
    .with_swing_strategy('find_peaks', prominence=1.8, width=4, distance=6)
    .analyze()
    .build()
)
```

### Подсказки

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

## PivotPointsSwingStrategy

### Базовые параметры

- `min_bars` — минимальная длина свинга (количество баров между high/low).
- `max_bars` — верхнее ограничение для долгих свингов.
- `sensitivity` — коэффициент фильтрации мелких колебаний (0–1).

```python
result = (
    builder
    .with_swing_strategy('pivot_points', min_bars=3, max_bars=20, sensitivity=0.25)
    .analyze()
    .build()
)
```

### Работа с несколькими стратегиями

```python
result = (
    analyze_zones(price_df)
    .with_swing_scope('global')
    .with_swing_strategy('zigzag', threshold=0.018)
    .with_swing_strategy('pivot_points', min_bars=4, sensitivity=0.2)
    .analyze()
    .build()
)

for zone in result.zones:
    zigzag_swings = zone.get_zone_swings(strategy='zigzag')
    pivot_swings = zone.get_zone_swings(strategy='pivot_points')
    print(zone.zone_id, len(zigzag_swings), len(pivot_swings))
```

Если стратегия не найдена, метод `get_zone_swings()` выбросит исключение с подсказкой по доступным ключам. Это помогает обнаружить опечатку в названии стратегии.

## 📈 Проверка результатов

1. Используйте `ZoneAnalysisResult.visualize(zone_id=...)` (если доступен в вашей сборке) или собственные графики Matplotlib.
2. Сравнивайте количество свингов и амплитуды между стратегиями для одной и той же зоны.
3. Фиксируйте настройки в changelog: глобальный режим + конкретные параметры стратегии.

## 🧪 Контроль качества

- Запускайте smoke-тесты пайплайна (`tests/integration/test_pipeline_global_swings.py`), если модифицируете параметры по умолчанию.
- Проверяйте `ZoneInfo.metadata['swing_scope']` — он должен совпадать с режимом, который вы устанавливали в builder.
- Для исследовательских ноутбуков сохраняйте `SwingPoint`-объекты в `DataFrame`, чтобы повторно строить графики без пересчёта.

