Files
dzentra_bot/docs/migrations/build_048.md

907 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Build 048 — Переключение вычислительных потребителей Market Analysis на каноническую модель Candle
**Статус:** Completed
**Дата:** 2026-07-15
**Подсистема:** Market Data Acquisition / OHLCV Feed / Market Analysis
---
## 1. Назначение Build
Build 048 переводит активные вычислительные компоненты подсистемы `Market Analysis`, непосредственно работающие с последовательностями рыночных свечей, с legacy-модели:
```text
src.integrations.exchange.models.Kline
```
на каноническую модель рыночной свечи:
```text
src.market_data.acquisition.models.candle.Candle
```
Build является очередным этапом поэтапной миграции получения и использования OHLCV-данных в канонический слой:
```text
Market Data Acquisition
```
Основная цель Build — устранить прямую зависимость активных вычислительных функций анализа рынка от legacy-модели `Kline`, сохранив существующую торговую семантику и поведение системы.
---
## 2. Контекст миграции
До Build 048 канонический OHLCV pipeline уже был создан и интегрирован поэтапно.
### Build 044
Создан фундамент канонического Candles Feed:
```text
REST transport
schema validation
parser
value validation
mapper
Candle
handler
CandlesFeed
```
Каноническая модель:
```text
src/market_data/acquisition/models/candle.py
```
### Build 045
Создан и протестирован:
```text
CandlesFeedRegistry
```
### Build 046
Создан и интегрирован:
```text
CandlesAcquisitionService
```
### Build 047
Legacy-метод:
```text
ExchangeService.get_klines()
```
переключён на канонический Candles Feed.
После Build 047 транспортный запрос:
```text
/api/v1/klines
```
выполняется только внутри:
```text
src/market_data/acquisition/adapters/dzengi/rest.py
```
При этом `ExchangeService.get_klines()` временно сохраняет обратную совместимость и преобразует канонические `Candle` обратно в legacy-модели `Kline`.
Build 048 начинает устранять эту обратную legacy-зависимость непосредственно внутри вычислительных потребителей `Market Analysis`.
---
## 3. Границы Build
В Build 048 изменены только активные вычислительные компоненты `Market Analysis`, которые непосредственно принимают последовательности свечей и используют поля OHLCV.
Изменены:
```text
src/trading/market_analysis/indicators/volatility.py
src/trading/market_analysis/quality.py
src/trading/market_analysis/structure.py
```
Добавлены специализированные unit-тесты:
```text
tests/unit/trading/market_analysis/indicators/test_volatility_candle.py
tests/unit/trading/market_analysis/test_quality_candle.py
tests/unit/trading/market_analysis/test_structure_candle.py
```
Build 048 не изменяет:
```text
src/trading/market_analysis/service.py
src/trading/market_analysis/htf.py
src/trading/market_analysis/indicators_legacy.py
src/integrations/exchange/service.py
src/integrations/exchange/models.py
```
Build также не удаляет:
```text
Kline
KlineBatch
ExchangeService.get_klines()
```
Их дальнейшая судьба определяется отдельными последующими этапами миграции.
---
## 4. Основное архитектурное изменение
До Build 048 активные вычислительные функции использовали legacy-модель:
```python
from src.integrations.exchange.models import Kline
```
После Build 048 они используют каноническую модель:
```python
from src.market_data.acquisition.models.candle import Candle
```
Изменение выполнено в:
```text
src/trading/market_analysis/indicators/volatility.py
src/trading/market_analysis/quality.py
src/trading/market_analysis/structure.py
```
Таким образом, активные вычислительные функции:
```text
atr()
atr_percent_baseline()
candle_noise_score()
market_structure()
```
больше не зависят от:
```text
src.integrations.exchange.models.Kline
```
и работают непосредственно с:
```text
src.market_data.acquisition.models.candle.Candle
```
---
## 5. Адаптация к канонической модели Candle
Каноническая модель `Candle` использует точные числовые значения:
```text
Decimal
```
для полей:
```text
open_price
high_price
low_price
close_price
volume
```
Legacy-модель `Kline` использовала:
```text
float
```
Поэтому Build 048 выполняет явную адаптацию вычислительного слоя к `Decimal`.
Для безопасного преобразования используется существующий helper:
```text
src.core.numbers.safe_float
```
Числовые значения преобразуются непосредственно на границе вычислений.
Принцип:
```text
Candle
Decimal OHLCV
safe_float(...)
float
существующая вычислительная логика Market Analysis
```
Это позволяет:
- сохранить точность канонической модели данных;
- не переносить `float` в слой Market Data Acquisition;
- сохранить существующие вычислительные алгоритмы;
- минимизировать область изменений;
- не изменять торговую семантику в рамках миграционного Build.
---
## 6. Изменения volatility.py
Файл:
```text
src/trading/market_analysis/indicators/volatility.py
```
переведён с:
```text
Sequence[Kline]
```
на:
```text
Sequence[Candle]
```
Адаптированы функции:
```text
atr()
atr_percent_baseline()
```
Поля канонической модели:
```text
previous.close_price
current.high_price
current.low_price
```
преобразуются через:
```text
safe_float(...)
```
Дополнительно выполняется проверка:
```text
math.isfinite(...)
```
для исключения нечисловых конечных значений:
```text
NaN
Infinity
-Infinity
```
Это необходимо, поскольку преобразование:
```text
Decimal("NaN")
```
в `float` само по себе не возвращает `None`, а создаёт:
```text
float("nan")
```
Без проверки `isfinite()` такое значение могло проникнуть в вычисление ATR.
---
## 7. Изменения quality.py
Файл:
```text
src/trading/market_analysis/quality.py
```
переведён с:
```text
Sequence[Kline]
```
на:
```text
Sequence[Candle]
```
Адаптирована функция:
```text
candle_noise_score()
```
Поля:
```text
high_price
low_price
open_price
close_price
```
преобразуются через:
```text
safe_float(...)
```
и проверяются через:
```text
isfinite(...)
```
Невалидные свечи не участвуют в расчёте.
Если после фильтрации отсутствуют допустимые свечи, функция возвращает:
```text
None
```
Существующая функция:
```text
price_position_score()
```
сохранена.
Build 048 не изменяет её назначение и вычислительную семантику.
---
## 8. Изменения structure.py
Файл:
```text
src/trading/market_analysis/structure.py
```
переведён с:
```text
Sequence[Kline]
```
на:
```text
Sequence[Candle]
```
Адаптирована функция:
```text
market_structure()
```
Для построения последовательностей максимумов и минимумов используются значения:
```text
candle.high_price
candle.low_price
```
с безопасным преобразованием к вычислительному типу.
Существующая логика определения структуры рынка сохранена:
```text
HH_HL
LH_LL
MIXED
UNKNOWN
```
Build 048 не изменяет:
- правила определения swing high;
- правила определения swing low;
- правила сравнения последних swing-точек;
- adaptive structure parameters;
- существующие причины результата;
- существующую классификацию `MarketStructure`.
---
## 9. Защита от невалидных числовых значений
В ходе специализированного тестирования была выявлена необходимость явной проверки конечности числовых значений.
Для вычислительных функций используется:
```python
from math import isfinite
```
После:
```text
safe_float(...)
```
значения дополнительно проверяются на:
```text
NaN
Infinity
-Infinity
```
Это предотвращает распространение невалидных числовых значений внутри:
```text
ATR
ATR baseline
candle noise score
```
В частности, предотвращается ситуация:
```text
Decimal("NaN")
float("nan")
результат вычисления nan
```
Вместо этого невалидное значение исключается из вычисления согласно локальной логике соответствующей функции.
---
## 10. Специализированные unit-тесты
Добавлены три специализированных тестовых файла.
### 10.1. Volatility
Файл:
```text
tests/unit/trading/market_analysis/indicators/test_volatility_candle.py
```
Проверяет:
- работу `atr()` с каноническими `Candle`;
- поддержку `Decimal`;
- недостаточное количество свечей;
- невалидный период;
- обработку не конечных числовых значений;
- работу `atr_percent_baseline()`;
- невалидную цену закрытия.
### 10.2. Quality
Файл:
```text
tests/unit/trading/market_analysis/test_quality_candle.py
```
Проверяет:
- работу `candle_noise_score()` с `Candle`;
- поддержку `Decimal`;
- пустую последовательность;
- свечу с нулевым диапазоном;
- не конечные числовые значения;
- применение указанного tail window.
### 10.3. Structure
Файл:
```text
tests/unit/trading/market_analysis/test_structure_candle.py
```
Проверяет:
- структуру `HH_HL`;
- структуру `LH_LL`;
- структуру `MIXED`;
- недостаточное количество свечей;
- непосредственную работу с `Decimal`-значениями `Candle`.
---
## 11. Результаты специализированных тестов
Команда:
```bash
python -m pytest -q \
tests/unit/trading/market_analysis/indicators/test_volatility_candle.py \
tests/unit/trading/market_analysis/test_quality_candle.py \
tests/unit/trading/market_analysis/test_structure_candle.py
```
Результат:
```text
16 passed in 0.02s
```
---
## 12. Regression-проверка стратегий
Дополнительно выполнена проверка стратегий:
```bash
python -m pytest -q \
tests/unit/trading/strategies/test_scalp_quote.py \
tests/unit/trading/strategies/test_trend_quote.py
```
Результат:
```text
6 passed in 0.14s
```
Эта проверка подтверждает сохранение импортов и существующей интеграции `Market Analysis` с торговыми стратегиями.
---
## 13. Полный regression suite
Выполнена команда:
```bash
python -m pytest -q
```
Результат:
```text
766 passed in 2.53s
```
Полный unit test suite проекта проходит успешно.
---
## 14. Контроль legacy-зависимости Kline
Выполнена команда:
```bash
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"integrations.exchange.models import Kline" \
src/trading/market_analysis
```
Результат:
```text
src/trading/market_analysis/indicators_legacy.py:5:from src.integrations.exchange.models import Kline
```
Следовательно, после Build 048 активные вычислительные компоненты:
```text
volatility.py
quality.py
structure.py
```
больше не импортируют legacy-модель `Kline`.
Оставшийся импорт находится только в:
```text
indicators_legacy.py
```
который не изменяется в рамках Build 048.
---
## 15. Контроль использования канонической модели Candle
Выполнена команда:
```bash
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"models.candle import Candle" \
src/trading/market_analysis
```
Результат:
```text
src/trading/market_analysis/indicators/volatility.py:10:from src.market_data.acquisition.models.candle import Candle
src/trading/market_analysis/structure.py:9:from src.market_data.acquisition.models.candle import Candle
src/trading/market_analysis/quality.py:9:from src.market_data.acquisition.models.candle import Candle
```
Это подтверждает прямую зависимость трёх активных вычислительных потребителей от канонической модели `Candle`.
---
## 16. Контроль оставшихся вызовов ExchangeService.get_klines()
Выполнена команда:
```bash
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"\.get_klines(" \
src/trading/market_analysis
```
Результат:
```text
src/trading/market_analysis/service.py:243: batch = ExchangeService().get_klines(
src/trading/market_analysis/htf.py:55: batch = ExchangeService().get_klines(
src/trading/market_analysis/htf.py:153: batch = ExchangeService().get_klines(
```
Эти три вызова являются ожидаемыми и не удаляются в Build 048.
Они показывают следующую границу дальнейшей миграции:
```text
Market Analysis orchestration
прямое получение Candle
устранение зависимости от ExchangeService.get_klines()
```
Такое переключение должно выполняться отдельным Build после анализа контрактов:
```text
service.py
htf.py
```
---
## 17. Проверка форматирования diff
Выполнена команда:
```bash
git diff --check
```
Вывод отсутствует.
Следовательно:
```text
trailing whitespace отсутствует
ошибки whitespace отсутствуют
```
---
## 18. Архитектурный результат
После Build 048 активный вычислительный путь выглядит следующим образом:
```text
Dzengi REST API
DzengiCandlesDocumentSource
validate_candles_schema()
parse_candles()
validate_candles_values()
map_candles()
Candle
CandlesDocumentHandler
CandlesFeed
CandlesFeedRegistry
CandlesAcquisitionService
ExchangeService.get_klines()
legacy compatibility conversion
Market Analysis orchestration
active computational consumers typed for Candle
```
При этом три активных вычислительных компонента уже используют канонический контракт:
```text
volatility.py → Candle
quality.py → Candle
structure.py → Candle
```
Однако orchestration-слой `Market Analysis` пока продолжает получать данные через:
```text
ExchangeService.get_klines()
```
Поэтому полное устранение legacy-преобразования `Candle → Kline` ещё не завершено.
---
## 19. Что сознательно не сделано
В Build 048 сознательно не выполнялось:
- удаление `Kline`;
- удаление `KlineBatch`;
- удаление `ExchangeService.get_klines()`;
- изменение `MarketAnalysisService`;
- изменение HTF orchestration;
- изменение `indicators_legacy.py`;
- изменение торговых стратегий;
- изменение scoring;
- изменение signal logic;
- изменение торговых порогов;
- изменение определения market structure;
- изменение правил ATR;
- изменение существующей архитектуры каталогов;
- удаление рабочего legacy-кода.
Это соответствует принципу поэтапной миграции:
```text
сначала новый канонический путь
затем переключение потребителей
затем подтверждение отсутствия legacy-потребителей
только после этого отдельное удаление legacy-кода
```
---
## 20. Соблюдение правил миграции
Build 048 соответствует утверждённым правилам проекта Dzentra:
1. Рабочий код не удаляется без отдельного согласования.
2. Изменения ограничены согласованными границами Build.
3. Канонический слой Market Data не зависит от `src.trading`.
4. Миграция выполняется поэтапно.
5. Обратная совместимость сохраняется там, где она ещё необходима.
6. Legacy-код не удаляется до подтверждённого переключения всех его потребителей.
7. Существующая торговая семантика не изменяется в рамках инфраструктурной миграции.
8. Каждый Build подтверждается специализированными тестами, полным regression suite и контрольными grep.
---
## 21. Итог Build 048
Build 048 завершён успешно.
В результате:
```text
volatility.py
quality.py
structure.py
```
переведены с:
```text
Kline
```
на:
```text
Candle
```
Канонические `Decimal`-значения адаптированы к существующему вычислительному слою через:
```text
safe_float(...)
```
с дополнительной защитой от:
```text
NaN
Infinity
-Infinity
```
Подтверждено:
```text
16 специализированных тестов passed
6 regression-тестов стратегий passed
766 тестов полного suite passed
git diff --check — чисто
```
Build 048 завершает переключение выбранных активных вычислительных потребителей `Market Analysis` на каноническую модель `Candle`.
Следующая архитектурная граница миграции — прямое переключение orchestration-компонентов:
```text
src/trading/market_analysis/service.py
src/trading/market_analysis/htf.py
```
с:
```text
ExchangeService.get_klines()
```
на получение канонических:
```text
Candle
```
через слой:
```text
Market Data Acquisition
```
Такое переключение должно выполняться отдельным Build с сохранением существующего поведения системы.