Stage 07.4.4.1.14 — Execution refactoring and runtime semantics
This commit is contained in:
902
docs/architecture/execution_refactoring.md
Normal file
902
docs/architecture/execution_refactoring.md
Normal file
@@ -0,0 +1,902 @@
|
||||
# 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
|
||||
|
||||
Порядок методов:
|
||||
|
||||
1. Payload builders
|
||||
2. Journal helpers
|
||||
3. Decision helpers
|
||||
4. Validation / Checks
|
||||
5. Execution methods
|
||||
6. Utility methods
|
||||
|
||||
### Уже обработаны
|
||||
|
||||
- constants.py
|
||||
- flip.py
|
||||
- position_actions.py
|
||||
- risk_close.py
|
||||
|
||||
### Этап A — маленькие и базовые файлы
|
||||
|
||||
1. quality.py
|
||||
2. models.py
|
||||
3. calculations.py
|
||||
4. resets.py
|
||||
5. pricing.py
|
||||
6. engine.py
|
||||
|
||||
### Этап B — средние файлы
|
||||
|
||||
7. position_runtime.py
|
||||
8. sizing.py
|
||||
9. runtime_actions.py
|
||||
10. position_exit_decision.py
|
||||
|
||||
### Этап C — крупные и рискованные файлы
|
||||
|
||||
11. position_metrics.py
|
||||
12. supervisor.py
|
||||
13. 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_ASK`
|
||||
- `SHORT_ENTRY_BID`
|
||||
- `ENTRY_LAST`
|
||||
- `LONG_EXIT_BID`
|
||||
- `SHORT_EXIT_ASK`
|
||||
- `EXIT_LAST`
|
||||
- `MARKET_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
|
||||
|
||||
Принятые правила:
|
||||
|
||||
1. Любые вычисления позиции должны происходить только через position_metrics.py.
|
||||
|
||||
2. Pricing не должен содержать бизнес-логику.
|
||||
|
||||
3. Mixins должны иметь следующую структуру:
|
||||
|
||||
- helpers
|
||||
- journal helpers
|
||||
- validation
|
||||
- execution
|
||||
- utility
|
||||
|
||||
4. Все безопасные рефакторинги выполняются без изменения поведения 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:
|
||||
1. Sync state.
|
||||
2. Проверка RUNNING.
|
||||
3. Update unrealized PnL.
|
||||
4. Risk close.
|
||||
5. Runtime protection.
|
||||
6. Signal readiness.
|
||||
7. Execution supervisor.
|
||||
8. Duplicate signal guard.
|
||||
9. Flip.
|
||||
10. Open position.
|
||||
11. 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 не расширялся;
|
||||
- бот после каждого шага успешно перезапускался.
|
||||
Reference in New Issue
Block a user