31 KiB
Execution Architecture Overview
Архитектурные уровни
Foundation
- constants.py
- models.py
- pricing.py
- calculations.py
- position_metrics.py
- resets.py
Business Operations
- position_actions.py
- flip.py
- risk_close.py
Runtime
- position_runtime.py
- position_protection.py
- runtime_actions.py
- position_exit_decision.py
Orchestration
- supervisor.py
- engine.py
Sizing
- sizing.py
Execution refactoring roadmap
Цель: безопасный поэтапный рефакторинг app/src/trading/execution.
Принципы:
- сначала аудит;
- без изменения бизнес-логики;
- без изменения payload;
- без изменения EventBus;
- без изменения JournalService;
- без изменения ExecutionDecision;
- каждый шаг проверяется перезапуском бота.
Статус файлов
| Файл | Статус | Комментарий |
|---|---|---|
| constants.py | Done | Этап 1 завершён |
| flip.py | Done stage 1 | Reject helper, payload builders, grouping |
| position_actions.py | Done stage 1 | Reject helper, payload builders, grouping |
| risk_close.py | Done | Risk close helper |
| calculations.py | Not audited | |
| engine.py | Not audited | |
| models.py | Not audited | |
| position_exit_decision.py | Not audited | |
| position_metrics.py | Not audited | |
| position_protection.py | Not audited | |
| position_runtime.py | Not audited | |
| pricing.py | Done | Добавлен _build_execution_price(), убраны дубли сборки ExecutionPrice |
| quality.py | Not audited | |
| resets.py | Not audited | |
| runtime_actions.py | Not audited | |
| sizing.py | Not audited | |
| supervisor.py | Not audited |
Completed:
- constants.py
- models.py
- calculations.py
- pricing.py
- resets.py
- risk_close.py
- position_metrics.py
- position_runtime.py
- position_protection.py (safe refactoring)
- flip.py (safe refactoring)
- position_actions.py (safe refactoring)
- runtime_actions.py (safe refactoring)
- supervisor.py (safe refactoring)
- constants.py (completed)
Правила аудита
Для каждого файла фиксируем:
- назначение;
- размер и сложность;
- зависимости;
- безопасные улучшения;
- что нельзя трогать;
- рекомендуемый следующий шаг.
Порядок аудита
Стандарт структуры ExecutionMixin
Порядок методов:
- Payload builders
- Journal helpers
- Decision helpers
- Validation / Checks
- Execution methods
- Utility methods
Уже обработаны
- constants.py
- flip.py
- position_actions.py
- risk_close.py
Этап A — маленькие и базовые файлы
- quality.py
- models.py
- calculations.py
- resets.py
- pricing.py
- engine.py
Этап B — средние файлы
- position_runtime.py
- sizing.py
- runtime_actions.py
- position_exit_decision.py
Этап C — крупные и рискованные файлы
- position_metrics.py
- supervisor.py
- position_protection.py
quality.py
Статус: Empty / candidate for removal later
Назначение:
- Файл существует, но сейчас не содержит логики.
Размер и сложность:
- 2 строки.
- Сложность отсутствует.
Зависимости:
- Нужно отдельно проверить, импортируется ли где-то
src.trading.execution.quality.
Безопасные улучшения:
- Сейчас ничего не менять.
Что нельзя трогать:
- Не удалять файл до проверки импортов.
Рекомендуемый следующий шаг:
- Позже выполнить grep по проекту:
grep -R "execution.quality\|from src.trading.execution import quality" app/src
models.py
Статус: Completed (без изменений)
Назначение:
- DTO результата выполнения торгового действия.
Размер:
- Отличный.
Связность:
- Минимальная.
Безопасные улучшения:
- Не требуются.
Что нельзя менять:
- Структуру ExecutionDecision.
- Имена полей.
- Поведение.
Итог: Файл соответствует целевой архитектуре и рефакторинга не требует.
calculations.py
Статус: Completed after minor cleanup
Назначение:
- Compatibility-wrapper для старых методов расчёта.
- Реальные расчёты централизованы в position_metrics.py.
Размер:
- Небольшой.
Связность:
- Зависит от PositionState и build_position_metrics().
- Связность нормальная.
Безопасные улучшения:
- Только косметика форматирования.
Что нельзя менять:
- Не удалять wrapper-методы.
- Не менять возвращаемые значения.
- Не переносить расчёты обратно в этот файл.
Итог: Файл архитектурно нормальный. Основная логика уже вынесена в position_metrics.py.
resets.py
Статус: Completed (без изменений)
Назначение:
- Централизованный reset состояния AutoTradeState.
Размер:
- Хороший.
Связность:
- Минимальная.
Безопасные улучшения:
- Пока не требуются.
Возможные будущие улучшения:
- Только группировка полей по смысловым секциям без изменения поведения.
Что нельзя менять:
- Состав очищаемых полей.
- Порядок вызова методов reset.
Итог: Файл соответствует целевой архитектуре и рефакторинга не требует.
pricing.py
Статус: Completed after minor cleanup
Назначение:
- Получение execution-цены для входа, выхода и market last.
- Проверка свежести execution snapshot.
- Нормализация bid/ask/last цены.
Размер:
- Нормальный.
Связность:
- Зависит от ExchangeService, AutoTradeState и ExecutionPrice.
- Связность ожидаемая для pricing-слоя.
Что сделано:
- Добавлен helper
_build_execution_price(). - Убраны повторяющиеся сборки
ExecutionPrice. - Логика выбора bid/ask/last не менялась.
- Проверка свежести snapshot не менялась.
Безопасные улучшения:
- Завершены.
Что нельзя менять:
- Роли pricing:
LONG_ENTRY_ASKSHORT_ENTRY_BIDENTRY_LASTLONG_EXIT_BIDSHORT_EXIT_ASKEXIT_LASTMARKET_LAST
- Логику выбора ask/bid для LONG/SHORT.
- Поведение
_ensure_fresh_snapshot().
Итог: Файл соответствует целевой архитектуре. Рефакторинг на текущем этапе завершён.
position_metrics.py
Статус: Audited / no changes now
Назначение:
- Центральная точка расчёта метрик открытой и планируемой позиции.
- Формирует PositionMetrics и PlannedPositionMetrics.
Размер:
- Большой, но оправданный.
- В файле много вычислений, но они хорошо разделены на helpers.
Связность:
- Основная связность нормальная: PositionState, NumericLike, safe_float.
- Потенциально спорная связность:
_trading_fee()обращается к ExchangeService.
Что хорошо:
- Есть единая функция
build_position_metrics(). - Есть отдельная функция
build_planned_position_metrics(). - Расчёты вынесены в маленькие private helpers.
- Формулы читаемые.
Безопасные улучшения:
- Сейчас не требуются.
Что нельзя менять:
- Формулы PnL.
- Округления.
- Поведение при None/invalid values.
- Расчёт commission.
- Расчёт overnight cashflow.
- Поведение
_trading_fee().
Будущий возможный этап:
- Отдельно обсудить, нужно ли выносить получение trading fee из position_metrics.py.
- Но только после тестов и сверки PnL.
Итог: Файл архитектурно важный и в целом хорошо организован. На текущем безопасном этапе правки не нужны.
position_runtime.py
Статус: Audited / minor cleanup only
Назначение:
- Обновление runtime PnL открытой позиции.
- Синхронизация PositionState с AutoTradeState.
- Обновление runtime-памяти позиции: peak PnL, MFE/MAE, best/worst price, fatigue.
Размер:
- Средний.
Связность:
- Зависит от PositionState, AutoTradeState, ExecutionPrice и build_position_metrics().
- Связность ожидаемая.
Что хорошо:
- PnL и price move считаются через position_metrics.py.
- Runtime-память позиции вынесена в отдельный helper.
- Fatigue score/state вынесены отдельно.
Что настораживает:
_sync_state_from_position()частично дублирует reset-логику из resets.py.- Пока это не трогаем, чтобы не изменить поведение.
Безопасные улучшения:
- Только косметика форматирования.
Что нельзя менять:
- Поведение
_sync_state_from_position(). - Состав полей, которые сбрасываются при
position.side == "NONE". - Логику peak PnL, MFE/MAE, best/worst price.
- Логику fatigue score.
Итог: Файл можно оставить как есть. Возможный будущий этап — аккуратно сравнить reset-поля с resets.py, но без автоматического объединения.
Progress
Completed:
- constants.py
- models.py
- calculations.py
- pricing.py
- resets.py
- risk_close.py
- position_metrics.py
- position_runtime.py
- flip.py (safe refactoring)
- position_actions.py (safe refactoring)
Current status:
- Центральные расчёты execution уже унифицированы.
- PnL рассчитывается только через position_metrics.py.
- Pricing унифицирован.
- Runtime обновляется через единый pipeline.
- Все изменения выполнены без изменения бизнес-логики.
Architecture decisions
Принятые правила:
-
Любые вычисления позиции должны происходить только через position_metrics.py.
-
Pricing не должен содержать бизнес-логику.
-
Mixins должны иметь следующую структуру:
- helpers
- journal helpers
- validation
- execution
- utility
- Все безопасные рефакторинги выполняются без изменения поведения execution.
position_protection.py
Статус: Audited / candidate for safe payload extraction
Назначение:
- Runtime protection открытой позиции.
- Управляет break-even, profit lock и trailing stop.
- Проверяет причины закрытия позиции по protection-логике.
- Логирует события runtime protection.
Размер:
- Большой.
Связность:
- Зависит от PositionState, AutoTradeState, PositionMetrics, ExecutionPrice.
- Использует JournalService и EventBus для runtime protection событий.
- Использует build_position_metrics() для расчётов позиции.
Что хорошо:
- Цена выхода получается один раз в
_process_runtime_protection(). - PositionMetrics считается один раз.
- Break-even, profit lock и trailing stop разделены по отдельным методам.
- Закрытие позиции выполняется через общий
_close_position().
Что настораживает:
- Большой payload внутри
_log_runtime_protection_event(). - Константы thresholds пока находятся прямо в файле.
- Файл совмещает protection-логику и logging payload.
Безопасные улучшения:
- Вынести payload из
_log_runtime_protection_event()в_build_runtime_protection_payload().
Что нельзя менять:
- Protection thresholds.
- Логику активации break-even.
- Логику profit lock.
- Логику trailing stop.
- Порядок проверки close reason.
- forced_reason при закрытии.
- JournalService/EventBus события.
Итог: Файл рабочий, но требует безопасного структурного улучшения: сначала вынести payload builder без изменения поведения.
position_protection.py
Статус: Completed (safe refactoring stage 1)
Назначение:
- Runtime-защита открытой позиции.
- Управляет break-even, profit lock и trailing stop.
- Проверяет условия принудительного закрытия позиции.
- Формирует runtime protection события.
Размер:
- Большой.
Связность:
- PositionState
- AutoTradeState
- PositionMetrics
- ExecutionPrice
- JournalService
- EventBus
Что сделано:
- Добавлен helper
_build_runtime_protection_payload(). - Построение payload вынесено из
_log_runtime_protection_event(). _log_runtime_protection_event()теперь отвечает только за:- построение payload;
- запись в JournalService;
- публикацию EventBus.
- Поведение protection полностью сохранено.
Что НЕ изменялось:
- Break-even.
- Profit lock.
- Trailing stop.
- Protection thresholds.
- Алгоритм закрытия позиции.
- Journal payload.
- EventBus payload.
Что нельзя менять на следующих этапах:
- Последовательность обработки protection.
- Логику определения close reason.
- Формулы расчёта protection уровней.
- Runtime protection thresholds.
Возможный следующий этап:
- При необходимости вынести protection thresholds в отдельный constants.py, но только после завершения всего безопасного рефакторинга execution.
Итог: Файл приведён к единому стилю execution.
position_exit_decision.py
Статус: Audited / no changes now
Назначение:
- Runtime-intelligence решение о закрытии позиции.
- Определяет close reason по giveback, time-decay, hard-loss и нормальному pullback.
Размер:
- Средний/большой.
Связность:
- Зависит от AutoTradeState, PositionState, PositionMetrics.
- Использует build_position_metrics().
- Использует get_position_exit_thresholds() из execution/constants.py.
Что хорошо:
- Расчёты позиции берутся из position_metrics.py.
- Thresholds вынесены из файла.
- Giveback и time-decay разделены по отдельным методам.
- Нет JournalService/EventBus/payload.
Что настораживает:
- Длинные методы
_giveback_close_reason()и_time_decay_close_reason(). - Много строковых close reason прямо внутри условий.
- Decision-методы частично изменяют state.
Безопасные улучшения:
- Сейчас не требуются.
Что нельзя менять:
- Порядок проверки giveback/time-decay.
- Порядок условий внутри
_giveback_close_reason(). - Порядок условий внутри
_time_decay_close_reason(). - Строковые close reason.
- Изменения state внутри decision-логики.
- Thresholds.
Будущий возможный этап:
- После завершения безопасного аудита можно отдельно обсудить вынос reason-кодов в constants.py.
- Дробление длинных методов делать только отдельным этапом с тестами.
Итог: Файл архитектурно понятный, но чувствительный к порядку условий. На текущем этапе оставляем без изменений.
runtime_actions.py
Статус: Audited / candidate for safe payload extraction
Назначение:
- Runtime autonomous actions для открытой позиции.
- Обрабатывает autonomous EXIT / REDUCE / PROTECT.
- Проверяет cooldown runtime actions.
- Логирует runtime action события.
Размер:
- Средний/большой.
Связность:
- Зависит от AutoTradeState, PositionState, ExecutionDecision.
- Использует JournalService и EventBus.
- Использует execution constants и get_position_exit_thresholds().
Что хорошо:
- Основной вход —
process_runtime_action(). - Cooldown вынесен в
_runtime_action_cooldown_active(). - Early exit guard вынесен в
_early_exit_guard_active(). - Закрытие позиции выполняется через общий
_close_position().
Что настораживает:
- Большой payload внутри
_log_runtime_action(). _log_runtime_action()совмещает dedupe, payload, Journal, EventBus, state update и ExecutionDecision.
Безопасные улучшения:
- Вынести payload из
_log_runtime_action()в_build_runtime_action_payload().
Что нельзя менять:
- Порядок обработки action.
- Early exit guard.
- Confidence threshold.
- Cooldown logic.
- Deduplication key.
- State updates в
_log_runtime_action(). - Journal/EventBus payload.
Итог: Файл рабочий. Первый безопасный шаг — вынести payload builder без изменения поведения.
runtime_actions.py
Статус: Completed (safe refactoring stage 1)
Что сделано:
- Добавлен helper
_build_runtime_action_payload(). - Payload вынесен из
_log_runtime_action(). _log_runtime_action()сохранил dedupe, JournalService, EventBus, state update и ExecutionDecision.- Поведение runtime actions не менялось.
Что НЕ изменялось:
- Порядок обработки autonomous action.
- Cooldown logic.
- Early exit guard.
- Confidence threshold.
- Deduplication key.
- Journal/EventBus payload.
- State updates.
Итог: Файл приведён к единому стилю execution.
supervisor.py
Статус: Audited / candidate for safe payload extraction
Назначение:
- Execution supervisor перед исполнением торгового действия.
- Блокирует исполнение при emergency halt, cooldown, degraded market, stale execution, entry block, low confidence и signal conflict.
Размер:
- Средний/большой.
Связность:
- Зависит от AutoTradeState, ExecutionDecision, JournalService, EventBus.
- Использует execution thresholds/settings из состояния и констант engine.
Что хорошо:
- Основной вход —
_process_execution_supervisor(). - Причины блокировки разделены по отдельным методам.
- UI-тексты вынесены в
_human_execution_block(). - Есть dedupe через
_last_supervisor_block_key.
Что настораживает:
- Большой payload внутри
_block_execution(). _block_execution()совмещает state update, UI block, dedupe, payload, JournalService, EventBus и ExecutionDecision.
Безопасные улучшения:
- Вынести payload из
_block_execution()в_build_supervisor_block_payload().
Что нельзя менять:
- Порядок проверок в
_process_execution_supervisor(). - Логику emergency halt.
- Cooldown logic.
- Degraded market logic.
- Early impulse allowance.
- Stale execution logic.
- Entry block logic.
- Low execution confidence logic.
- Conflict signal logic.
- UI-тексты в
_human_execution_block(). - Dedupe key.
- Journal/EventBus payload.
Итог: Файл рабочий. Первый безопасный шаг — вынести payload builder без изменения поведения.
supervisor.py
Статус: Completed (safe refactoring stage 1)
Что сделано:
- Добавлен helper
_build_supervisor_block_payload(). - Payload вынесен из
_block_execution(). _block_execution()сохранил:- state update;
- UI block;
- dedupe;
- JournalService;
- EventBus;
- ExecutionDecision.
- Поведение supervisor не менялось.
Что НЕ изменялось:
- Порядок проверок supervisor.
- Emergency halt.
- Cooldown logic.
- Degraded market logic.
- Early impulse allowance.
- Stale execution logic.
- Entry block logic.
- Low confidence logic.
- Signal conflict logic.
- UI-тексты.
- Dedupe key.
- Journal/EventBus payload.
Итог: Файл приведён к единому стилю execution.
sizing.py
Статус: Audited / no logic changes
Назначение:
- Расчёт размера позиции по risk и stop-loss.
- Adaptive size multiplier.
- Market score для sizing.
- Синхронизация adaptive size/effective risk в AutoTradeState.
- Ограничение размера позиции по margin limit.
- Округление размера позиции.
Размер:
- Средний/большой.
Связность:
- Зависит от AutoTradeState, ExecutionPrice, safe_float.
- Активно изменяет поля AutoTradeState.
Что хорошо:
- Расчёт размера, multiplier, market score, margin limit и rounding разделены.
- Нет JournalService/EventBus/payload.
_sync_effective_risk_after_margin_limit()вынесен отдельно.
Что настораживает:
- Очень чувствительный файл: любые изменения влияют на реальные размеры сделок.
- Много state updates.
- Повторяются вызовы
_sync_adaptive_size_state(...0...), но пока их лучше не трогать.
Безопасные улучшения:
- Только косметика форматирования.
Что нельзя менять:
- Формулу base size.
- Adaptive multiplier thresholds.
- Market score thresholds.
- Execution quality multipliers.
- Margin limit logic.
- Effective risk recalculation.
- Rounding logic.
Итог: Файл архитектурно понятный, но очень чувствительный. На текущем этапе оставляем без изменения логики.
engine.py
Статус: Audited / minor cleanup only
Назначение:
- Главная orchestration-точка execution layer.
- Управляет последовательностью execution pipeline.
Размер:
- Нормальный.
Связность:
- Собирает execution mixins.
- Использует AutoTradeState, ExecutionDecision и PositionState.
- Не содержит JournalService/EventBus/payload.
Что хорошо:
process()имеет понятный последовательный pipeline.- Бизнес-логика вынесена в mixins.
- Risk close, runtime protection, supervisor, flip и open position разделены.
- Нет прямых расчётов PnL/sizing/pricing внутри engine.
Pipeline:
- Sync state.
- Проверка RUNNING.
- Update unrealized PnL.
- Risk close.
- Runtime protection.
- Signal readiness.
- Execution supervisor.
- Duplicate signal guard.
- Flip.
- Open position.
- Skip if no action.
Безопасные улучшения:
- Только косметика форматирования.
Что нельзя менять:
- Порядок pipeline.
- Состав mixins.
- Class-level настройки.
- Duplicate signal guard.
- Порядок flip/open position.
Итог: Файл соответствует роли orchestration layer. Логических правок не требуется.
flip.py
Статус: Completed (safe refactoring stage 1)
Что сделано:
- Добавлен helper
_reject_flip(). - Вынесены payload builders:
_build_flip_rejected_payload()_build_flip_blocked_payload()_build_flip_executed_payload()
- Методы сгруппированы по смыслу:
- payload builders
- journal helpers
- decision helpers
- flip checks
- execution
- Поведение flip не менялось.
Что НЕ изменялось:
_flip_position()не разбивался._flip_block_reason()не разбивался.- Алгоритм flip не менялся.
- Порядок проверок не менялся.
- Payload не расширялся.
- EventBus не менялся.
- JournalService не менялся.
- ExecutionDecision не менялся.
Что нельзя менять на текущем этапе:
- Порядок расчёта exit/entry price.
- Расчёт pnl.
- Обновление cycle stats.
- Логику loss cooldown.
- Создание новой PositionState.
- Порядок reset runtime/protection state.
- Порядок Journal/EventBus событий.
Будущий этап:
- Только после завершения всего аудита можно отдельно рассмотреть аккуратное разбиение
_flip_position()на несколько внутренних шагов. - Расширение payload для анализа стратегии делать отдельным этапом, не смешивать с safe refactoring.
Итог: Файл приведён к единому стилю execution. На текущем безопасном этапе дополнительных правок не требуется.
position_actions.py
Статус: Completed (safe refactoring stage 1)
Что сделано:
- Добавлен helper
_reject_position_open(). - Вынесены payload builders:
_build_position_open_rejected_payload()_build_position_opened_payload()_build_position_closed_payload()
- Методы сгруппированы:
- trade id
- payload builders
- journal helpers
- decision helpers
- position actions
- Поведение открытия/закрытия позиции не менялось.
Что НЕ изменялось:
_open_position_if_empty()не разбивался._close_position()не разбивался.- Алгоритм открытия позиции не менялся.
- Алгоритм закрытия позиции не менялся.
- Payload не расширялся.
- JournalService/EventBus не менялись.
- ExecutionDecision не менялся.
Что нельзя менять на текущем этапе:
- Порядок расчёта entry/exit price.
- Расчёт size.
- Margin limit.
- Расчёт pnl.
- Обновление cycle stats.
- Loss cooldown.
- Reset position/protection runtime.
- Порядок Journal/EventBus событий.
Итог: Файл приведён к единому стилю execution. На текущем безопасном этапе дополнительных правок не требуется.
constants.py
Статус: Completed
Назначение:
- Единая точка констант execution layer.
- Хранит execution actions, types, reasons, pricing modes, runtime actions, position health/risk/exit thresholds и flip filters.
Что сделано ранее:
- Удалены дубли констант.
- Константы сгруппированы по смысловым разделам.
- Сохранены существующие имена констант.
- Логика не менялась.
Что хорошо:
- Есть asset-specific thresholds.
- Есть helper
asset_symbol(). - Есть helper
get_position_thresholds(). - Health/exit thresholds доступны через отдельные helpers.
build_flip_action()оставлен совместимым.
Что нельзя менять:
- Имена существующих констант.
- Значения thresholds.
- Структуру
DEFAULT_POSITION_THRESHOLDS. - Структуру
POSITION_THRESHOLDS_BY_ASSET. - Поведение helper-функций.
Итог: Файл завершён. Дополнительных правок на safe stage не требуется.
Safe refactoring stage 1 — completed
Статус: завершён.
Проверены все файлы app/src/trading/execution.
Итог:
- payload builders вынесены из крупных execution-файлов;
- reject/block helpers добавлены там, где это безопасно;
- pricing унифицирован через
_build_execution_price(); - position metrics признан центральной точкой расчётов;
- engine подтверждён как orchestration layer;
- бизнес-логика не менялась;
- payload не расширялся;
- бот после каждого шага успешно перезапускался.