# bquant.analysis.zones.strategies — Стратегии свингов Раздел описывает контракт `SwingCalculationStrategy` и обновлённые реализации ZigZag, FindPeaks и PivotPoints после перехода на глобальный расчёт свингов. ## Протокол `SwingCalculationStrategy` Все стратегии должны соответствовать протоколу `SwingCalculationStrategy` (см. `bquant/analysis/zones/strategies/base.py`). Ключевые методы: ### `calculate_global(full_data: pd.DataFrame) -> SwingContext` - Выполняет единичный проход по подготовленному датафрейму и возвращает `SwingContext`. - Должен логировать основные параметры стратегии (делается внутри реализации стратегии). - Используется пайплайном в режиме `swing_scope="global"`. ### `aggregate_for_zone(zone: ZoneInfo, context: SwingContext) -> SwingMetrics` - Преобразует глобальные точки свинга в метрики конкретной зоны. - Работает с neighbor-aware срезом из `SwingContext.slice()`, чтобы корректно оценивать амплитуды. - Обязан возвращать `SwingMetrics` с заполненными метаданными (`strategy_name`, `strategy_params`). ### `calculate(zone_data: pd.DataFrame) -> SwingMetrics` - Сохраняет совместимость со старым режимом `per_zone`. - Может вызывать `aggregate_for_zone`, создавая временный `SwingContext` (как делает ZigZag/FindPeaks/PivotPoints). ### `get_metadata()` и `config_hash()` - Методы остаются без изменений: используются пайплайном и кэшем. ## ZigZagSwingStrategy Файл: `bquant/analysis/zones/strategies/swing/zigzag.py` - `calculate_global()` запускает ZigZag на полном наборе данных, формирует список `SwingPoint` и собирает `SwingContext`. - `aggregate_for_zone()` срезает точки через `context.slice()` и вычисляет метрики (количество свингов, амплитуды, симметрию и т.д.). - При отсутствии глобального контекста `calculate()` переходит к локальному расчёту, сохраняя поведение прошлых версий. ## FindPeaksSwingStrategy Файл: `bquant/analysis/zones/strategies/swing/find_peaks.py` - `calculate_global()` использует `scipy.signal.find_peaks`/`find_troughs` и формирует `SwingContext`. - `aggregate_for_zone()` применяет общую вспомогательную функцию `_aggregate_metrics()` для расчёта амплитуд и длительностей. - Локальный метод `calculate()` продолжает работать для совместимости, но теперь реиспользует глобальную логику. ## PivotPointsSwingStrategy Файл: `bquant/analysis/zones/strategies/swing/pivot_points.py` - `calculate_global()` строит пивоты по методике классических pivot points и сохраняет результаты в `SwingContext`. - `aggregate_for_zone()` повторно использует общую агрегацию, возвращая метрики, даже если в зоне нет внутренних пивотов (в таком случае срабатывает neighbor padding). - Локальный `calculate()` остаётся в коде для совместимости с прежними пайплайнами. ## Общие рекомендации - Для пользовательских стратегий реализуйте `calculate_global` и `aggregate_for_zone`, затем зарегистрируйте стратегию через `StrategyRegistry`. - Если необходимо поддержать только локальный режим, явно документируйте это и бросайте `NotImplementedError` в `calculate_global` — пайплайн отработает фолбэком. - Проверьте, что `strategy_params` включают ключевые настройки (например, `deviation` для ZigZag или `min_prominence` для FindPeaks) — это повышает трассируемость. Такая унификация интерфейса упрощает расширение набора стратегий и делает результаты свингов сопоставимыми между зонами.