26 KiB
Dzentra Target Architecture
Контроль документа
| Свойство | Значение |
|---|---|
| Тип | Target Architecture |
| Статус | Active Baseline |
| Версия | 1.1 |
| Дата | 2026-08-03 |
| Проект | Dzentra |
1. Назначение
Документ фиксирует целевую архитектурную карту Dzentra и связывает:
- фактическую структуру существующего проекта;
- выполняемую Build-by-Build миграцию;
- будущие подсистемы профессиональной автоматической торговой системы;
- обязательное направление зависимостей между доменами.
Документ не требует немедленного создания всех перечисленных каталогов и не заменяет архитектурные спецификации отдельных Build.
Целевая архитектура отвечает на вопрос:
Какие ответственности должны существовать в системе и как они могут взаимодействовать?
Последовательность реализации и текущий статус определяет
docs/roadmap/master-roadmap.md.
2. Текущий контекст
Dzentra является работающим modular monolith, который постепенно мигрирует из Telegram trading bot в модульную алгоритмическую торговую платформу.
Проект не является greenfield-системой. В нём одновременно существуют:
- принятые новые архитектурные слои;
- рабочие legacy-компоненты;
- временные compatibility boundaries;
- будущие целевые подсистемы.
Поэтому целевой каталог нельзя создавать механическим переносом файлов. Любое изменение ownership или направления зависимостей выполняется отдельным Build после анализа фактических consumers.
Вертикаль Trades Feed принята от Production Runtime до persistent Storage, Startup Recovery, Historical Access и deterministic Replay в Builds 060.25–060.29. Build 060.30 актуализировал документацию этого состояния. Завершение одной вертикали не означает готовность остальных Market Data feeds или всей торговой платформы.
3. Верхнеуровневая карта
External Exchanges and Data Sources
│
▼
┌───────────────────────────────────────────────┐
│ Market Data │
│ Acquisition → Canonicalization → Quality │
│ │ │
│ ├── Live / Operational │
│ └── Storage → Replay │
└───────────────────────────────────────────────┘
│ Canonical Live or Replay Data
▼
┌───────────────────────────────────────────────┐
│ Market Intelligence │
│ Processing → Features → Market State │
│ → Scenario Evaluation │
└───────────────────────────────────────────────┘
│ Analysis Results
▼
┌───────────────────────────────────────────────┐
│ Trading │
│ Strategy / Decision → Portfolio / Risk │
│ → Order Management → Execution │
│ → Position and Account Reconciliation │
└───────────────────────────────────────────────┘
│ Commands and Reports
▼
Exchange
Все уровни обслуживаются общей Platform-плоскостью:
Runtime and Scheduling
Event Contracts
Configuration and Secrets
Logging, Audit and Observability
Resilience and Recovery
Security
Deployment and Operations
Logging, Audit, Monitoring и Runtime не являются последними этапами торгового конвейера. Они действуют на всех уровнях системы.
4. Market Data
4.1. Market Data Acquisition
Назначение: получение внешних рыночных и справочных данных.
Целевые семейства Feed:
- Instrument Reference Data;
- Quotes;
- OHLCV / Candles;
- Trades / Time & Sales;
- Order Book;
- Derivatives Market Data;
- Market Index;
- Exchange Time;
- Exchange and Instrument Status.
Каждый Feed развивается как самостоятельный vertical slice:
external document
↓
schema validation
↓
parser / transport model
↓
value validation
↓
mapper
↓
canonical model
↓
handler / feed / service
REST и WebSocket могут иметь независимые transport pipelines, но до передачи downstream обязаны сходиться в одну source-independent Canonical Model.
Текущее размещение:
app/src/market_data/acquisition/
Текущий активный результат: Production Runtime для Trades Feed завершён в Build 060.25, а network/fault/stress/soak/live verification — в Build 060.26.
4.2. Validation, Canonicalization and Data Quality
Назначение:
- проверять структуру внешних документов;
- проверять допустимость значений;
- нормализовать время, числовые значения и идентификаторы;
- преобразовывать transport data в Canonical Models;
- контролировать дубликаты, порядок и пропуски;
- формировать явные признаки качества и freshness.
Эта ответственность сейчас распределена между:
adapters/
validation/
models/
consistency/
recovery/
Build 061.00 должен сначала проверить фактические границы, а уже затем
решить, требуется ли отдельный каталог normalization.
Schema Validation, Value Validation, Mapping, Stream Consistency и Missing Data Recovery не должны смешиваться в один универсальный компонент.
4.3. Operational Market State
Оперативное состояние необходимо для работы активного потока:
- последний принятый Trade;
- deduplication window;
- состояние подписок;
- connection generation;
- liveness и reconnect state.
Оно не является долговременной историей рынка.
TradeStreamState принадлежит Consistency Layer, а не общему Market
Data Storage и не WebSocket Transport.
Подтверждённая durable точка восстановления хранится отдельно как Persistent Checkpoint. Она восстанавливает operational state после перезапуска, но не заменяет долговременную историю рынка.
4.4. Persistent Market Data Storage
Назначение: долговременно хранить Canonical Market Data для:
- восстановления после перезапуска;
- исторических запросов;
- Replay;
- разработки и проверки аналитики;
- backtesting;
- аудита качества данных.
Build 060.27 реализовал два явно разных слоя:
app/src/storage/
общий/исторический PostgreSQL foundation, pool и migrations
app/src/market_data/storage/
канонические contracts и repositories Market Data
Канонический слой содержит idempotent PostgreSQL repositories для
Trades, Quotes и Candle revisions, provenance, schema versions,
write-only MarketDataStorage, Partition Manager и Retention Service.
Production writer wiring подключён только для Trades. Существующие REST
Quotes/Candles обслуживают Trading/UI, но не записываются этими
persistent repositories автоматически.
Физическое partitioning реализовано отдельным parent/default family для каждого типа данных:
market_data.trades
RANGE (executed_at)
├── trades_default
└── trades_YYYY_MM
market_data.quotes
RANGE (received_at)
├── quotes_default
└── quotes_YYYY_MM
market_data.candle_revisions
RANGE (open_time)
├── candle_revisions_default
└── candle_revisions_YYYY_MM
venue и symbol участвуют в identity и queries, но не являются
уровнями физического partitioning. Месячный child имеет UTC-границы для
всех venue/symbol соответствующего parent. Partition Manager вызывается
явно, сериализует создание advisory lock, переносит подходящие строки из
default partition и регистрирует управляемый child в
market_data.partition_registry в одной транзакции.
Retention также запускается только явно. Он не является Scheduler-задачей Production Runtime. Raw storage, automatic partition creation, historical backfill и гарантия полноты истории пока не реализованы.
4.5. Persistent Checkpoint and Startup Recovery
Build 060.28 реализовал постоянный operational checkpoint Trades:
- identity checkpoint —
(venue, symbol); - checkpoint ссылается на точную durable Trade;
- Trade и checkpoint продвигаются в одной PostgreSQL-транзакции;
- optimistic CAS revision защищает конкурентное продвижение;
- in-memory state изменяется только после durable commit;
- Hydration восстанавливает checkpoint и bounded deduplication tail;
- Startup Recovery заполняет разрыв при закрытом Live gate;
- buffered live data выпускаются только после успешного Recovery.
Checkpoint существует только для Trades. Он не является второй копией истории, не доказывает полноту Storage и не имеет отдельного feature flag: persistent checkpoint включается вместе с Market Data Storage.
4.6. Historical Access
Build 060.29 создал отдельный synchronous read-side:
app/src/market_data/access/
Trade, Quote и Candle revision history читаются forward keyset pages. Каждый вызов Historical query читает одну текущую committed page; единый snapshot между последовательными страницами не гарантируется. Access не изменяет durable data или operational checkpoint, вызывается явным consumer и не запускается из Bootstrap автоматически.
4.7. Deterministic Replay
Replay использует те же Canonical Models, что live processing, и не
обходит validation guarantees. Migration 9 добавила общий immutable
replay_sequence для Trades, Quotes и Candle revisions. Миграция
блокирующая и перед большой production-базой требует maintenance window,
backup и предварительного замера длительности.
Replay Plan Builder материализует bounded snapshot в транзакции
READ ONLY REPEATABLE READ. Превышение max_records завершается явной
ошибкой. Смешанный порядок событий равен
(replay_at, replay_sequence).
DeterministicReplayClock принимает timezone-aware datetime,
канонизирует его в UTC, допускает равное время и запрещает движение
назад; naive datetime запрещён. ReplaySession — caller-owned one-shot
lifecycle с новым графом зависимостей для каждого запуска.
Автоматический Replay startup, default consumer, отдельный Replay endpoint, hidden task и historical backfill не реализованы. Backtesting может использовать этот фундамент, но сам не входит в Build 060.29.
5. Market Intelligence
5.1. Market Data Processing
Формирует устойчивое состояние и базовые рыночные представления:
- Candle aggregation;
- Order Book reconstruction;
- best bid / ask / mid / spread;
- trade-flow aggregation;
- временные окна;
- подтверждённые market events.
Processing не принимает торговых решений.
5.2. Feature Engineering
Формирует производные признаки:
- returns и momentum;
- volatility;
- relative и abnormal volume;
- trade-flow intensity и delta;
- Order Book imbalance и microprice;
- liquidity;
- time/session features;
- statistical и cross-market features;
- derivatives features.
Canonical Trade price, quantity и timestamp уже являются исходными данными и не требуют отдельного дублирующего Trade Facts model без подтверждённого consumer.
5.3. Market State Estimation
Интерпретирует признаки и определяет:
- market structure;
- trend и range;
- momentum и correction;
- volatility regime;
- liquidity regime;
- order-flow state;
- market phase;
- microstructure context.
Текущее основное размещение:
app/src/trading/market_intelligence/
Изменение этого ownership требует отдельного архитектурного Build.
5.4. Scenario Evaluation
Dzentra рассматривает прогнозирование как оценку нескольких возможных сценариев:
- scenario generation;
- probability estimation;
- ranking;
- confidence and uncertainty.
Scenario Evaluation является опциональной аналитической возможностью. Strategy, которой отдельный прогноз не требуется, не должна создавать фиктивную зависимость от Forecasting.
6. Trading
6.1. Strategy and Trading Decision
Преобразует рыночный анализ в торговое намерение:
- enter;
- hold;
- reduce;
- exit;
- do nothing.
Результат Decision не является биржевым ордером и не должен напрямую вызывать Transport.
6.2. Portfolio and Risk
Проверяет и ограничивает торговое намерение:
- допустимый размер позиции;
- leverage и margin;
- общий капитал под риском;
- концентрацию по символам;
- drawdown и loss limits;
- pre-trade, continuous и emergency risk controls.
Risk не является только одним последовательным шагом после Strategy. Он может запрещать вход, изменять размер позиции и останавливать уже активное исполнение.
6.3. Order Management System
Отвечает за внутренний жизненный цикл собственных заявок:
- создание client order identity;
- переходы состояния заявки;
- amend / cancel;
- partial fills;
- deduplication;
- reconciliation с биржей;
- восстановление после reconnect и restart.
OMS не следует смешивать с Market Trades Feed: рыночная сделка и исполнение собственной заявки являются разными предметными сущностями.
6.4. Execution Management
Отвечает за:
- преобразование одобренного намерения в execution command;
- выбор цены и способа исполнения;
- маршрутизацию на биржу;
- контроль slippage, liquidity и freshness;
- обработку transport и exchange errors.
Текущее основное размещение:
app/src/trading/execution/
6.5. Position and Account Reconciliation
Сопоставляет локальное состояние с биржей:
- позиции;
- balances;
- fills;
- open orders;
- fees;
- realized и unrealized PnL.
Биржевое состояние является внешним фактом и должно периодически сверяться, а не только вычисляться из локальных событий.
7. Platform and Governance
Runtime and Scheduling
- явные владельцы задач и ресурсов;
- конечные timeouts;
- детерминированные startup и shutdown;
- controlled retry/reconnect;
- отсутствие скрытого fire-and-forget.
Event Contracts
- типизированные и версионируемые события;
- явная граница между market, runtime, execution и audit events;
- контролируемое ordering;
- отсутствие чувствительных transport payload в логах.
Configuration and Secrets
- feature flags безопасны по умолчанию;
- URL, symbols и credentials задаются явно;
- production secrets не попадают в код, документацию и события.
Logging, Audit and Observability
- технические логи;
- domain audit trail;
- Trade Journal;
- metrics, latency и data freshness;
- health и liveness;
- alerting;
- объяснение причин торгового решения.
Resilience
- idempotency;
- reconnect;
- Recovery;
- persistent checkpoint;
- startup reconciliation;
- controlled degradation;
- failure isolation.
Backtesting and Simulation
Backtesting является отдельной capability, но переиспользует:
- Canonical Market Data;
- Replay;
- deterministic clock;
- production Feature, Decision и Risk contracts;
- exchange/OMS simulator.
Отдельная копия торговой логики только для backtest не допускается.
Persistent Storage, Historical Access, Replay Plan, deterministic clock и Replay Session уже создают необходимые data/time prerequisites. Backtesting engine, exchange/OMS simulator и автоматическая composition этой capability пока не реализованы.
8. Правила зависимостей
Разрешённое основное направление:
Market Data
↓
Market Intelligence
↓
Trading Decision
↓
Portfolio / Risk
↓
OMS / Execution
↓
Exchange Integration
Обязательные ограничения:
- Market Data не импортирует Trading;
- Canonical Models не зависят от Dzengi transport schema;
- Market Intelligence не управляет WebSocket lifecycle;
- Strategy не отправляет биржевую заявку напрямую;
- Execution не изменяет правила Market Data Consistency;
- Telegram UI не является владельцем domain state;
- Storage не вызывает торговые решения;
- Backtesting использует те же domain contracts, что production;
- Platform-компоненты не получают лишнюю предметную ответственность.
Обратная информация от Exchange возвращается через явные execution, order, account и runtime events, а не через обратные импорты между слоями.
9. Политика каталогов
Логический домен и физический каталог не обязаны иметь одинаковое имя.
Текущее соответствие:
| Ответственность | Фактическое размещение |
|---|---|
| Market Data Acquisition | app/src/market_data/acquisition/ |
| Application Runtime Composition | app/src/bootstrap/ |
| Runtime Events | app/src/runtime_events/ и локальные runtime events |
| Общий/исторический Storage foundation | app/src/storage/ |
| Canonical Market Data Storage | app/src/market_data/storage/ |
| Historical Market Data Access | app/src/market_data/access/ |
| Deterministic Replay | app/src/market_data/replay/ |
| Market Intelligence | app/src/trading/market_intelligence/ |
| Trading Decision | app/src/trading/decision/ |
| Execution | app/src/trading/execution/ |
| Position | app/src/trading/position/ |
| Trade Journal | app/src/trading/journal/ |
| Exchange Integration | app/src/integrations/exchange/ |
Новый каталог создаётся только когда:
- ответственность подтверждена фактическими consumers;
- определён публичный контракт;
- существующее ownership признано неверным;
- подготовлен отдельный migration plan;
- проверено направление импортов.
Предложенные имена вроде analytics/features или
market_data/normalization являются логическими ориентирами, а не
заранее утверждённой файловой структурой. Каталоги
market_data/storage, market_data/access и market_data/replay уже
являются принятыми фактическими boundaries.
10. Current-to-target status
| Область | Состояние |
|---|---|
| Market Data Acquisition foundation | Trades vertical slice завершён; остальные feeds развиваются Build-by-Build |
| Trades Feed production runtime | Completed — Build 060.25 |
| Runtime integration/stress/live verification | Completed — Build 060.26 |
| Persistent Market Data Storage | Completed — Build 060.27 |
| Persistent Checkpoint / Startup Recovery | Completed — Build 060.28 |
| Historical Access / Replay | Completed — Build 060.29 |
| Market Data Acquisition Final Documentation | Completed — Build 060.30 |
| Validation ownership audit/refactoring | Planned — Build 061.00 |
| Market Intelligence | Существующая активная подсистема |
| Decision / Execution / Position | Существующие подсистемы, требуют будущих boundary audits |
| OMS / Reconciliation | Целевая ответственность, отдельный план не утверждён |
| Backtesting | Storage/Replay prerequisites готовы; capability не реализована |
| Operations / Deployment | Docker hardening принят; deployment остаётся отдельной cross-cutting программой |
Completed означает завершение утверждённого Build, а не окончательную
сертификацию всей подсистемы для любой production-нагрузки.
11. Управление изменениями
Этот документ изменяется только когда меняется:
- ownership домена;
- публичная архитектурная граница;
- разрешённое направление зависимостей;
- целевая карта подсистем.
Статус конкретного Build изменяется в master-roadmap.md и его
migration report.
Детали реализации, тестовые evidence и локальные решения фиксируются в:
docs/migrations/build_<number>_architecture.md
docs/migrations/build_<number>.md
docs/decisions/
При конфликте:
- фактический код и тесты определяют текущее поведение;
- принятый Build architecture document определяет локальное решение;
- настоящий документ определяет целевую границу;
- roadmap определяет порядок дальнейшей миграции.