21 KiB
Build 048 — Переключение вычислительных потребителей Market Analysis на каноническую модель Candle
Статус: Completed
Дата: 2026-07-15
Подсистема: Market Data Acquisition / OHLCV Feed / Market Analysis
1. Назначение Build
Build 048 переводит активные вычислительные компоненты подсистемы Market Analysis, непосредственно работающие с последовательностями рыночных свечей, с legacy-модели:
src.integrations.exchange.models.Kline
на каноническую модель рыночной свечи:
src.market_data.acquisition.models.candle.Candle
Build является очередным этапом поэтапной миграции получения и использования OHLCV-данных в канонический слой:
Market Data Acquisition
Основная цель Build — устранить прямую зависимость активных вычислительных функций анализа рынка от legacy-модели Kline, сохранив существующую торговую семантику и поведение системы.
2. Контекст миграции
До Build 048 канонический OHLCV pipeline уже был создан и интегрирован поэтапно.
Build 044
Создан фундамент канонического Candles Feed:
REST transport
↓
schema validation
↓
parser
↓
value validation
↓
mapper
↓
Candle
↓
handler
↓
CandlesFeed
Каноническая модель:
src/market_data/acquisition/models/candle.py
Build 045
Создан и протестирован:
CandlesFeedRegistry
Build 046
Создан и интегрирован:
CandlesAcquisitionService
Build 047
Legacy-метод:
ExchangeService.get_klines()
переключён на канонический Candles Feed.
После Build 047 транспортный запрос:
/api/v1/klines
выполняется только внутри:
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.
Изменены:
src/trading/market_analysis/indicators/volatility.py
src/trading/market_analysis/quality.py
src/trading/market_analysis/structure.py
Добавлены специализированные unit-тесты:
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 не изменяет:
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 также не удаляет:
Kline
KlineBatch
ExchangeService.get_klines()
Их дальнейшая судьба определяется отдельными последующими этапами миграции.
4. Основное архитектурное изменение
До Build 048 активные вычислительные функции использовали legacy-модель:
from src.integrations.exchange.models import Kline
После Build 048 они используют каноническую модель:
from src.market_data.acquisition.models.candle import Candle
Изменение выполнено в:
src/trading/market_analysis/indicators/volatility.py
src/trading/market_analysis/quality.py
src/trading/market_analysis/structure.py
Таким образом, активные вычислительные функции:
atr()
atr_percent_baseline()
candle_noise_score()
market_structure()
больше не зависят от:
src.integrations.exchange.models.Kline
и работают непосредственно с:
src.market_data.acquisition.models.candle.Candle
5. Адаптация к канонической модели Candle
Каноническая модель Candle использует точные числовые значения:
Decimal
для полей:
open_price
high_price
low_price
close_price
volume
Legacy-модель Kline использовала:
float
Поэтому Build 048 выполняет явную адаптацию вычислительного слоя к Decimal.
Для безопасного преобразования используется существующий helper:
src.core.numbers.safe_float
Числовые значения преобразуются непосредственно на границе вычислений.
Принцип:
Candle
↓
Decimal OHLCV
↓
safe_float(...)
↓
float
↓
существующая вычислительная логика Market Analysis
Это позволяет:
- сохранить точность канонической модели данных;
- не переносить
floatв слой Market Data Acquisition; - сохранить существующие вычислительные алгоритмы;
- минимизировать область изменений;
- не изменять торговую семантику в рамках миграционного Build.
6. Изменения volatility.py
Файл:
src/trading/market_analysis/indicators/volatility.py
переведён с:
Sequence[Kline]
на:
Sequence[Candle]
Адаптированы функции:
atr()
atr_percent_baseline()
Поля канонической модели:
previous.close_price
current.high_price
current.low_price
преобразуются через:
safe_float(...)
Дополнительно выполняется проверка:
math.isfinite(...)
для исключения нечисловых конечных значений:
NaN
Infinity
-Infinity
Это необходимо, поскольку преобразование:
Decimal("NaN")
в float само по себе не возвращает None, а создаёт:
float("nan")
Без проверки isfinite() такое значение могло проникнуть в вычисление ATR.
7. Изменения quality.py
Файл:
src/trading/market_analysis/quality.py
переведён с:
Sequence[Kline]
на:
Sequence[Candle]
Адаптирована функция:
candle_noise_score()
Поля:
high_price
low_price
open_price
close_price
преобразуются через:
safe_float(...)
и проверяются через:
isfinite(...)
Невалидные свечи не участвуют в расчёте.
Если после фильтрации отсутствуют допустимые свечи, функция возвращает:
None
Существующая функция:
price_position_score()
сохранена.
Build 048 не изменяет её назначение и вычислительную семантику.
8. Изменения structure.py
Файл:
src/trading/market_analysis/structure.py
переведён с:
Sequence[Kline]
на:
Sequence[Candle]
Адаптирована функция:
market_structure()
Для построения последовательностей максимумов и минимумов используются значения:
candle.high_price
candle.low_price
с безопасным преобразованием к вычислительному типу.
Существующая логика определения структуры рынка сохранена:
HH_HL
LH_LL
MIXED
UNKNOWN
Build 048 не изменяет:
- правила определения swing high;
- правила определения swing low;
- правила сравнения последних swing-точек;
- adaptive structure parameters;
- существующие причины результата;
- существующую классификацию
MarketStructure.
9. Защита от невалидных числовых значений
В ходе специализированного тестирования была выявлена необходимость явной проверки конечности числовых значений.
Для вычислительных функций используется:
from math import isfinite
После:
safe_float(...)
значения дополнительно проверяются на:
NaN
Infinity
-Infinity
Это предотвращает распространение невалидных числовых значений внутри:
ATR
ATR baseline
candle noise score
В частности, предотвращается ситуация:
Decimal("NaN")
↓
float("nan")
↓
результат вычисления nan
Вместо этого невалидное значение исключается из вычисления согласно локальной логике соответствующей функции.
10. Специализированные unit-тесты
Добавлены три специализированных тестовых файла.
10.1. Volatility
Файл:
tests/unit/trading/market_analysis/indicators/test_volatility_candle.py
Проверяет:
- работу
atr()с каноническимиCandle; - поддержку
Decimal; - недостаточное количество свечей;
- невалидный период;
- обработку не конечных числовых значений;
- работу
atr_percent_baseline(); - невалидную цену закрытия.
10.2. Quality
Файл:
tests/unit/trading/market_analysis/test_quality_candle.py
Проверяет:
- работу
candle_noise_score()сCandle; - поддержку
Decimal; - пустую последовательность;
- свечу с нулевым диапазоном;
- не конечные числовые значения;
- применение указанного tail window.
10.3. Structure
Файл:
tests/unit/trading/market_analysis/test_structure_candle.py
Проверяет:
- структуру
HH_HL; - структуру
LH_LL; - структуру
MIXED; - недостаточное количество свечей;
- непосредственную работу с
Decimal-значениямиCandle.
11. Результаты специализированных тестов
Команда:
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
Результат:
16 passed in 0.02s
12. Regression-проверка стратегий
Дополнительно выполнена проверка стратегий:
python -m pytest -q \
tests/unit/trading/strategies/test_scalp_quote.py \
tests/unit/trading/strategies/test_trend_quote.py
Результат:
6 passed in 0.14s
Эта проверка подтверждает сохранение импортов и существующей интеграции Market Analysis с торговыми стратегиями.
13. Полный regression suite
Выполнена команда:
python -m pytest -q
Результат:
766 passed in 2.53s
Полный unit test suite проекта проходит успешно.
14. Контроль legacy-зависимости Kline
Выполнена команда:
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"integrations.exchange.models import Kline" \
src/trading/market_analysis
Результат:
src/trading/market_analysis/indicators_legacy.py:5:from src.integrations.exchange.models import Kline
Следовательно, после Build 048 активные вычислительные компоненты:
volatility.py
quality.py
structure.py
больше не импортируют legacy-модель Kline.
Оставшийся импорт находится только в:
indicators_legacy.py
который не изменяется в рамках Build 048.
15. Контроль использования канонической модели Candle
Выполнена команда:
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"models.candle import Candle" \
src/trading/market_analysis
Результат:
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()
Выполнена команда:
grep -RIn \
--exclude-dir="__pycache__" \
--exclude="*.pyc" \
"\.get_klines(" \
src/trading/market_analysis
Результат:
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.
Они показывают следующую границу дальнейшей миграции:
Market Analysis orchestration
↓
прямое получение Candle
↓
устранение зависимости от ExchangeService.get_klines()
Такое переключение должно выполняться отдельным Build после анализа контрактов:
service.py
htf.py
17. Проверка форматирования diff
Выполнена команда:
git diff --check
Вывод отсутствует.
Следовательно:
trailing whitespace отсутствует
ошибки whitespace отсутствуют
18. Архитектурный результат
После Build 048 активный вычислительный путь выглядит следующим образом:
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
При этом три активных вычислительных компонента уже используют канонический контракт:
volatility.py → Candle
quality.py → Candle
structure.py → Candle
Однако orchestration-слой Market Analysis пока продолжает получать данные через:
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-кода.
Это соответствует принципу поэтапной миграции:
сначала новый канонический путь
↓
затем переключение потребителей
↓
затем подтверждение отсутствия legacy-потребителей
↓
только после этого отдельное удаление legacy-кода
20. Соблюдение правил миграции
Build 048 соответствует утверждённым правилам проекта Dzentra:
- Рабочий код не удаляется без отдельного согласования.
- Изменения ограничены согласованными границами Build.
- Канонический слой Market Data не зависит от
src.trading. - Миграция выполняется поэтапно.
- Обратная совместимость сохраняется там, где она ещё необходима.
- Legacy-код не удаляется до подтверждённого переключения всех его потребителей.
- Существующая торговая семантика не изменяется в рамках инфраструктурной миграции.
- Каждый Build подтверждается специализированными тестами, полным regression suite и контрольными grep.
21. Итог Build 048
Build 048 завершён успешно.
В результате:
volatility.py
quality.py
structure.py
переведены с:
Kline
на:
Candle
Канонические Decimal-значения адаптированы к существующему вычислительному слою через:
safe_float(...)
с дополнительной защитой от:
NaN
Infinity
-Infinity
Подтверждено:
16 специализированных тестов passed
6 regression-тестов стратегий passed
766 тестов полного suite passed
git diff --check — чисто
Build 048 завершает переключение выбранных активных вычислительных потребителей Market Analysis на каноническую модель Candle.
Следующая архитектурная граница миграции — прямое переключение orchestration-компонентов:
src/trading/market_analysis/service.py
src/trading/market_analysis/htf.py
с:
ExchangeService.get_klines()
на получение канонических:
Candle
через слой:
Market Data Acquisition
Такое переключение должно выполняться отдельным Build с сохранением существующего поведения системы.