Files
dzentra_bot/docs/migrations/build_051.md

14 KiB
Raw Permalink Blame History

Build 051 — Переключение HTF-анализа на канонические Candle

Статус

Завершён


Цель Build

Переключить оба HTF-пути подсистемы Market Analysis с legacy API:

ExchangeService.get_klines()
    ↓
KlineBatch
    ↓
batch.candles

на канонический API:

ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

без изменения существующей HTF-семантики, расчётных алгоритмов, порогов, payload-полей и диагностических причин.


Исходное состояние

До Build 051 в файле:

src/trading/market_analysis/htf.py

существовали два legacy-пути получения свечей:

htf_volatility_context()
htf_trend_context()

Оба использовали:

ExchangeService.get_klines()

и затем извлекали:

batch.candles

После Build 050 основной MarketAnalysisService уже был переключён на:

ExchangeService.get_candles()

Поэтому htf.py оставался последним активным production-потребителем get_klines() внутри src/trading/market_analysis.


Объём изменений

В Build 051 изменены:

src/trading/market_analysis/htf.py
tests/unit/trading/market_analysis/test_htf_candles.py
docs/migrations/build_051.md

Build 051 не изменяет:

src/trading/market_analysis/service.py
src/integrations/exchange/service.py
src/integrations/exchange/models.py
src/market_data/acquisition/

Build также не удаляет:

ExchangeService.get_klines()
Kline
KlineBatch
_kline_from_candle()

Их удаление возможно только после отдельной общей проверки всех production-потребителей.


Переключение htf_volatility_context()

До Build 051:

htf_volatility_context()
    ↓
ExchangeService.get_klines()
    ↓
KlineBatch
    ↓
batch.candles

После Build 051:

htf_volatility_context()
    ↓
ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

Удалена зависимость от:

batch.candles

Все остальные расчёты сохранены.


Переключение htf_trend_context()

До Build 051:

htf_trend_context()
    ↓
ExchangeService.get_klines()
    ↓
KlineBatch
    ↓
batch.candles

После Build 051:

htf_trend_context()
    ↓
ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

Удалена зависимость от legacy-контейнера KlineBatch.


Каноническая модель Candle

После Build 051 оба HTF-пути непосредственно получают:

tuple[Candle, ...]

Каноническая модель:

src.market_data.acquisition.models.candle.Candle

использует:

Decimal

для полей:

open_price
high_price
low_price
close_price
volume

Поэтому для вычислительных функций была сохранена явная числовая граница:

Decimal
    ↓
safe_float(...)
    ↓
isfinite(...)
    ↓
float

Числовая граница в htf_volatility_context()

В htf_volatility_context() последняя цена закрытия преобразуется через:

safe_float()

и дополнительно проверяется через:

math.isfinite()

Невалидные значения:

NaN
Infinity
-Infinity

не допускаются к вычислению ATR percent.

При невозможности получить корректную цену закрытия сохраняется существующая причина:

HTF_ATR_UNAVAILABLE

Числовая граница в htf_trend_context()

В htf_trend_context() формируется:

closes: list[float]

Каждая каноническая цена:

Candle.close_price

проходит:

safe_float()
isfinite()

Если хотя бы одно значение невалидно, HTF-анализ возвращает существующую причину:

HTF_INDICATORS_UNAVAILABLE

Невалидные значения не пропускаются выборочно, поскольку это нарушило бы соответствие:

candles[index] ↔ closes[index]

Сохранение диагностического контракта

Несмотря на переход с get_klines() на get_candles(), существующая причина ошибки получения данных сохранена:

HTF_KLINES_ERROR

Она используется в обоих HTF-путях.

Переименование в:

HTF_CANDLES_ERROR

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


Сохранённая логика htf_volatility_context()

Без изменений сохранены:

проверка одинакового base и HTF interval
минимальное количество свечей
ATR
close price validation
ATR percent
ATR percent baseline
volatility ratio
classify_volatility()
rounding
формат payload
HTF_SKIPPED_SAME_INTERVAL
HTF_NOT_ENOUGH_CANDLES
HTF_ATR_UNAVAILABLE
HTF_OK

Сохранённая логика htf_trend_context()

Без изменений сохранены:

проверка одинакового base и HTF interval
минимальное количество свечей
EMA fast
EMA slow
ATR
ATR percent
adaptive thresholds
EMA slopes
trend classification
trend gap
trend strength
trend consistency
trend efficiency
EMA distance / ATR
candle noise score
price position score
trend quality
market phase
market state
alignment
confirmation score
формат HTF payload

Новый тестовый файл

Добавлен:

tests/unit/trading/market_analysis/test_htf_candles.py

Файл создан отдельно, поскольку до Build 051 специализированного test_htf.py в проекте не существовало.


Покрытие htf_volatility_context()

Тесты проверяют:

  1. пропуск запроса при одинаковом base и HTF interval;
  2. точные аргументы get_candles();
  3. сохранение причины HTF_KLINES_ERROR;
  4. сохранение причины HTF_NOT_ENOUGH_CANDLES;
  5. отклонение не конечной close price;
  6. сохранение причины HTF_ATR_UNAVAILABLE;
  7. успешный HTF volatility payload;
  8. поддержку canonical Candle с Decimal.

Покрытие htf_trend_context()

Тесты проверяют:

  1. пропуск запроса при одинаковом base и HTF interval;
  2. точные аргументы get_candles();
  3. сохранение причины HTF_KLINES_ERROR;
  4. сохранение причины HTF_NOT_ENOUGH_CANDLES;
  5. отклонение не конечной close price;
  6. сохранение причины HTF_INDICATORS_UNAVAILABLE;
  7. преобразование Decimal closes в float;
  8. успешный HTF trend payload;
  9. неизменность структуры результата.

Targeted tests

Выполнена команда:

python -m pytest -q \
  tests/unit/trading/market_analysis/test_htf_candles.py

Результат:

11 passed in 0.12s

Regression-набор Market Analysis и стратегий

Выполнена команда:

python -m pytest -q \
  tests/unit/trading/market_analysis \
  tests/unit/trading/strategies/test_scalp_quote.py \
  tests/unit/trading/strategies/test_trend_quote.py

Результат:

38 passed in 0.14s

Полный regression suite

Выполнена команда:

python -m pytest -q

Результат:

805 passed in 2.72s

Регрессий не обнаружено.


Контроль отсутствия get_klines() в Market Analysis

Выполнена команда:

grep -RIn \
  --exclude-dir="__pycache__" \
  --exclude="*.pyc" \
  "\.get_klines(" \
  src/trading/market_analysis

Результат:

пусто

Это подтверждает, что в активном production-коде Market Analysis больше нет вызовов:

ExchangeService.get_klines()

Контроль использования get_candles()

Выполнена команда:

grep -RIn \
  --exclude-dir="__pycache__" \
  --exclude="*.pyc" \
  "\.get_candles(" \
  src/trading/market_analysis

Результат:

src/trading/market_analysis/service.py:244:            candles = ExchangeService().get_candles(
src/trading/market_analysis/htf.py:57:        candles = ExchangeService().get_candles(
src/trading/market_analysis/htf.py:157:        candles = ExchangeService().get_candles(

После Build 051 в Market Analysis существует ровно три production-вызова канонического API.


Контроль legacy batch-зависимостей

Выполнена команда:

grep -RIn \
  --exclude-dir="__pycache__" \
  --exclude="*.pyc" \
  "batch\.candles\|batch\.symbol\|KlineBatch\|Kline" \
  src/trading/market_analysis

Результат:

src/trading/market_analysis/indicators_legacy.py:5:from src.integrations.exchange.models import Kline
src/trading/market_analysis/indicators_legacy.py:21:def atr(candles: list[Kline], period: int = 14) -> float | None:

Следовательно:

  • активные production-компоненты Market Analysis больше не зависят от Kline;
  • единственная оставшаяся зависимость находится в подтверждённом неиспользуемом legacy-файле;
  • indicators_legacy.py намеренно не изменяется в Build 051.

Проверка форматирования

Выполнена команда:

git diff --check

Вывод отсутствует.

Whitespace-ошибок не обнаружено.


Архитектурный результат

После Build 051 весь активный production-путь Market Analysis использует канонические свечи:

MarketAnalysisService
    ↓
ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

HTF volatility
    ↓
ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

HTF trend
    ↓
ExchangeService.get_candles()
    ↓
tuple[Candle, ...]

Legacy API:

ExchangeService.get_klines()

больше не используется активным Market Analysis.


Что намеренно не выполнено

Build 051 намеренно не включает:

  • удаление ExchangeService.get_klines();
  • удаление Kline;
  • удаление KlineBatch;
  • удаление _kline_from_candle();
  • удаление indicators_legacy.py;
  • изменение диагностической причины HTF_KLINES_ERROR;
  • изменение алгоритмов HTF;
  • изменение торговой логики;
  • изменение порогов;
  • изменение scoring;
  • изменение Market Data Acquisition;
  • изменение структуры каталогов;
  • удаление рабочего compatibility-кода.

Критерии завершения

Build 051 считается завершённым, поскольку:

  • оба HTF-пути используют get_candles();
  • зависимости batch.candles удалены;
  • Decimal close prices безопасно преобразуются в float;
  • NaN и бесконечности отклоняются;
  • существующие диагностические причины сохранены;
  • HTF payload не изменён;
  • специализированные тесты проходят;
  • regression-набор проходит;
  • полный suite проходит;
  • get_klines() отсутствует во всём активном Market Analysis;
  • legacy Kline остаётся только в неиспользуемом indicators_legacy.py;
  • git diff --check чистый.

Итог

Build 051 завершён успешно.

Текущее состояние:

MarketAnalysisService → get_candles()
HTF volatility        → get_candles()
HTF trend             → get_candles()

Результаты:

Targeted HTF tests: 11 passed
Market Analysis + strategies: 38 passed
Full test suite: 805 passed
git diff --check: clean

Следующий безопасный этап — общая проверка всех оставшихся production-потребителей:

ExchangeService.get_klines()
Kline
KlineBatch
_kline_from_candle()

Только после этой проверки можно определять отдельный Build по удалению compatibility bridge.