14 KiB
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()
Тесты проверяют:
- пропуск запроса при одинаковом base и HTF interval;
- точные аргументы
get_candles(); - сохранение причины
HTF_KLINES_ERROR; - сохранение причины
HTF_NOT_ENOUGH_CANDLES; - отклонение не конечной close price;
- сохранение причины
HTF_ATR_UNAVAILABLE; - успешный HTF volatility payload;
- поддержку canonical
CandleсDecimal.
Покрытие htf_trend_context()
Тесты проверяют:
- пропуск запроса при одинаковом base и HTF interval;
- точные аргументы
get_candles(); - сохранение причины
HTF_KLINES_ERROR; - сохранение причины
HTF_NOT_ENOUGH_CANDLES; - отклонение не конечной close price;
- сохранение причины
HTF_INDICATORS_UNAVAILABLE; - преобразование
Decimalcloses вfloat; - успешный HTF trend payload;
- неизменность структуры результата.
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удалены; Decimalclose 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.