902 lines
31 KiB
Markdown
902 lines
31 KiB
Markdown
# 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 не расширялся;
|
||
- бот после каждого шага успешно перезапускался. |