# MOVE_HOLD.md — ідентифікація рухів вгору/вниз як індикатор УТРИМАННЯ угоди

Постановка (15.08.2026). Ми не шукаємо тут точку входу. Питання інше й вужче:
**угода вже відкрита — чи каже книга, що рух, у якому ми сидимо, ще триває?**
Тобто ціль системи — не «куди піде», а «чи ще тримати».

Різниця принципова, і вона одразу міняє метрику. Сигнал входу треба міряти
точністю на рідкій події й окупністю комісії 0.30% за оборот. Індикатор
утримання міряється інакше: скільки відсотків руху ми з ним забираємо проти
«тримати до кінця сесії» і проти «вийти за фіксованим стопом». Він може бути
слабким як класифікатор і при цьому корисним як фільтр виходу.

Документ написаний за `DIARY_STANDARD.md` — це **виконуваний рецепт наступної
роботи**, а не опис зробленого. Числа в ньому — вже виміряні на датасеті
BTC 14.02–08.08.2026 (56263 вікна 210 с, кеш `class4/cache08`), вкладка
[/zznet](https://marketflowresear.ch), і саме вони задають, що тут можна робити,
а що вже перевірено й не працює.

---

## 1. Вхід

**Формат.** Вікно 210 с × 8 ордербук-фіч, сирі числа, подання лінії
`log1p(x/0.01)`. Ні ціни, ні часу, ні норми, ні відповідей інших детекторів на
вході — усе, що додається, додається окремим кроком і окремо міряється.

**Мінімальний обсяг.** 175 діб / 56263 вікна дають 120 ніг зигзага 2.3% і
119 переломів. Це **дуже мало для подієвої статистики**: будь-яке твердження про
переломи стоїть на сотні незалежних випадків, і бутстреп треба робити по
переломах, а не по вікнах (одна нога — до 9 сусідніх вікон).

**Головне правило задачі.** Одиниця вимірювання — **рух**, а не вікно. Вікна
всередині одного руху корелюють; будь-яка метрика, порахована по вікнах, буде
завищена рівно настільки, наскільки довгі ноги.

---

## 2. Що вже виміряно і чого повторювати не треба

Ці числа — з вкладки /zznet, розділи ⑧-⑨. Вони обмежують простір рішень.

| питання | число | висновок |
|---|---|---|
| у якій половині руху ми зараз (нога вгору проти вниз) | AUC 0.496-0.520 після поправки на гучність | **книга мовчить** |
| те саме на 40 описах (/zzall) | 0.513-0.557 | те саме |
| бік УЖЕ НАЯВНОГО перелому (вершина/дно) | \|0.60-0.62\| на рівнях, 0.736 на рівні події | **читається** |
| розворот проти не-розвороту при однаковій гучності | 0.565 (найкраще: обсяги мінус стіни) | ледь |
| сама гучність як детектор розвороту | 0.7575 проти 0.7571 у мережі на 1680 числах | **рівень вичерпано** |
| напрям через годину (/zzall dir) | 0.504-0.510 при нулі 0.500 | прогнозу немає |

**Читання.** Ордербук КОНСТАТУЄ стан і момент, але не віщує напрям. Отже
індикатор утримання не може бути побудований як «модель напряму». Він може бути
побудований тільки як **детектор кінця руху**: поки ознак перелому немає —
тримаємо.

**Єдина величина, що йде за напрямом руху і не є тінню гучності** — чистий
приріст стіни на одиницю агресії свого боку,
`(приплив − відтік) / обсяг`:

| період | (resist_plus − resist_minus)/vol_buy | (support_plus − support_minus)/vol_sell |
|---|---|---|
| дно | 18.42 | 13.87 |
| нога вниз | 19.16 | 15.58 |
| нога вгору | 16.80 | 17.09 |
| вершина | 14.47 | 16.95 |
| не-розворот, зіставлений за гучністю | 17.07 | 17.47 |

У падінні стіна продавців доростає швидше на одиницю покупок; у зростанні —
дзеркально. У найтихіших і найгучніших множинах різниця того самого порядку,
тобто це **не гучність**. Саме ця пара чисел — головний кандидат у вхід
індикатора.

---

## 3. Кроки

### Крок 1. Мітка «рух триває»
Не брати мітку зигзага як є — вона знає майбутнє. Правильна мітка утримання:
для кожного вікна `t` і горизонту `H` — чи не стався перелом зигзага 2.3% в
інтервалі `(t, t+H]`. Тобто ціль **бінарна і причинна**: «наступні H хвилин без
перелому».
*Контроль:* частка позитивів мусить дорівнювати `1 − H/середня нога`; при
H = 1 год і середній нозі 33.9 год це ≈97%. Мітка вироджена — і саме тому
працювати треба на **подієвому** рівні (крок 3), а не на віконному.

### Крок 2. Вхід без гучності
Три групи чисел, кожна окремо і разом:
* `A` — 8 середніх рівнів вікна (еталон лінії);
* `B` — дві величини `(приплив − відтік)/обсяг` по боках книги;
* `C` — `B` плюс дві `const/обсяг`.
**Гучність із входу прибирається обовʼязково** — або стратифікацією по децилях,
або віднімання регресії на `loud8`. Без цього будь-яке число з таблиці вище
перетворюється на «наскільки гучно», що вже виміряно і вичерпано.
*Контроль:* AUC самої гучності на вашому розрізі мусить впасти до 0.50 ± 0.01.

### Крок 3. Оцінка НА РУХАХ, не на вікнах
Відповіді усереднюються всередині руху (нога від пивота до пивота), і метрика
рахується по 120 ногах. Бутстреп — по ногах.
*Контроль:* віконна AUC мусить бути ПОМІТНО вищою за подієву; якщо вони
збіглися — десь протекло сусідство.

### Крок 4. Торговий переклад
Індикатор виводиться в одне рішення: `тримати / вийти`. Міряється трьома
числами проти трьох еталонів:
* забраний відсоток ноги проти «тримати до кінця ноги» (стеля);
* те саме проти фіксованого стопу 2×TP (правило проєкту: ТП завжди менший за СЛ);
* те саме проти виходу за часом (42-годинна сесія — стандарт проєкту).
*Контроль:* усе брутто, потім мінус **0.30% за оборот**. Число, що не перекриває
комісію, не є результатом.

### Крок 5. Нуль-контроль і свіжі дані
Нуль — циклічний зсув мітки відносно вікон (999 зсувів). Спліт — блоковий,
ембарго 30 хв. Фінальна перевірка — на даних після межі датасету, замороженими
вагами й порогами (як розділ ⑩ вкладки /zznet).

---

## 4. Пастки

1. **Зигзаг знає майбутнє.** Нога визначена лише після наступного пивота. Будь-яка
   мітка, побудована на «ми в нозі вгору», у реальному часі недоступна — тому
   ціль формулюється як «перелому НЕ буде протягом H», а не «це нога вгору».
2. **Гучність поглинає все.** Половина «відкриттів» цієї лінії виявлялись
   рівнем: сама гучність дає 0.7575 там, де мережа на 1680 числах дає 0.7571.
   Поправка на гучність — не опція, а частина постановки.
3. **Гронування.** Один перелом — до 9 сусідніх вікон 210 с. Метрика по вікнах
   зважена довжиною грона і завищена.
4. **Пастка Сімпсона на боках.** У сирих рівнях `vol_sell` вищий на ДНІ; при
   однаковій гучності — навпаки, на ВЕРШИНІ (0.617). Без стратифікації знак
   читається протилежно.
5. **Мітка з тих самих чисел.** Якщо ціль побудована з тих самих 1680 чисел
   (як «очищений датасет» у /zznet), висока якість нічого не доводить — це
   тавтологія. Мітка утримання мусить приходити з ЦІНИ.
6. **Нерівні множини.** Добір пари за гучністю потребує донорського запасу:
   вершин 407, дна 416 — добір там не працює (гучність лишається 0.416 замість
   0.5), потрібна стратифікація.
7. **Комісія.** 0.15% за дію. Перевага моделі ніг над випадковістю в 4-6 в.п.
   (лінія /nets) вимагала 10 в.п., щоб окупитись, — і напрям було закрито.

---

## 5. Таблиця контрольних чисел з допусками

Прогін вважається відтвореним, якщо всі числа в межах допуску.

| що | очікуване | допуск |
|---|---|---|
| вікон у датасеті | 56 263 | точно |
| ніг зигзага 2.3% / переломів | 120 / 119 | точно |
| середня тривалість ноги | 33.86 год | ±0.05 |
| розворотних вікон (±15 хв) | 863 (823 в очищеному) | точно |
| AUC гучності після поправки | 0.500 | ±0.010 |
| нога вгору проти вниз, будь-яка фіча | 0.50 | ±0.035 |
| вершина проти дна, vol_sell | 0.617 | ±0.02 |
| (приплив−відтік)/обсяг, нога вниз | 19.16 / 15.58 | ±0.15 |
| (приплив−відтік)/обсяг, нога вгору | 16.80 / 17.09 | ±0.15 |
| комісія за оборот | 0.30% | точно |

---

## 6. Відкинуті напрямки (не пропонувати повторно)

* **Модель напряму на вікні** — 0.504-0.510 при нулі 0.500, пʼять різних
  постановок у трьох лініях.
* **Стредл/брекет на VOL_SCORE** — закрито рішенням користувача.
* **Стиснення події (PCA, автокодувальник)** перед головою — програло одному
  числу тричі (/events, /ae, /pool).
* **Форма всередині вікна як самостійний вхід** — 1680 чисел програють 8-16
  числам у кожній постановці лінії.
* **Мітка «+1% раніше за −2%»** — AUC 0.437 на пʼятьох сідах.

---

## 7. Порядок команд

```bash
python3 zznet.py corr BTC          # кореляції фіч у трьох сенсах
python3 zznet.py heat BTC          # множини, теплові карти, поправка на гучність
python3 zzclust.py legs BTC        # таблиця ніг зигзага 2.3%
# далі — новий етап hold (ще не написаний):
#   python3 zznet.py hold BTC       # мітка «без перелому протягом H», кроки 1-3
#   python3 zznet.py holdtrade BTC  # крок 4: переклад у рішення і комісія
```

---

## 8. Що зробить цей документ неправильним

Якщо на подієвому рівні (120 ніг) величина `(приплив − відтік)/обсяг` дасть AUC
у межах нуль-контролю — індикатор утримання на ордербуці закривається так само,
як закрито напрям, і це треба буде записати тут же, у цьому файлі. Помилки з
щоденників не вирізаються.
