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.
✅ Чеклист перед реализацией
Определите входные данные и обязательные правила (
rules) конфигурации.Решите, какие типы зон (
zone_types) поддерживает стратегия.Продумайте набор полей
indicator_context, который требуется для последующих анализаторов.Подготовьте тесты: минимум unit-тест на
detect_zones()и сценарий интеграции сZoneAnalysisPipeline(см. раздел «Тестирование»).
🚀 Пошаговое создание стратегии
Сверьтесь с архитектурой. Перечитайте раздел «Точки расширения: Слой 1» (см. документацию), чтобы убедиться, что новая стратегия действительно расширяет слой детекции, а не дублирует существующие правила.
Определите контракт конфигурации. Зафиксируйте список обязательных правил (
REQUIRED_RULES) и ожидаемые типы данных. Обновите схемы в документации или конфигураторах, если добавляете новые ключи.Соберите входные данные. Опишите, какие поля
pd.DataFrameобязаны присутствовать, и подключите дополнительные индикаторы/источники данных (черезindicator_requirements).Реализуйте стратегию. Создайте модуль, следуя шаблону ниже, и зарегистрируйте класс через
@ZoneDetectionRegistry.register(см. документацию).Покройте контракт тестами. Напишите unit-тесты на валидацию правил, правильность
indicator_contextи регистрационный тест на интеграцию сZoneDetectionRegistry.Интегрируйте в pipeline. Добавьте сценарий в интеграционные тесты
ZoneAnalysisPipeline, чтобы зафиксировать ожидаемое поведение.Обновите документацию. Кратко опишите стратегию и её правила в соответствующих справочниках (API/конфигурации).
🧱 Базовый шаблон стратегии
# 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 |
Метод |
|
Registry |
Стратегия доступна через |
Используйте фикстуру |
Pipeline |
Интеграция с |
Добавьте сценарий в |
Пример минимального unit-теста:
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"
🔌 Использование в пайплайне
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 архитектуры (см. документацию) и отвечает за полный жизненный цикл анализа зон.
Жизненный цикл анализа
Извлечение признаков. Вызывает
ZoneFeaturesAnalyzer.extract_all_zones_featuresи дописывает полученные признаки обратно вzone.features.Статистика и гипотезы. Передаёт признаки в
ZoneFeaturesAnalyzer.analyze_zones_distributionиHypothesisTestSuite.run_all_tests.Последовательности и кластеры. Через
ZoneSequenceAnalyzerвыполняет анализ переходов и (опционально) кластеризацию.Регрессия и валидация. При включённых флагах делегирует работу
ZoneRegressionAnalyzerиValidationSuite.Сбор результатов. Формирует
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 и сослались на соответствующие разделы «Точки расширения» для ревьюеров.
📎 Полезные ссылки
Протокол и конфигурация (см. исходный код)
Реестр стратегий (см. исходный код)
Примеры существующих стратегий (см. исходный код)
📝 TODO перед завершением задачи
[ ] Добавить стратегию в список
docs/api/analysis/strategies.md(если это публичная возможность).[ ] Обновить соответствующие руководства пользователя/примеры.
[ ] Отразить изменение в
CHANGELOG.mdиMIGRATION_v2.md(при наличии breaking changes).[ ] Запустить
pytestдля unit и integration тестов, связанные с новой стратегией.