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

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

Проблема: локальный (per_zone) расчёт свингов не учитывает пивоты за пределами зоны и искажает метрики покрытия:

  • find_peaks: свинги присутствуют только в 18.9% зон.

  • pivot_points: свинги присутствуют только в 8.1% зон.

  • zigzag: покрытие достигает лишь 62.2% зон.

Решение: глобальный режим вычисляет свинговые точки один раз на всём датасете и затем нарезает их по зонам.

  • 70–90% зон получают свинговые метрики (+20–50 п.п. к покрытию).

  • Быстрее: одна прогонка стратегии вместо N запусков для каждой зоны.

  • Стабильнее: нет артефактов на границах зон и пересчёта адаптивных порогов.

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

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

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

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

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

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

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

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. Очистите кэш результатов

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 (минимальный сценарий глобального режима).