# Zone Detection Strategies — Developer Guide

## 🎯 Цель документа

Этот документ описывает процесс создания и сопровождения стратегий детекции зон для Universal Pipeline v2.1.
Он дополняет архитектурное описание и концентрируется на практических шагах,
которые необходимы разработчику для расширения слоя 1 — `ZoneDetectionStrategy`.

## 🧭 Когда нужна новая стратегия

Создавайте отдельную стратегию, если выполняется хотя бы одно условие:

- требуется другой способ маркировки зон, который нельзя выразить параметрами существующих стратегий (`zero_crossing`, `line_crossing`, `threshold`, `combined_rules`, `preloaded`);
- используются дополнительные источники данных или метрики (объём, корреляции, машинное обучение);
- нужно переиспользовать стратегию в разных пайплайнах через `ZoneDetectionRegistry`.

Если достаточно скорректировать правила (`rules`) существующей стратегии, создавайте новую конфигурацию `ZoneDetectionConfig`, а не новый класс.

## 🗂️ Структура пакета `bquant.analysis.zones.detection`

```
bquant/analysis/zones/detection/
├── __init__.py              # Экспорт Strategy, Config, Registry
├── base.py                  # Протокол ZoneDetectionStrategy + ZoneDetectionConfig
├── registry.py              # ZoneDetectionRegistry и декоратор @register
├── zero_crossing.py         # Стратегия пересечения нуля
├── line_crossing.py         # Стратегия пересечения линий
├── threshold.py             # Стратегия порогов (RSI и т.п.)
├── combined.py              # Комбинированные правила
└── preloaded.py             # Предзагруженные зоны
```

Новые стратегии размещаются рядом с существующими модулями и автоматически подключаются через `ZoneDetectionRegistry`.

## ✅ Чеклист перед реализацией

1. Определите входные данные и обязательные правила (`rules`) конфигурации.
2. Решите, какие типы зон (`zone_types`) поддерживает стратегия.
3. Продумайте набор полей `indicator_context`, который требуется для последующих анализаторов.
4. Подготовьте тесты: минимум unit-тест на `detect_zones()` и сценарий интеграции с `ZoneAnalysisPipeline` (см. раздел «Тестирование»).

## 🚀 Пошаговое создание стратегии

1. **Сверьтесь с архитектурой.** Перечитайте раздел «Точки расширения: Слой 1» (см. документацию), чтобы убедиться, что новая стратегия действительно расширяет слой детекции, а не дублирует существующие правила.
2. **Определите контракт конфигурации.** Зафиксируйте список обязательных правил (`REQUIRED_RULES`) и ожидаемые типы данных. Обновите схемы в документации или конфигураторах, если добавляете новые ключи.
3. **Соберите входные данные.** Опишите, какие поля `pd.DataFrame` обязаны присутствовать, и подключите дополнительные индикаторы/источники данных (через `indicator_requirements`).
4. **Реализуйте стратегию.** Создайте модуль, следуя шаблону ниже, и зарегистрируйте класс через `@ZoneDetectionRegistry.register` (см. документацию).
5. **Покройте контракт тестами.** Напишите unit-тесты на валидацию правил, правильность `indicator_context` и регистрационный тест на интеграцию с `ZoneDetectionRegistry`.
6. **Интегрируйте в pipeline.** Добавьте сценарий в интеграционные тесты `ZoneAnalysisPipeline`, чтобы зафиксировать ожидаемое поведение.
7. **Обновите документацию.** Кратко опишите стратегию и её правила в соответствующих справочниках (API/конфигурации).

## 🧱 Базовый шаблон стратегии

```python
# bquant/analysis/zones/detection/my_strategy.py
from typing import List

import pandas as pd

from .base import ZoneDetectionStrategy, ZoneDetectionConfig
from .registry import ZoneDetectionRegistry
from ..models import ZoneInfo


@ZoneDetectionRegistry.register(
    name="my_strategy",
    indicator_requirements=["my_indicator"],  # отображается в list_strategies()
    description="Detects custom bullish/bearish zones based on My Indicator."
)
class MyStrategy(ZoneDetectionStrategy):
    """Детекция зон по кастомным правилам."""

    REQUIRED_RULES = ["my_indicator"]

    def detect_zones(
        self, data: pd.DataFrame, config: ZoneDetectionConfig
    ) -> List[ZoneInfo]:
        # 1. Валидация правил и получение параметров
        config.validate(self.REQUIRED_RULES)
        indicator = config.rules["my_indicator"]

        # 2. Собственно логика детекции
        #    (здесь примерная заготовка, замените на ваши условия)
        positives = data[data[indicator] > 0]
        if positives.empty:
            return []

        start_label = positives.index[0]
        end_label = positives.index[-1]
        start_idx = data.index.get_loc(start_label)
        end_idx = data.index.get_loc(end_label)

        # 3. Конструирование ZoneInfo с обязательным indicator_context
        zone = ZoneInfo(
            zone_id=0,
            type="bull",
            start_idx=start_idx,
            end_idx=end_idx,
            start_time=start_label.to_pydatetime(),
            end_time=end_label.to_pydatetime(),
            duration=end_idx - start_idx + 1,
            data=data.iloc[start_idx : end_idx + 1],
            indicator_context={
                "detection_strategy": "my_strategy",
                "detection_indicator": indicator,
                "detection_rules": config.rules,
            },
        )

        return [zone]
```

### Обязательные элементы шаблона

- `@ZoneDetectionRegistry.register(...)` — регистрирует стратегию и публикует метаданные.
- `REQUIRED_RULES` — список обязательных полей `rules`, используемый в `config.validate(...)`.
- Возвращаемые `ZoneInfo` должны заполнять `indicator_context` как минимум полями `detection_strategy` и `detection_indicator` (требования контракта v2.1).

## 🧪 Тестирование стратегии

| Тип теста | Что проверяем | Пример |
|-----------|---------------|--------|
| Unit      | Метод `detect_zones()` возвращает ожидаемые зоны и заполняет `indicator_context`. | `tests/unit/zones/detection/test_my_strategy.py` |
| Registry  | Стратегия доступна через `ZoneDetectionRegistry.get('my_strategy')`. | Используйте фикстуру `registry_cleanup` (см. `tests/conftest.py`). |
| Pipeline  | Интеграция с `ZoneAnalysisPipeline` через `ZoneDetectionConfig`. | Добавьте сценарий в `tests/integration/zones/test_pipeline_strategies.py`. |

Пример минимального unit-теста:

```python
def test_my_strategy_detects_zone(sample_indicator_df):
    strategy = MyStrategy()
    config = ZoneDetectionConfig(
        strategy_name="my_strategy",
        rules={"my_indicator": "signal"},
    )

    zones = strategy.detect_zones(sample_indicator_df, config)

    assert zones
    assert zones[0].indicator_context["detection_strategy"] == "my_strategy"
    assert zones[0].indicator_context["detection_indicator"] == "signal"
```

## 🔌 Использование в пайплайне

```python
from bquant.analysis.zones.pipeline import ZoneAnalysisPipeline
from bquant.analysis.zones.detection import ZoneDetectionConfig

pipeline = (
    ZoneAnalysisPipeline()
    .with_data(source="df", data=df)
    .detect_zones(
        ZoneDetectionConfig(
            strategy_name="my_strategy",
            rules={"my_indicator": "signal"},
        )
    )
    .analyze()
    .build()
)

result = pipeline.run()
```

После регистрации стратегия автоматически появится в `ZoneDetectionRegistry.list_strategies()` и станет доступна в документации API (см. `docs/api/analysis/strategies.md`).

## ♻️ Расширение UniversalZoneAnalyzer

`UniversalZoneAnalyzer` относится к слою 2 архитектуры (см. документацию) и отвечает за полный жизненный цикл анализа зон.

### Жизненный цикл анализа

1. **Извлечение признаков.** Вызывает `ZoneFeaturesAnalyzer.extract_all_zones_features` и дописывает полученные признаки обратно в `zone.features`.
2. **Статистика и гипотезы.** Передаёт признаки в `ZoneFeaturesAnalyzer.analyze_zones_distribution` и `HypothesisTestSuite.run_all_tests`.
3. **Последовательности и кластеры.** Через `ZoneSequenceAnalyzer` выполняет анализ переходов и (опционально) кластеризацию.
4. **Регрессия и валидация.** При включённых флагах делегирует работу `ZoneRegressionAnalyzer` и `ValidationSuite`.
5. **Сбор результатов.** Формирует `ZoneAnalysisResult` с агрегированной метаинформацией.

Полный код жизненного цикла см. в `bquant/analysis/zones/analyzer.py`.

### Интерфейсы расширения

Каждый компонент конструктора `UniversalZoneAnalyzer` принимает DI-объект. Чтобы расширить слой 2:

- **Features Analyzer** (`features_analyzer`): реализуйте метод `extract_all_zones_features` и опционально дополнительные анализы распределения.
- **Hypothesis Suite** (`hypothesis_suite`): предоставьте `run_all_tests`, возвращающий словарь результатов гипотез.
- **Sequence Analyzer** (`sequence_analyzer`): реализуйте `analyze_zone_transitions` и, при необходимости, `cluster_zones`.
- **Regression Analyzer** (`regression_analyzer`): предоставьте методы `predict_zone_duration` и `predict_price_return`.
- **Validation Suite** (`validation_suite`): внедрите проверки качества, совместимые с сигнатурой `.validate(...)` (см. текущую реализацию в `bquant.analysis.validation`).

При добавлении новых DI-компонентов синхронизируйте описание с документацией и обновите примеры использования в API-документации.

## 🤝 Contribution guide для новых стратегий и анализаторов

Разработчики, расширяющие слой 1 (стратегии) или слой 2 (анализаторы), должны соблюдать следующие требования:

- **Тесты.**
  - Unit-тесты покрывают основную логику (`detect_zones`, кастомные анализаторы признаков и т.п.).
  - Регистрационные тесты подтверждают, что новые классы доступны через DI/registry.
  - Интеграционные сценарии `ZoneAnalysisPipeline` запускаются с новой стратегией/анализатором.
- **Документация.**
  - Обновите developer guide (этот документ) и профильные страницы API/конфигураций.
  - Добавьте примеры конфигурации и использования, включая параметры `rules` и флаги анализатора.
- **Проверки.**
  - Выполните `pytest` для затронутых пакетов.
  - Прогоните статический анализ (например, `ruff`, `mypy` или используемые в проекте инструменты) при изменении Python-кода.
  - Обновите `CHANGELOG`/`CHANGE_TRACE_LOG`, если изменение публичное.
  - Убедитесь, что линтеры и форматтеры (например, `ruff --fix`, `black`) не оставляют нарушений.

Зафиксируйте результаты проверок в описании pull request и сослались на соответствующие разделы «Точки расширения» для ревьюеров.

## 📎 Полезные ссылки

- [Zone Analysis Pipeline](../api/analysis/pipeline.md)
- Протокол и конфигурация (см. исходный код)
- Реестр стратегий (см. исходный код)
- Примеры существующих стратегий (см. исходный код)

## 📝 TODO перед завершением задачи

- [ ] Добавить стратегию в список `docs/api/analysis/strategies.md` (если это публичная возможность).
- [ ] Обновить соответствующие руководства пользователя/примеры.
- [ ] Отразить изменение в `CHANGELOG.md` и `MIGRATION_v2.md` (при наличии breaking changes).
- [ ] Запустить `pytest` для unit и integration тестов, связанные с новой стратегией.
