bquant.analysis.zones.models — Модели глобальных свингов

Этот раздел описывает новые структуры данных, которые поддерживают режим глобального расчёта свингов в пайплайне анализа зон.

SwingPoint

SwingPoint — дата-класс, описывающий одну точку свинга (пик или впадину), обнаруженную на глобальном ряду котировок. Экземпляры создаются стратегиями свингов один раз и переиспользуются для всех зон.

Поля

Поле

Тип

Описание

point_id

int

Уникальный идентификатор точки в последовательности свингов.

timestamp

datetime

Метка времени, совпадающая со значением индекса исходного DataFrame.

index

int

Позиция точки в полном датасете (iloc).

price

float

Цена инструмента в момент свинга.

swing_type

str

Тип точки: 'peak' или 'trough'.

amplitude_to_next

Optional[float]

Процентное изменение до следующей точки свинга (если она существует).

duration_to_next

Optional[int]

Количество баров до следующего свинга.

strategy_name

str

Название стратегии, обнаружившей свинг.

strategy_params

Dict[str, Any]

Параметры стратегии для трассируемости (по умолчанию пустой словарь).

Основные особенности

  • Структура полностью сериализуема: используется в SwingContext.to_dict() для кэширования.

  • Совместима с любыми стратегиями свингов — поля не зависят от конкретного алгоритма.

  • Позволяет сохранять не только геометрию свинга, но и метаданные стратегии (например, допуски ZigZag).

SwingContext

SwingContext агрегирует все SwingPoint, рассчитанные для полного набора данных. Контекст хранится на уровне пайплайна и передаётся в зоны, что устраняет повторные расчёты.

Ключевые поля

  • swing_points: List[SwingPoint] — упорядоченный список свингов.

  • indices: np.ndarray — отсортированный массив iloc-индексов, используемый для быстрых срезов через bisect.

  • full_data_length: int — размер исходного датафрейма (для валидации).

  • strategy_name: str и strategy_params: Dict[str, Any] — метаданные стратегии.

Методы

  • slice(start_idx: int, end_idx: int) -> List[SwingPoint]

    • Возвращает точки, попадающие в диапазон зоны, с захватом соседей слева и справа. Это обеспечивает корректные амплитуды при вычислении метрик.

  • get_swings_for_zone(zone: ZoneInfo) -> List[SwingPoint]

    • Удобный враппер над slice, использующий zone.start_idx и zone.end_idx.

  • to_dict() -> Dict[str, Any]

    • Сериализует весь контекст в словарь. Используется кэшем и для трассировки.

Типичные сценарии

from bquant.analysis.zones.models import SwingContext

context = strategy.calculate_global(prepared_df)
first_zone = result.zones[0]
zone_swings = context.get_swings_for_zone(first_zone)

ZoneInfo и глобальные свинги

ZoneInfo теперь содержит поле swing_context: Optional[SwingContext]. Пайплайн вызывает _inject_swing_context() сразу после детекции зон (см. соответствующий раздел), поэтому каждая зона получает ссылку на общий контекст.

Поле swing_context

  • Устанавливается только в режиме swing_scope="global".

  • Остаётся None в режиме per_zone, что сохраняет обратную совместимость.

  • Попадает в метод to_analyzer_format(), поэтому все анализаторы признаков имеют доступ к глобальным свингам.

Метод get_zone_swings()

ZoneInfo.get_zone_swings() извлекает список SwingPoint для конкретной зоны. Если контекст не инъектирован, метод возвращает пустой список — таким образом старые сценарии не ломаются.

zone = result.zones[0]
for point in zone.get_zone_swings():
    print(point.timestamp, point.price, point.swing_type)

Используйте этот метод в пользовательских метриках и визуализациях, чтобы работать с уже рассчитанными глобальными свингами без повторных вычислений.