# Stage 05.8 — Quantity Normalization by Exchange Rules

# Stage 05.8 — Нормализация количества по правилам биржи

## Кратко

Добавлена единая нормализация quantity во всем flow создания и редактирования ордера.

Количество теперь всегда:
- соответствует stepSize
- не меньше minQty
- учитывает minNotional
- отображается без float-артефактов

---

## Что сделано

- Нормализация quantity вынесена в сервис (`OrderDraftsService`)
- Одинаковая логика для preset и ручного ввода
- Для LIMIT без цены используется рыночный reference price
- Убраны хвосты типа `0.0050000003`
- Количество стабильно на всех шагах FSM

---

## Поведение

### Малое значение
Если пользователь вводит слишком маленькое количество:
- система автоматически корректирует до допустимого (если возможно)
- иначе показывает ошибку

### LIMIT без цены
- minNotional считается через рынок (ask/bid)
- не нужно ждать ввода цены

---

## Затронутые файлы

- app/src/trading/orders/service.py  
- app/src/telegram/handlers/trade/new_order_flow.py  

---

## Changelog

### Added
- Нормализация quantity по stepSize, minQty, minNotional
- Автокоррекция при ручном вводе

### Changed
- Flow quantity переведен на normalize_entry_quantity
- Preset quantity проходит через те же правила

### Fixed
- Убраны float-артефакты
- Исправлена рассинхронизация quantity между шагами

---

## Breaking Changes

- quantity теперь может автоматически изменяться системой
  (например: 0.000001 → 0.0002)

- normalize_quantity больше не используется как финальный результат

- для LIMIT без цены используется reference price




⸻

Stage 05.8 — quantity normalization by exchange rules

Что сделано

На этапе формирования и редактирования ордера добавлена единая нормализация количества по биржевым правилам.

Теперь количество приводится к корректному виду не только при финальной валидации, но уже в самом flow создания/редактирования черновика.

Это устраняет проблемы с:

* хвостами после вычислений и округлений
* значениями, не кратными stepSize
* слишком маленькими значениями, которые должны быть автоматически доведены до допустимого минимума
* расхождениями между количеством на разных экранах одного и того же ордера

⸻

Основные изменения

1. Добавлена нормализация количества по правилам биржи

В OrderDraftsService добавлены методы:

* normalize_entry_quantity(...)
* normalize_preset_quantity(...)
* внутренняя логика _normalize_entry_quantity_with_rules(...)

Они:

* принимают “сырое” количество
* приводят его к Decimal
* учитывают stepSize
* учитывают minQty
* учитывают minNotional
* возвращают уже готовую нормализованную строку количества

⸻

2. Для LIMIT-ордера minimum по quantity теперь считается ещё до ввода цены

Если пользователь находится на этапе ввода количества для LIMIT-ордера и цена ещё не введена, сервис больше не пропускает расчёт minNotional.

Вместо этого используется рыночный ориентир:

* для BUY — ask_price
* для SELL — bid_price

Благодаря этому минимально допустимое количество считается корректно уже на этапе quantity.

Пример:

* пользователь вводит 0.000001
* minQty = 0.0001
* но по minNotional требуется 0.0002
* теперь система автоматически приводит quantity к 0.0002

⸻

3. Нормализация применяется и для preset-кнопок, и для ручного ввода

Одинаковая логика работает в обоих сценариях:

* выбор количества через кнопки preset
* ручной ввод количества

Это гарантирует единое поведение вне зависимости от того, как пользователь выбрал quantity.

⸻

4. Исправлены визуальные артефакты количества

Убраны случаи, когда в flow отображались значения типа:

* 0.0050000003
* 0.001300000000000000

После нормализации во всех экранах показывается чистое значение, например:

* 0.005
* 0.0013

⸻

Затронутые файлы

app/src/trading/orders/service.py

Добавлена бизнес-логика нормализации количества:

* отдельные методы для preset/manual quantity
* расчёт минимально допустимого количества по minQty и minNotional
* использование reference price для LIMIT even before explicit price input

app/src/telegram/handlers/trade/new_order_flow.py

Flow переключён на новые методы нормализации:

* process_quantity_callback(...)
* process_order_quantity(...)

Теперь далее по сценарию передаётся уже нормализованное quantity.

⸻

Поведение после изменений

Ручной ввод слишком малого количества

Если пользователь вводит quantity ниже допустимого минимума, система не обязательно сразу показывает ошибку.

Если значение можно автоматически привести к допустимому:

* количество округляется по шагу
* при необходимости поднимается до минимального значения
* дальше по flow используется уже скорректированное quantity

⸻

Preset quantity

Если preset даёт слишком маленькое количество:

* оно не превращается в 0
* не остаётся “грязным”
* приводится к допустимому биржей значению

⸻

LIMIT до ввода цены

Для LIMIT-ордера на этапе quantity:

* minimum по minNotional считается по рыночному ориентиру
* не требуется дожидаться отдельного ввода цены

⸻

Что проверено

После изменений вручную были проверены 6 регрессионных сценариев:

1. BUY + LIMIT + manual quantity below minimum
2. SELL + LIMIT + manual quantity below minimum
3. LIMIT + preset quantity
4. MARKET + manual quantity
5. edit draft + change quantity
6. переходы назад/вперёд после автонормализации

Все сценарии отработали корректно при стабильной связи с биржей.

⸻

Что не входит в этот этап

Stage 05.8 не решает задачи отказоустойчивости сети и API биржи.

Если биржа не отвечает или отвечает с таймаутом:

* flow по-прежнему может падать на этапе получения market/balance/exchange metadata
* это отдельная задача для следующего этапа

⸻

Итог

Stage 05.8 завершает блок нормализации количества и делает quantity-flow устойчивым с точки зрения биржевых ограничений.

Пользователь теперь видит:

* корректное quantity
* одинаковое quantity на всех этапах
* отсутствие мусорных хвостов
* корректный минимум по minQty и minNotional

⸻

Для коммита можно использовать:

git add app/src/trading/orders/service.py app/src/telegram/handlers/trade/new_order_flow.py
git commit -m "Stage 05.8 - quantity normalization by exchange rules"