# Дослідження 28 — краї ноги і кількість подій

| | |
| --- | --- |
| Пари | BTC_USDT, ETH_USDT, SOL_USDT, XRP_USDT, BNB_USDT, DOGE_USDT |
| Ряд подій | `class210x10x7`, `train` + `val` разом |
| Розмітка | зігзаг 2.3 % на ема10, нога ділиться на 10 десятин |
| Величина події | ціна події (етап 1); будь-яка фіча класу — тим самим ходом |
| Статус | етапи 1–8 підтверджені, 2026-09-09 |
| Вкладка | [`/edges`](http://localhost:8080/edges) |
| Правила | [`02-markup.md`](../../rules/02-markup.md), [`05-visualization.md`](../../rules/05-visualization.md) |

## Ціль

Дослідження 01 (етап 10) знайшло дві речі й на них зупинилось:

- рух ноги зігзага 2.3 % збирається на її **краях** — 18 % у першій
  десятині, 19 % в останній, по 6 % у середині;
- **кількість подій** у нозі гуляє від десятків до тисяч, і з рухом ноги
  вона повʼязана слабко (+0.420).

Тут обидві міряються окремо й до кінця: профіль по десятинах, краї проти
середини, розподіл довжини ноги і те, як довжина міняє профіль.

Головне — **метод**. Він написаний так, щоб тим самим ходом виміряти
будь-який клас проєкту: міняється лише величина події, решта однакова,
тому профілі різних класів прямо порівнюються між собою.

## Метод: як аналізується подія в нозі

Порядок кроків. Кожен крок однаковий для ціни й для будь-якої фічі класу —
різниця тільки в кроці 5.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Ряд подій** | усі події монети за часом: `train` + `val` разом, без розривів у нумерації. Ключ часу — `t_start` (класи на блоки по 21 с) або `timestamp` (класи на блоки по 14 с) |
| 2 | **Півоти** | `ема10(price_open)` → зігзаг 2.3 % ([`rules/scripts/zigzag.py`](../../rules/scripts/zigzag.py)) |
| 3 | **Ноги** | нога — від події **після** попереднього півота до самого півота включно; напрямок за півотом, яким вона закінчується |
| 4 | **Десятини** | нога ділиться на 10 рівних частин **за кількістю подій**: `1` — перші 10 % подій, `10` — останні. Місце міряється часом, не ціною |
| 5 | **Величина події `v`** | ціна: `v = ln(price_close / price_open)` — рух за 210 с самої події. Фіча класу: значення фічі, згорнуте по блоках події (`mean`, `sum` або `last`) |
| 6 | **Приведення до ноги** | `v ← v · direction`, де `direction` = +1 для ноги вгору і −1 для ноги вниз. Після цього «за ногою» завжди додатне, і ноги обох напрямків лягають в один ряд |
| 7 | **Фільтр ніг** | нога з дірою в ряді довше за 1 год **не рахується**: дослідження 01 (етап 11) показало, що на таких ногах рух приходить із розриву, а не з подій |
| 8 | **Профіль** | сума `v` по кожній десятині, поділена на суму по нозі |
| 9 | **Два способи звести** | `пулом` — сума десятини по всіх ногах до загальної суми; `по нозі` — частка рахується в кожній нозі окремо й усереднюється |
| 10 | **Краї проти середини** | краї — десятини 1 і 10, середина — 4–7; звіряється сума країв, сума середини і відношення однієї десятини краю до однієї десятини середини |
| 11 | **Довжина ноги** | кількість подій у нозі: медіана, квартилі, гістограма, і той самий профіль окремо по чотирьох групах довжини |

Чому саме так:

- **Пул і по нозі дають різні відповіді, і обидві потрібні.** Пулом
  довга нога важить більше — це відповідь на питання «де лежить рух».
  По нозі всі ноги рівні — це відповідь на питання «як виглядає типова
  нога».
- **Приведення до напрямку** дозволяє не ділити вибірку навпіл. Без нього
  ноги вниз давали б дзеркальні знаки й у сумі гасили ноги вгору.
- **Фільтр дір** обовʼязковий: без нього 158 ніг із 712 приносять у профіль
  рух, якого в подіях немає.
- Для фічі, яка **не додається** (рівень, обʼєм, похідна), частка суми
  сенсу не має — тоді читається `mean`: середня величина події десятини.
  Скрипт рахує обидва.

### Як повторити на будь-якому класі

```bash
# ціна події — базовий замір, етап 1
python3 research/28-leg-edge-profile/scripts/edge_profile.py

# будь-яка фіча будь-якого класу тим самим ходом
python3 research/28-leg-edge-profile/scripts/edge_profile.py \
    --class class210x10x7 --feature vol_balance --reduce mean
```

- `--class` — тека класу в `data/datasets/<PAIR>/`; ряд і ноги беруться
  з неї ж, тому клас міряється **на своїй сітці подій**.
- `--feature` — імʼя фічі з `features` того класу; без ключа міряється
  ціна події.
- `--reduce` — як звести блоки події в одне число: `mean` (за
  замовчуванням), `sum` або `last`.
- Вихід лягає в `results/edge_profile_<клас>_<фіча>.json`, тому заміри
  не затирають один одного і порівнюються між собою.

## Етап 2: початок ноги

Береться **тільки початок ноги** — її перші події після півота — і з нього
ставляться три питання про решту ноги.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Ряд, півоти, ноги, фільтр дір** | ті самі, що на етапі 1 |
| 2 | **Початок ноги** | три способи: `перші 10 % ноги` (постановка етапу 1, медіана 39 подій); `перші 39 подій після півота` — стале число подій, узяте рівним тій медіані, щоб початки були одного розміру; `рух 0.15 / 0.30 / 0.50 % від півота` — початок триває, поки \|ln(ціна / ціна півота)\| не дійде до межі, тобто міряється відсотком ціни, а не подіями |
| 3 | **Ознаки початку** | 31 число з подій самого початку: рух (`v_sum`, `v_mean`, `v_std`, `v_max`, `v_min`, `v_last`, `v_abs`, `up_share`, `run_up`, `draw_down`, `path`, `straight`), час (`n`, `seconds`, `gap`), ціна (`price`, `ema_slope`) і по кожній із 7 фіч `class210x10x7` — середнє й нахил усередині початку |
| 4 | **Ціль 1 — напрямок** | нога вгору (1) чи вниз (0) |
| 5 | **Ціль 2 — події завершення** | `events_left` — ln подій до кінця ноги; `last_share` — частка руху ноги, що ляже в останню десятину; `last_event` — середній рух події останньої десятини, за ногою |
| 6 | **Ціль 3 — зустрічний рух** | по подіях решти ноги, що йдуть **проти** неї: `against_share` — їх частка, `against_p90` — 90-й процентиль \|ln\|, `against_max` — найбільша, `against_sum` — сума зустрічного руху до руху ноги |
| 7 | **Розбиття** | нога йде у `val`, якщо її перша подія від **2026-08-14**, інакше — у `train` |
| 8 | **Модель** | градієнтний бустинг (`HistGradientBoosting`, 300 дерев, крок 0.05, 7 листків, seed 17) на ознаках початку |
| 9 | **Базовий рівень** | напрямок — частка більшого класу на `train`; числа — медіана `train` |
| 10 | **Якість** | напрямок — точність і AUC на `val`; числа — кореляція Спірмена і **медіанна** похибка проти базової |
| 11 | **Два прогони ознак** | `усі` і `без довжини ноги` — без `n` і `seconds` |

Чому два способи взяти початок:

- **Перші 10 % ноги** — це постановка етапу 1, але сам розмір такого
  початку вже знає довжину ноги, а разом із ним її знає будь-яка сума по
  початку (`v_sum`, `path`, `run_up`). Тому `events_left` тут не
  прогноз, а вимір: Спірмен `+0.995`, і навіть без `n` і `seconds` —
  `+0.956`.
- **Перші 39 подій після півота** — стале число подій, у якому про
  майбутнє немає нічого. Саме 39 — це медіана довжини тих «перших
  10 %», тому два способи взяти початок мають однаковий розмір і
  порівнюються прямо.
- **Рух 0.15 / 0.30 / 0.50 % від півота** — межа не в подіях, а у
  відсотках ціни: початок триває, поки ціна не відійде від півота на
  задане. Це причинна межа (у реальному часі видно, що ціна відійшла
  на 0.15 %) і вона не залежить від темпу подій: у швидкому ринку
  початок вкладається у 2 події, у повільному — у десятки. Модуль,
  а не знак, тому напрямок ноги в саму межу не закладено. Ноги, де
  межа береться першою ж подією, лишаються в замірі з початком у дві
  події — інакше з вибірки випадали б саме ноги з різким стартом.

Обидва заміри спираються на **готовий півот**: нога починається після
нього, а сам він на зігзагу 2.3 % підтверджується лише за 2.3 % руху.
Числа етапу 2 — це «що видно з початку ноги, коли ми знаємо, що нога
почалась», а не сигнал у реальному часі.

## Етап 3: ріст проти падіння

Ті самі перші 39 подій після півота, але ноги росту й ноги падіння
розібрані нарізно. Чотири заміри:

| # | Замір | Як саме |
| - | ----- | ------- |
| 1 | **Сам початок** | кожна з 31 ознаки: медіана й квартилі на ногах росту проти ніг падіння, критерій Манна-Вітні і **дельта Кліффа** — ранговий розмір ефекту (+1 — ознака на кожній нозі росту більша за будь-яку ногу падіння, 0 — ряди перемішані) |
| 2 | **Хід усередині початку** | середній рух події на кожній із 39 позицій, приведений до напрямку ноги, ріст і падіння окремо |
| 3 | **Звʼязки** | Спірмен кожної ознаки з кожною ціллю решти ноги, окремо в кожному напрямку, на `train`; поріг — поправка Бенʼяміні-Хохберга на всі 406 перевірок разом (рівень 0.05); кожна знахідка перевіряється на `val` — витримала, якщо знак той самий і сила не менша за 0.15 |
| 4 | **Модель нарізно** | бустинг тільки на ногах цього напрямку проти бустинга на всіх ногах, обидва на тому самому `val` |

Поправка обовʼязкова: 31 ознака × 7 цілей × 2 напрямки = 406 перевірок,
з них десяток «значущих» знайшовся б і на шумі.

## Етап 4: хвіст ноги і початок наступної

Питання зворотне до етапу 2: не «що буде далі в цій нозі», а **«що буде
на початку наступної»**. Читаються останні 39 подій ноги A, питається,
яким вийде початок ноги B — перші 39 подій одразу за півотом.

Напрямок ноги B тут не питається: на зігзагу ноги чергуються, і він
відомий наперед.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Пара ніг** | сусідні ноги A → B; пара береться, тільки якщо **обидві** без дір довших за годину і в кожній не менше 39 подій |
| 2 | **Ознаки** | ті самі 31 з `leg_start.py`, але на **останніх** 39 подіях ноги A |
| 3 | **Цілі** | `head_move` — рух перших 39 подій ноги B за її напрямком; `head_std` — розкид цих подій; `head_path` — пройдений шлях; `head_max` — найбільша подія, \|ln\|; `head_speed` — ln подій, поки ціна не відійде від півота на 0.15 %; `head_share` — частка подій, що йдуть за ногою; `next_events` — ln довжини ноги B |
| 4 | **Розбиття** | пара йде у `val`, якщо нога B починається від 2026-08-14 |
| 5 | **Модель** | той самий бустинг проти медіани `train` |
| 6 | **Перенос** | те саме число, взяте з хвоста ноги A **без навчання**: розкид хвоста проти розкиду початку, шлях проти шляху. Якщо модель не бʼє перенос, у звʼязку немає нічого, крім тривання волатильності |

Перенос обовʼязковий: хвіст A і початок B — сусідні події в одному ряді,
і будь-яка величина, що просто триває в часі, дасть кореляцію без жодної
причини з боку зігзага.

## Етап 5: подія краю ноги

Етапи 2–4 питали про ногу цілком. Тут питається про **окрему подію**:

1. чи відрізняється подія кінця ноги від звичайної події;
2. чи видно, що почались події нової ноги;
3. на якому етапі формування ноги це стає видно.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Ознаки події** | вікно її **попередніх 39 подій**: рух (`v_sum`, `v_mean`, `v_std`, `v_max`, `v_min`, `v_abs`, `v_last`, `up_share`, `path`, `run_up`, `draw_down`, `straight`, `v_slope`), нахил ема10, ціна і по кожній із 7 фіч класу — середнє й нахил у вікні. У ознаках немає нічого з майбутнього |
| 2 | **Мітки** | `start_window` — розворот стався **всередині вікна**: подія з перших 39 подій ноги; `end_fifth` — подія останніх **двох** десятин ноги; `end_decile` — подія останньої десятини; `end_ten` — подія з останніх 10 подій; `start_decile` — подія першої десятини; `start_ten` — подія з перших 10; `near_pivot` — подія в межах 10 подій від півота з будь-якого боку |
| 3 | **Розбиття** | подія йде у `val`, якщо її час від 2026-08-14 |
| 4 | **Модель** | бустинг (`HistGradientBoosting`, 300 дерев, 31 листок, seed 17) окремо на кожну мітку |
| 5 | **Оцінка** | AUC на `val`; точність, приріст над часткою мітки в ряді й покриття на кривій порога — верхівки 0.1, 0.5, 1, 2, 5 і 10 % оцінок |
| 6 | **Коли видно** | середня оцінка моделі по десятинах ноги і по позиції після півота |
| 7 | **Сторона краю** | окремий замір **тільки на подіях краю**: до півота вони чи після. Детектор краю може казати просто «півот поруч», бо останні події ноги A і перші події ноги B стоять поруч |

Події ніг із дірою довшою за годину в замір не йдуть.

## Етап 6: за скільки подій видно нову ногу

Ціль поставлена прямо: **узяти останні `X` подій ряду і сказати, чи
всередині них стався розворот** — тобто чи це початок нової ноги.
`X` перебирається від 5 до 100 подій.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Вікно** | останні `X` подій ряду, для кожної події ряду |
| 2 | **Ознаки вікна** | рух, розкид, шлях, підйом, просадка, прямота, нахил, частка подій угору |
| 3 | **Ознаки зламу** | де у вікні лежить вершина ходу (`peak_at`) і дно (`pit_at`) і скільки шляху пройдено **після** них (`after_peak`, `after_pit`). У вікні початку нової ноги вершина стоїть усередині, а не в кінці |
| 4 | **Контраст із попереднім вікном** | ті самі числа на попередніх `X` подіях (`was_*`), відношення шляху й розкиду (`ratio_path`, `ratio_v_std`, `ratio_v_abs`), різниця ходів (`turn`) і зміна знака ходу (`turned`) |
| 5 | **Мітка** | подія лежить у перших `X` подіях своєї ноги |
| 6 | **Оцінка** | AUC, крива порога і **затримка** — медіана того, на якій події після півота спрацьовує сигнал |

Затримка обовʼязкова в замірі: точність без неї нічого не варта. Сигнал,
що спрацьовує на 31-й події після півота, — це не той самий сигнал, що
на 5-й, навіть при однаковій точності.

## Етап 7: те саме питання на подіях класу

Етап 6 описував вікно **порахованими з ціни** числами. Тут те саме
питання — «чи стався розворот усередині останніх `X` подій» — ставиться
на **самих подіях класу**, без жодної ціни.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Клас** | `клас210х14х4` — перший клас датасету (`клас210х8` проміжний, у `data/datasets/` не лежить). Подія — `(15, 4)`. Для спільного ряду з етапом 6 той самий замір робиться й на `клас210х10х7` |
| 2 | **Квантування** | сирих чисел забагато: вікно на 100 подій дало б `100 × 15 × 4 = 6000` колонок. Тому блоки події згортаються в одне число на фічу, вікно ділиться на **8 рівних частин за подіями**, і на кожну береться середнє й розкид кожної фічі |
| 3 | **Розмір входу** | `8 × фіч × 2` колонок — 64 на `клас210х14х4`, 112 на `клас210х10х7`. Він **не залежить** від довжини вікна, тому X = 39 і X = 100 порівнюються прямо |
| 4 | **Мітка й розбиття** | ті самі, що на етапі 6 |
| 5 | **Усі класи** | той самий замір робиться на **кожному класі, що є в усіх шести монет** — їх 13. Клас міряється на своїй сітці подій, тому частки міток різні і порівнюється лише AUC |
| 6 | **Фільтр дір** | два режими. `сума` — як на етапах 1–6. `найбільший` — для розріджених класів: `клас210х14х4` вимагає 210 с суцільної історії, тому в його ряді 34 466 подій проти 70 647 у `клас210х10х7`, і **сума** дрібних розривів на будь-якій нозі перевищує годину. Там нога відкидається за найбільшим одним розривом |

## Етап 8: прогноз середини й кінця ноги

Етапи 2–7 дивились на ногу зсередини. Тут питання інше: чи можна сказати
наперед, **якими будуть події середини ноги** (десятини 4–7) і **якими
будуть події її кінця** (десятина 10) — з попередньої ноги, з позаминулої
або з власного початку ноги.

| # | Крок | Як саме |
| - | ---- | ------- |
| 1 | **Цілі** | параметри **подій** відрізка, а не самої ціни: середній модуль руху події, розкид рухів, пройдений шлях, напрямлений хід, кількість подій, частка подій у бік ноги. Шість цілей × два відрізки |
| 2 | **Що видно моделі** | чотири набори: `попередня нога` (вся нога, її остання десятина і її перші 39 подій), `попередня + позаминула`, `власний початок` — перші 39 подій цієї ноги, `початок + попередня` |
| 3 | **Захист від підглядання** | ноги коротші за **130 подій** у замір не йдуть: 39 / 130 = 0.30, тобто початок ноги гарантовано лежить у перших трьох десятинах і не залазить у середину, яку прогнозує |
| 4 | **Базові рівні** | `медіана` — train-медіана цілі, модель без жодного входу; `перенос` — те саме число з попередньої ноги, без навчання. Виграш = `1 − помилка / медіана`, помилка медіанна |
| 5 | **Два ділення** | **за датою** — train до 14.08, val після (58 ніг, чесний час); **відкладена монета** — навчання на пʼятьох монетах, відповідь на шостій (382 ноги, час перемішаний) |
| 6 | **Модель** | `HistGradientBoostingRegressor`, 300 дерев, 7 листків, `min_samples_leaf` 20, seed 17 — ніг мало, тому дерево дрібне |

## Дані

| | |
| --- | --- |
| Вхід | `data/datasets/<PAIR>/class210x10x7/{train,val}.npz` |
| Монет | 6 |
| Ніг у замірі | **554** (відкинуто з дірами — 158) |
| Подій | 309 021 |
| Довжина ноги | медіана 392 подій, квартилі 212 … 777, від 11 до 3099 |

## План роботи

| # | Етап | Статус |
| - | ---- | ------ |
| 1 | Профіль ноги по десятинах на ціні події: краї проти середини, розріз за напрямком, довжиною і монетою; довжина ноги в подіях і її звʼязок із рухом; вкладка `/edges` | підтверджено, 2026-09-09 |
| 2 | Початок ноги: напрямок ноги, події її завершення і діапазон зустрічних рухів — з перших 10 % ноги, з перших 39 подій після півота і з руху 0.15 / 0.30 / 0.50 % від півота; розділ вкладки `/edges` | підтверджено, 2026-09-09 |
| 3 | Ріст проти падіння на тому самому початку: ознаки початку і дельта Кліффа, хід усередині початку, звʼязки з рештою ноги з поправкою Бенʼяміні-Хохберга і перевіркою на val, модель нарізно проти спільної; розділ вкладки `/edges` | підтверджено, 2026-09-09 |
| 4 | Хвіст ноги A → початок ноги B: рух, розкид, шлях, найбільша подія, швидкість старту, частка подій і довжина наступної ноги — модель проти простого переносу числа через півот; розділ вкладки `/edges` | підтверджено, 2026-09-09 |
| 5 | Подія краю ноги проти звичайної події: детектор кінця ноги і детектор початку нової на причинному вікні, коли саме вони стають видні, і чи відрізняється край до півота від краю після; розділ вкладки `/edges` | підтверджено, 2026-09-09 |
| 6 | За скільки подій видно, що почалась нова нога: вікно від 5 до 100 подій проти попереднього такого самого, точність на кривій порога і затримка сигналу після півота; розділ вкладки `/edges` | підтверджено, 2026-09-09 |
| 7 | Те саме питання на подіях класу: дві моделі (39 і 100 подій) на кожному з 13 класів, що є в усіх монет, вікно ділиться на 8 частин, вхід не залежить від довжини вікна; видачі класів на спільній шкалі ряду val із вибором, які показувати | підтверджено, 2026-09-09 |
| 8 | Прогноз середини й кінця ноги: шість параметрів подій кожного відрізка з попередньої ноги, з позаминулої і з власного початку — проти медіани й простого переносу числа через півот, двома діленнями; розділ вкладки `/edges` | підтверджено, 2026-09-09 |

## Скрипти

| Скрипт | Що робить | Вихід |
| ------ | --------- | ----- |
| [`scripts/edge_profile.py`](scripts/edge_profile.py) | профіль ноги по десятинах, краї проти середини, довжина ноги | `edge_profile.json` |
| [`scripts/leg_start.py`](scripts/leg_start.py) | що видно з початку ноги: напрямок, події завершення, зустрічний рух | `leg_start.json` |
| [`scripts/head_by_kind.py`](scripts/head_by_kind.py) | той самий початок нарізно: ноги росту проти ніг падіння | `head_by_kind.json` |
| [`scripts/next_head.py`](scripts/next_head.py) | хвіст ноги A проти початку ноги B, модель і перенос | `next_head.json` |
| [`scripts/event_edges.py`](scripts/event_edges.py) | подія краю ноги проти звичайної події, причинне вікно | `event_edges.json` |
| [`scripts/new_leg.py`](scripts/new_leg.py) | за скільки подій видно нову ногу: вікно X проти попереднього вікна | `new_leg.json` |
| [`scripts/class_new_leg.py`](scripts/class_new_leg.py) | те саме питання на подіях класу, вікно у 8 частинах | `class_new_leg.json` |
| [`scripts/new_leg_series.py`](scripts/new_leg_series.py) | чотири видачі рядом на val, пороги з train | `new_leg_series_<PAIR>.json` |
| [`scripts/leg_ahead.py`](scripts/leg_ahead.py) | прогноз середини й кінця ноги з попередніх ніг і з власного початку | `leg_ahead.json` |

```bash
python3 research/28-leg-edge-profile/scripts/leg_start.py             # усі способи взяти початок
python3 research/28-leg-edge-profile/scripts/leg_start.py --head 100  # інше число подій
python3 research/28-leg-edge-profile/scripts/leg_start.py --move 0.01 # інша межа за рухом ціни
python3 research/28-leg-edge-profile/scripts/head_by_kind.py          # ріст проти падіння
python3 research/28-leg-edge-profile/scripts/next_head.py             # хвіст A → початок B
python3 research/28-leg-edge-profile/scripts/event_edges.py           # подія краю ноги
python3 research/28-leg-edge-profile/scripts/new_leg.py               # за скільки подій видно нову ногу
python3 research/28-leg-edge-profile/scripts/new_leg.py --window 15   # своя довжина вікна
python3 research/28-leg-edge-profile/scripts/class_new_leg.py         # перший клас, вікна 5…100
python3 research/28-leg-edge-profile/scripts/class_new_leg.py \
    --class class210x10x7 --holes sum --window 39 --window 100        # той самий ряд, що в етапі 6
python3 research/28-leg-edge-profile/scripts/new_leg_series.py       # чотири видачі рядом на val
python3 research/28-leg-edge-profile/scripts/leg_ahead.py            # прогноз середини й кінця ноги
python3 research/28-leg-edge-profile/scripts/leg_ahead.py --head 60  # довший початок ноги
```

## Результат етапу 1

### Профіль по десятинах, ціна події

| Спосіб | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| ------ | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| пулом | +0.193 | +0.085 | +0.076 | +0.071 | +0.058 | +0.063 | +0.070 | +0.053 | +0.132 | +0.198 |
| по нозі | +0.225 | +0.089 | +0.077 | +0.062 | +0.061 | +0.067 | +0.065 | +0.055 | +0.145 | +0.153 |

- Краї (десятини 1 і 10) тримають **0.391** руху, середина
  (десятини 4–7) — 0.262.
- Одна десятина краю сильніша за одну десятину середини
  **в 2.98 раза**.
- Форма та сама обома способами зведення, тому це не ефект довгих ніг.

### Ноги вгору і вниз

| Нога | Ніг | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| ---- | --: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| вгору | 283 | +0.154 | +0.093 | +0.070 | +0.046 | +0.067 | +0.068 | +0.082 | +0.058 | +0.151 | +0.211 |
| вниз | 271 | +0.238 | +0.076 | +0.083 | +0.099 | +0.049 | +0.057 | +0.057 | +0.048 | +0.112 | +0.183 |

Нога вниз кладе більше руху в **перший** край (0.238 проти
0.154), нога вгору — в **останній** (0.211 проти
0.183). Падіння починається різко, зростання дотискається
в кінці.

### За довжиною ноги

| Подій у нозі | Ніг | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Краї |
| ------------ | --: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
| 11…212 | 138 | +0.229 | +0.090 | +0.088 | +0.048 | +0.080 | +0.116 | +0.094 | +0.078 | +0.169 | +0.007 | 0.237 |
| 212…392 | 139 | +0.178 | +0.121 | +0.095 | +0.074 | +0.060 | +0.033 | +0.051 | +0.045 | +0.138 | +0.205 | 0.383 |
| 392…777 | 138 | +0.202 | +0.092 | +0.073 | +0.075 | +0.058 | +0.052 | +0.067 | +0.031 | +0.120 | +0.230 | 0.432 |
| 777…3099 | 139 | +0.177 | +0.053 | +0.060 | +0.077 | +0.047 | +0.064 | +0.072 | +0.063 | +0.120 | +0.267 | 0.443 |

**Краєвий ефект росте з довжиною ноги:** 0.237 у найкоротших ніг
(11…212 подій) проти 0.443 у найдовших (777…3099).
У найкоротших ніг остання десятина взагалі порожня (+0.007): вони
доходять до півота, вже витративши рух, і кінець ноги в них не додає
нічого.

### Кількість подій

| | |
| --- | --- |
| Медіана | **392** подій (22.9 год) |
| Квартилі | 212 … 777 |
| Найкоротша / найдовша | 11 / 3099 |
| Кореляція довжини з рухом ноги | **+0.460** |

Довжина ноги розкидана більш ніж у 200 разів, і з величиною руху вона
повʼязана лише наполовину: нога на 3099 подій і нога на 11 подій обидві
закривають свої 2.3 %.

### По монетах

| Монета | Ніг | Медіана подій | Краї | Середина | Край / середина |
| ------ | --: | ------------: | ---: | -------: | --------------: |
| `BTC_USDT` | 70 | 562 | 0.401 | 0.254 | 3.15 |
| `ETH_USDT` | 103 | 432 | 0.376 | 0.285 | 2.65 |
| `SOL_USDT` | 109 | 360 | 0.406 | 0.258 | 3.15 |
| `XRP_USDT` | 103 | 351 | 0.357 | 0.266 | 2.68 |
| `BNB_USDT` | 64 | 464 | 0.397 | 0.251 | 3.16 |
| `DOGE_USDT` | 105 | 358 | 0.408 | 0.253 | 3.23 |

Краї тримають 0.357 … 0.408 руху на кожній монеті — розкид менший
за 0.06 при однаковій формі профілю.

## Результат етапу 2

Ноги: `перші 10 %` — 554 (train 455 · val 99), `перші 39 подій` — 541
(train 449 · val 92). Медіана початку в обох — 39 подій.

### Напрямок ноги

| Початок | Точність на val | База | AUC | Правило «знак руху початку» |
| ------- | --------------: | ---: | --: | --------------------------: |
| перші 10 % ноги | **0.939** | 0.510 | 0.997 | 0.960 |
| перші 39 подій | **0.978** | 0.506 | 0.998 | 0.946 |

Напрямок ноги береться з її початку майже даром: **знак руху перших
39 подій уже дає 0.946**, модель на 31 ознаці — 0.978. Це не прогноз
розвороту: нога починається після півота, тобто ціна вже пішла в її бік,
і перша десятина тримає 19 % руху ноги (етап 1). Питання «куди піде
нога» закривається, щойно відомо, що нога почалась.

### Події завершення ноги

Кореляція Спірмена на val і виграш медіанної похибки проти базового рівня:

| Ціль | перші 10 % ноги | перші 39 подій |
| ---- | --------------: | -------------: |
| `events_left` — подій до кінця ноги | +0.995 · +96.7 % | **+0.436 · +3.8 %** |
| `last_share` — рух останньої десятини | +0.649 · +30.9 % | **+0.261 · −4.0 %** |
| `last_event` — подія останньої десятини | +0.273 · −14.8 % | **+0.198 · +5.9 %** |

Ліва колонка — це вимір, а не прогноз: розмір початку в 10 % ноги сам
каже її довжину. Чесна колонка — права, і в ній **подій завершення з
початку ноги не видно**: скільки ще подій до кінця — Спірмен +0.44 при
виграші 4 % над медіаною, який рух принесе остання десятина — не краще
за медіану взагалі.

Самі ці числа на val (`перші 39 подій`):

| Ціль | квартилі | медіана | 90-й процентиль | край |
| ---- | -------- | ------: | --------------: | ---: |
| подій до кінця ноги | 101 … 546 | **310** | 812 | 3070 |
| частка руху в останній десятині | 0.043 … 0.322 | **0.161** | 0.450 | 0.815 |
| подія останньої десятини, за ногою | 0.01 … 0.03 % | **0.02 %** | 0.06 % | 0.16 % |

### Зустрічний рух

| Ціль | перші 10 % ноги | перші 39 подій |
| ---- | --------------: | -------------: |
| `against_share` — частка зустрічних подій | +0.319 · +12.3 % | **+0.213 · −21.3 %** |
| `against_p90` — зустрічна подія, 90-й процентиль | +0.799 · +41.4 % | **+0.602 · +22.1 %** |
| `against_max` — найбільша зустрічна подія | +0.125 · −2.2 % | **−0.033 · −15.9 %** |
| `against_sum` — сума зустрічного руху | +0.610 · +43.2 % | **+0.380 · +15.6 %** |

Діапазон зустрічних рухів на val (`перші 39 подій`), у відсотках ціни:

| Величина | квартилі | медіана | 90-й процентиль | край |
| -------- | -------- | ------: | --------------: | ---: |
| частка подій проти ноги | 0.443 … 0.485 | **0.467** | 0.500 | 0.533 |
| зустрічна подія, 90-й процентиль | 0.18 … 0.38 % | **0.26 %** | 0.53 % | 1.92 % |
| найбільша зустрічна подія | 0.46 … 0.87 % | **0.63 %** | 1.49 % | 8.25 % |
| сума зустрічного руху до руху ноги | 1.90 … 5.26 | **3.66** | 7.40 | 22.61 |

Три висновки:

- **Майже половина подій ноги йде проти неї** — 0.467 при квартилях
  0.443 … 0.485, і ця частка однакова на всіх ногах. З початку ноги вона
  не читається (виграш відʼємний), бо читати нічого: вона стала.
- **Сумарний зустрічний рух у 3.7 раза більший за сам рух ноги**
  (медіана 3.66): нога 2.3 % набирається з рухів, які в сумі дають
  ~8.4 % проти неї.
- **Розмах зустрічної події з початку ноги видно** — `against_p90`
  тримає Спірмен +0.60 і виграш 22 % над медіаною на чесному замірі.
  Волатильність початку ноги переходить у решту ноги. А от **найбільшу**
  зустрічну подію не видно взагалі (−0.03): хвіст приходить ззовні.

### Спосіб узяти початок

Той самий замір, чотири чесні межі початку (`без довжини ноги`, val — 92
… 99 ніг):

| Початок | Медіана подій | Напрямок | `events_left` | `last_share` | `against_p90` |
| ------- | ------------: | -------: | ------------: | -----------: | ------------: |
| перші 39 подій | 39 | 0.978 | +0.400 | +0.275 | +0.606 |
| рух 0.15 % | **2** | 0.970 | **+0.437** | **+0.335** | +0.478 |
| рух 0.30 % | 6 | 0.960 | +0.323 | +0.308 | +0.569 |
| рух 0.50 % | 11 | 0.939 | +0.294 | +0.250 | +0.463 |

Межа у відсотках ціни працює не гірше за 39 подій, а на **двох** подіях
дає найкращу оцінку довжини ноги (+0.437 проти +0.400): важить не
скільки подій прочитано, а **як швидко** ціна пройшла свої 0.15 % — саме
це число і є ознакою `n` у такому початку. Напрямок при цьому падає з
0.978 до 0.970 … 0.939: чим ближче межа до півота, тим менше руху
прочитано, і знак його менш надійний. Розмах зустрічної події
(`against_p90`) навпаки любить довший початок — його дає розкид подій,
а на двох подіях розкиду ще немає.

### Що з цього виходить

З початку ноги видно **напрямок** (0.978) і **типовий розмах зустрічної
події** (+0.60), і не видно **ні коли нога скінчиться** (+0.44 при
виграші 4 %), **ні чим саме вона скінчиться** (−0.04 … +0.06), **ні
найбільшої зустрічної події** (−0.03). Довжина ноги і її завершення
з початку не читаються — це те саме, що етап 1 показав кореляцією
довжини з рухом (+0.460).

## Результат етапу 3

Ноги росту — 275 (val 48), ноги падіння — 266 (val 44), початок — перші
39 подій після півота.

### Чим початок росту відрізняється від початку падіння

Дванадцять ознак із найбільшою дельтою Кліффа:

| Ознака початку | Ріст, медіана | Падіння, медіана | Дельта Кліффа | p |
| -------------- | ------------: | ---------------: | ------------: | -: |
| `straight` — сума руху до пройденого шляху | +0.217 | −0.216 | **+0.990** | 3e−88 |
| `draw_down` — найгірша просадка початку | −0.0003 | −0.0119 | +0.985 | 2e−87 |
| `v_mean` — середня подія | +0.00020 | −0.00022 | +0.981 | 9e−87 |
| `v_sum` — рух початку | +0.0077 | −0.0084 | +0.981 | 9e−87 |
| `run_up` — найкращий підйом початку | +0.0103 | +0.0001 | +0.976 | 6e−86 |
| `ema_slope` — нахил ема10 | +0.0185 | −0.0248 | +0.964 | 7e−84 |
| `price_avg_slope` — нахил середньої ціни блоків | +0.0129 | −0.0116 | +0.829 | 2e−62 |
| `up_share` — частка подій угору | 0.538 | 0.436 | +0.792 | 1e−57 |
| `v_min` — найгірша подія | −0.0025 | −0.0040 | +0.414 | 8e−17 |
| `bal_support_mean` — баланс опори знизу | 89.3 | 56.1 | +0.274 | 4e−05 |
| `v_max` — найкраща подія | +0.0035 | +0.0028 | +0.223 | 7e−06 |
| `vol_sell_slope` — нахил обʼєму продажів | −0.0005 | −0.0265 | +0.215 | 2e−05 |

Перші вісім ознак — це **той самий напрямок, сказаний різними словами**:
знак руху, нахил, просадка, частка подій угору. Дельта біля +0.98 — це
не знахідка, а перевірка того, що замір робить те, що має.

Цікаве починається нижче, там, де дельта менша за 0.5 — там ознака
**не** дзеркальна:

- **Початок падіння різкіший.** `v_min` на падінні −0.40 % проти −0.25 %
  на рості, а `v_max` більший на рості (+0.35 % проти +0.28 %). Але
  `up_share` на рості 0.538, а на падінні 0.436 — тобто подій **вниз**
  на падінні 0.564, більше, ніж подій угору на рості. Падіння йде
  частішими й більшими подіями; зростання — рідшими й дрібнішими.
- **Обʼєм продажів на початку падіння падає**
  (`vol_sell_slope` −0.0265 проти −0.0005): продажі на старті падіння
  йдуть згори і згасають, а не наростають.
- **Опора знизу на початку росту сильніша** (`bal_support_mean` 89 проти
  56) — єдина ознака рівнів класу, що розрізняє напрямки.

### Хід усередині початку

Середній рух події, приведений до напрямку ноги, перші 8 позицій, %:

| Нога | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Сума за 39 подій |
| ---- | -: | -: | -: | -: | -: | -: | -: | -: | ---------------: |
| ріст | +0.096 | +0.063 | +0.043 | +0.038 | +0.040 | +0.032 | +0.023 | −0.004 | **+0.95 %** |
| падіння | +0.099 | +0.100 | +0.041 | +0.081 | +0.049 | +0.031 | +0.044 | +0.050 | **+1.07 %** |

Перша подія в обох однакова (+0.096 і +0.099), а далі ноги розходяться:
**зростання видихається після першої події**, падіння тримає темп до
восьмої. За 39 подій падіння проходить 1.07 % своєї ноги проти 0.95 %
у росту, і до кінця початку рух росту вже гуляє біля нуля
(−0.008 … +0.030 на останніх позиціях), а падіння тримає рівні
+0.008 … +0.009.

### Звʼязки з рештою ноги

406 перевірок, поріг Бенʼяміні-Хохберга — 1.11e−02. Витримали `val`:
**45 звʼязків на ногах росту** і **37 на ногах падіння**, спільних — 30.

Найсильніші, обидва напрямки:

| Ознака початку | Ціль | Ріст: train / val | Падіння: train / val |
| -------------- | ---- | ----------------: | -------------------: |
| `v_std` — розкид подій | `against_p90` | +0.491 / +0.812 | +0.410 / +0.666 |
| `path` — пройдений шлях | `against_p90` | +0.490 / +0.819 | +0.403 / +0.676 |
| `v_min` — найгірша подія | `against_p90` | −0.452 / −0.720 | −0.383 / −0.525 |
| `v_std` | `events_left` | −0.429 / −0.750 | — |

Спільна частина одна: **розкид подій початку задає розкид зустрічних
подій решти ноги** — волатильність тримається. І чим більший розкид,
тим **коротша** нога в подіях (`events_left` −0.43): бурхлива нога
доходить до своїх 2.3 % швидше.

Що є **тільки на ногах росту** (15 звʼязків):

| Ознака | Ціль | train | val |
| ------ | ---- | ----: | --: |
| `run_up` — найкращий підйом початку | `events_left` | −0.416 | −0.610 |
| `run_up` | `last_share` | −0.365 | −0.505 |
| `run_up` | `against_sum` | −0.360 | −0.452 |
| `bal_support_mean` | `against_max` | −0.323 | −0.548 |
| `bal_support_mean` | `against_p90` | −0.244 | −0.829 |
| `support_slope` | `against_p90` | −0.263 | −0.300 |

**Нога росту цілком описується своїм найкращим підйомом на старті.**
Чим сильніший `run_up`, тим коротша нога, тим менше руху лишається на
останню десятину і тим менший зустрічний рух. І тільки на ногах росту
працюють **рівні опори**: сильніша опора знизу на старті — менший
розмах зустрічних подій далі.

Що є **тільки на ногах падіння** (7 звʼязків):

| Ознака | Ціль | train | val |
| ------ | ---- | ----: | --: |
| `draw_down` — найгірша просадка початку | `against_p90` | −0.343 | −0.542 |
| `draw_down` | `events_left` | +0.187 | +0.463 |
| `draw_down` | `last_share` | +0.236 | +0.349 |
| `ema_slope` | `against_share` | −0.306 | −0.209 |
| `vol_sell_mean` | `last_share` | −0.173 | −0.285 |
| `vol_buy_mean` | `last_share` | −0.172 | −0.290 |

Дзеркально: **ногу падіння описує її просадка на старті** — та сама
величина в іншому знаку. І тільки тут працюють **обʼєми**: більший обʼєм
на старті падіння — менша частка руху в останній десятині.

Ознаки класу серед витриманих: на рості — `bal_support_mean`,
`support_slope`, `resist_slope`, `price_avg_mean`, `vol_buy_mean`,
`vol_sell_mean`; на падінні — тільки `price_avg_mean`, `vol_buy_mean`,
`vol_sell_mean`. **Рівні класу дають щось лише на ногах росту**, обʼєми
працюють в обох напрямках.

### Чи варто вчити напрямки нарізно

Спірмен на `val`, модель тільки на ногах одного напрямку проти моделі на
всіх ногах:

| Ціль | Ріст: нарізно / разом | Падіння: нарізно / разом |
| ---- | --------------------: | -----------------------: |
| `events_left` | +0.335 / **+0.411** | +0.228 / **+0.289** |
| `last_share` | **+0.431** / +0.292 | **+0.204** / +0.095 |
| `against_p90` | +0.634 / **+0.658** | +0.386 / **+0.524** |
| `against_sum` | +0.266 / **+0.330** | +0.264 / **+0.396** |

Розділення виграє **тільки на `last_share`** — на частці руху в останній
десятині, і на обох напрямках (+0.431 проти +0.292 і +0.204 проти
+0.095). На решті цілей більша вибірка важить більше за однорідність:
модель на всіх 449 ногах бʼє модель на 227. Тобто напрямки треба
розділяти в **ознаках** (`run_up` проти `draw_down`), а не в **навчанні**.

### Що з цього виходить

- Початки росту й падіння **дзеркальні за формою** (дельта Кліффа +0.98
  на всіх ознаках руху) і **різні за темпом**: падіння йде частішими й
  більшими подіями і тримає темп вісім подій, зростання видихається
  після першої.
- Обидва напрямки мають один спільний робочий звʼязок: **розкид подій
  початку → розкид зустрічних подій ноги** (+0.41 … +0.49 на train,
  +0.67 … +0.82 на val).
- Далі вони розходяться: ногу росту веде **`run_up`** і **рівні опори**,
  ногу падіння — **`draw_down`** і **обʼєми**.
- Вчити нарізно варто лише частку руху в останній десятині; решту —
  разом.

## Результат етапу 4

486 пар ніг (train 404 · val 82), хвіст і початок по 39 подій.

| Що питається про початок ноги B | Модель | Виграш | Перенос | Спірмен | Краще |
| ------------------------------- | -----: | -----: | ------- | ------: | ----- |
| `head_path` — пройдений шлях | +0.770 | +41.0 % | `path` | **+0.856** | перенос |
| `head_std` — розкид подій | +0.686 | +32.5 % | `v_std` | **+0.802** | перенос |
| `head_max` — найбільша подія | +0.552 | +7.0 % | `v_max` | **+0.588** | перенос |
| `head_speed` — подій на 0.15 % | +0.323 | +35.1 % | `v_abs` | **−0.546** | перенос |
| `head_move` — рух початку | +0.299 | −37.1 % | `v_sum` | +0.150 | модель |
| `next_events` — довжина ноги B | +0.174 | −10.7 % | `seconds` | +0.053 | модель |
| `head_share` — частка подій за ногою | −0.019 | +3.6 % | `up_share` | −0.084 | — |

Розкид цілей на val:

| Ціль | квартилі | медіана |
| ---- | -------- | ------: |
| `head_move` | 0.54 … 1.72 % | **0.90 %** |
| `head_std` | 0.10 … 0.27 % | **0.16 %** |
| `head_path` | 3.16 … 7.35 % | **5.28 %** |
| `head_max` | 0.29 … 0.77 % | **0.48 %** |
| `head_speed` | 1 … 3 події | **2 події** |
| `head_share` | 0.513 … 0.615 | **0.564** |
| `next_events` | 129 … 594 подій | **377 подій** |

### Що з цього виходить

- **Масштаб початку наступної ноги видно, але це не заслуга зігзага.**
  Розкид, шлях і найбільша подія читаються з хвоста попередньої ноги
  (+0.55 … +0.77), проте **простий перенос одного числа через півот бʼє
  модель на кожній із цих цілей** (+0.59 … +0.86). Волатильність просто
  триває через півот: подія за подією ринок лишається таким самим, і те,
  що між ними стоїть розворот, нічого не додає.
- **Швидкість старту теж переноситься**: чим більший середній розмах
  події в хвості A, тим менше подій треба, щоб ціна відійшла від півота
  на 0.15 % (перенос −0.546 проти +0.323 у моделі).
- **Сам рух початку ноги B у відсотках з хвоста A не читається**:
  Спірмен +0.299 при похибці на 37 % **гіршій** за медіану. Тобто чи
  буде старт різким, ми знаємо, а на скільки саме відсотків він
  зрушить — ні.
- **Довжина наступної ноги — ні** (+0.174, похибка гірша за медіану на
  11 %). Це те саме, що етап 2 показав із середини ноги: довжина ноги в
  подіях не читається нізвідки.
- **Частка подій за ногою — ні** (−0.019): вона стала, як і `against_share`
  на етапі 2.

Разом: з хвоста попередньої ноги видно **тільки те, що вже видно з
ринку** — рівень волатильності, і він переноситься через півот сам, без
моделі. Нічого про **розмір** і **тривалість** наступної ноги хвіст
попередньої не каже.

## Результат етапу 5

309 017 подій (train 261 144 · val 47 873), вікно — 39 попередніх подій.

| Мітка події | Частка в ряді | AUC | Точність згори 5 % | Приріст |
| ----------- | ------------: | --: | -----------------: | ------: |
| `end_ten` — останні 10 подій ноги | 0.022 | **0.769** | 0.102 | 4.74× |
| `start_ten` — перші 10 подій ноги | 0.021 | **0.812** | 0.120 | 5.82× |
| `near_pivot` — ±10 подій від півота | 0.042 | 0.748 | 0.153 | 3.65× |
| `end_decile` — остання десятина | 0.106 | 0.639 | 0.301 | 2.82× |
| `start_window` — розворот усередині вікна з 39 подій | 0.079 | 0.769 | 0.356 | 4.49× |
| `end_fifth` — останні 20 % ноги | 0.212 | **0.567** | 0.443 | 2.09× |
| `start_decile` — перша десятина | 0.097 | **0.523** | 0.145 | 1.49× |

Чим ширша мітка краю, тим гірше вона відрізняється: 0.769 на десяти
подіях, 0.639 на десятині, 0.567 на пʼятій частині ноги. **Край ноги —
це десяток подій, а не її частка.**

### 1. Подія кінця ноги проти звичайної

Відрізняється, але слабко: AUC 0.769 на мітці «останні 10 подій».
На верхніх 5 % оцінок справжніх подій кінця 10.2 % проти 2.2 % у ряді —
приріст у 4.7 раза. Тобто **дев'ять сигналів із десяти хибні**.

Ширша мітка — «остання десятина» — дає AUC 0.639: чим більше подій
вважати кінцем, тим менше вони відрізняються від решти ноги. Кінець
ноги — це не десятина, а буквально останні події.

### 2. Подія початку нової ноги

Видно краще, ніж кінець: AUC 0.812, приріст 5.8×. Причина проста —
у вікні вже лежить сам розворот: ціна щойно змінила напрямок, і це
видно з форми вікна, тоді як перед розворотом у вікні лише рівний хід.

Ширша мітка «перша десятина» дає AUC **0.523** — тобто майже нічого:
через десяток подій після півота вікно вже нічим не відрізняється від
середини ноги.

### Крива порога

«Півот стався за останні 10 подій» — це мітка `start_ten`. Скільки
коштує кожен рівень упевненості (val — 47 873 події, з них 2.1 % справді
такі):

| Верхівка оцінок | Подій | Точність | Приріст | Покриття |
| --------------- | ----: | -------: | ------: | -------: |
| 0.1 % | 48 | **0.354** | 17.1× | 0.017 |
| 0.5 % | 240 | 0.229 | 11.1× | 0.056 |
| 1 % | 479 | 0.203 | 9.8× | 0.098 |
| 2 % | 958 | 0.159 | 7.7× | 0.154 |
| 5 % | 2 394 | 0.120 | 5.8× | 0.291 |
| 10 % | 4 788 | 0.094 | 4.6× | 0.457 |

Найчистіший сигнал — 35 % влучань, і це 48 подій із 48 тисяч: дві
третини таких сигналів однаково хибні, а ловлять вони 1.7 % усіх
розворотів. Те саме на `near_pivot` (±10 подій): 0.417 на верхівці
0.1 %, 0.153 на 5 %.

**Половини влучань не дає жоден поріг.**

### 3. На якому етапі це видно

Середня оцінка моделі `end_ten` по десятинах ноги:

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| -: | -: | -: | -: | -: | -: | -: | -: | -: | -: |
| 0.018 | 0.019 | 0.017 | 0.013 | 0.018 | 0.017 | 0.022 | 0.024 | 0.028 | **0.042** |

До сьомої десятини оцінка стоїть на місці; росте з восьмої й подвоюється
на останній.

Але **зсув середньої оцінки ще не означає, що подію можна назвати**.
Питання «чи почались останні 20 % ноги» поставлене прямо, окремою
міткою `end_fifth`, і відповідь на нього — **ні**: AUC 0.567 при
частці 0.212 у ряді, тобто трохи краще за монетку. На верхніх 5 %
оцінок такі події складають 44 % проти 21 % у ряді — приріст лише
удвічі. Пулом по сотнях ніг остання частина відрізняється, в окремій
події — майже ні.

Середня оцінка моделі `start_ten` по позиції після півота:

| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| -: | -: | -: | -: | -: | -: | -: | -: | -: | -: |
| 0.070 | 0.075 | 0.087 | 0.093 | 0.089 | **0.096** | 0.096 | 0.094 | 0.093 | 0.084 |

Найвпевненіше — **на 3–7 події після півота** (10–25 хвилин). На першій
події оцінка ще низька: розворот тільки почав входити у вікно. Після
десятої вона згасає.

### 4. Кінець чи початок

Детектор краю може казати просто «півот поруч». Перевірка: **тільки на
подіях краю** (2 002 події `val`) питається, до півота вони чи після.

| | |
| --- | --- |
| AUC | **0.877** |
| Точність | **0.793** (база 0.490) |

Сторона визначається добре: у вікні події **після** півота лежить
перелом ходу, у вікні події **до** півота — рівний хід. Тобто ланцюжок
працює так: спершу «півот поруч» (слабко, 1 з 10), потім «з якого боку»
(упевнено, 4 з 5).

Скільки подій для цього треба — точність сторони за відстанню від
півота (по 98 … 103 події `val` у кожній клітинці):

| Подій від півота | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| ---------------- | -: | -: | -: | -: | -: | -: | -: | -: | -: | -: |
| подія **після** півота | 0.657 | 0.673 | **0.776** | 0.827 | 0.837 | 0.806 | 0.816 | 0.796 | 0.806 | 0.847 |
| подія **до** півота | 0.680 | 0.882 | 0.912 | 0.843 | 0.814 | 0.824 | 0.824 | 0.775 | 0.755 | 0.716 |

**Констатація коштує 3–4 події (10–14 хвилин).** На першій-другій події
після півота модель ще плутається (0.66 … 0.67 — злам щойно ввійшов у
вікно і має вагу двох подій із 39), з третьої точність доходить 0.78,
з четвертої стає на 0.83 і далі тримається. Дзеркально по інший бік:
подію за 2–3 до півота модель бере найкраще (0.88 … 0.91) — там у вікні
ще чистий рівний хід, а ближче до півота хід уже гнеться і плутається
з тим, що по той бік.

### Що з цього виходить

- **Подія кінця ноги відрізняється від звичайної, але цього мало для
  сигналу**: AUC 0.769 і 10 % точності на верхівці оцінок.
- **Початок нової ноги видно краще за кінець** (0.812 проти 0.769) — і
  це не прогноз, а констатація: розворот уже стався і лежить у вікні.
- **Вікно видимості вузьке з обох боків**: кінець — останні 10 подій
  (десятина вже майже не читається, 0.639), початок — перші 10 подій
  (перша десятина — 0.523).
- **Коли саме**: кінець стає помітним у останніх 20 % ноги, початок —
  через 3–7 подій після півота.
- **Розрізнити кінець і початок** серед подій краю можна впевнено
  (0.877 / 0.793), а от **знайти сам край** у ряді — ні.

## Результат етапу 6

`val` — 47 873 події шести монет. Точність і затримка на верхівці 1 %
оцінок:

| X, подій | Частка в ряді | AUC | Точність | Приріст | Покриття | Затримка | Найсильніша ознака |
| -------: | ------------: | --: | -------: | ------: | -------: | -------: | ------------------ |
| 5 | 0.010 | 0.802 | 0.084 | 8.1× | 0.081 | **3** | `was_v_std` 0.750 |
| 10 | 0.021 | 0.812 | 0.115 | 5.6× | 0.056 | **5** | `path` 0.754 |
| 20 | 0.041 | 0.815 | 0.338 | 8.2× | 0.082 | **11** | `was_path` 0.761 |
| 39 | 0.079 | 0.830 | **0.628** | 7.9× | 0.079 | **21** | `was_path` 0.768 |
| 60 | 0.119 | 0.831 | **0.906** | 7.6× | 0.076 | **25** | `was_path` 0.772 |
| 100 | 0.189 | 0.830 | **0.981** | 5.2× | 0.052 | **31** | `path` 0.764 |

На найвищому порозі (верхівка 0.1 %, 48 подій із 48 тисяч) точність
доходить 0.938 при X = 39 і 1.000 при X = 60 і X = 100.

### Головне: AUC не міняється, міняється ціна питання

AUC стоїть на 0.80 … 0.83 для **всіх** довжин вікна. Задача не стає
легшою — легшою стає **мітка**: при X = 5 подія «в перших пʼяти подіях
ноги» трапляється раз на сто, при X = 100 — раз на пʼять. Тому точність
росте від 0.08 до 0.98 майже сама, і читати її треба разом із приростом
над часткою: 8.1× · 5.6× · 8.2× · 7.9× · 7.6× · 5.2× — він однаковий.

**Модель весь час робить одне й те саме — бачить злам у вікні.** Питання
лише в тому, скільки подій ми готові чекати, щоб цей злам у вікно
вмістився.

### Ціна затримки

| Хочемо | Треба вікно | Сигнал прийде | Що це значить |
| ------ | ----------- | ------------- | ------------- |
| 1 влучання з 3 | X = 20 | на 11-й події (~40 хв) | третина сигналів справжні |
| 2 влучання з 3 | X = 39 | на 21-й події (~1.2 год) | розворот уже пройшов десяту частину ноги |
| 9 влучань з 10 | X = 60 | на 25-й події (~1.5 год) | нога вже пройшла 5–10 % свого шляху |
| майже без помилок | X = 100 | на 31-й події (~1.8 год) | нога вже пройшла до чверті |

Медіанна нога — 392 події (етап 1), тому 21 подія затримки — це перші
5 % ноги, а 31 подія — 8 %. Рух у перших 10 % ноги — 19 % її розмаху
(етап 1), тобто **до моменту впевненої констатації частину краєвого
руху вже втрачено**.

### Видача рядом на val

Та сама модель (вікно 39 подій), поріг узятий **на train** — верхівка 1 %
його оцінок, 0.6883. На val він дає таке:

| Монета | Подій | Розворот у вікні | Сигналів | Влучив | Хибний | Точність |
| ------ | ----: | ---------------: | -------: | -----: | -----: | -------: |
| `BTC_USDT` | 7 986 | 351 | 38 | 6 | 32 | 0.16 |
| `ETH_USDT` | 8 895 | 468 | 26 | 9 | 17 | 0.35 |
| `SOL_USDT` | 8 791 | 624 | 35 | 1 | 34 | **0.03** |
| `XRP_USDT` | 6 925 | 1 163 | 199 | 162 | 37 | **0.81** |
| `BNB_USDT` | 6 166 | 273 | 26 | 17 | 9 | 0.65 |
| `DOGE_USDT` | 9 110 | 921 | 123 | 96 | 27 | 0.78 |

Пулом — 291 влучань із 447 сигналів, 0.65, тобто рівно те, що дала крива
порога етапу 6. **Але по монетах розкид від 0.03 до 0.81**: на `SOL_USDT`
поріг із train майже не працює, на `XRP_USDT` і `DOGE_USDT` працює добре.
Один поріг на всі монети — груба настройка; це видно тільки на ряді, у
зведених числах етапу 6 воно сховане усередненням.

Покриття скрізь мале: сигналів у рази менше, ніж подій із розворотом у
вікні (351 проти 38 на BTC) — верхівка 1 % оцінок бере лише найяскравіші
злами.

### Що каже сама модель

Найсильніша окрема ознака на всіх довжинах, крім найкоротшої, —
`was_path` і `was_v_std`, тобто **шлях і розкид попереднього вікна**,
а не поточного. Це прямо те, чого й слід чекати з етапу 1: перед
розворотом іде кінець старої ноги, а він — найбурхливіша частина ряду.
Модель упізнає нову ногу **за слідом старої**, а не за самим початком
нової.

### Що з цього виходить

- **Так, нову ногу можна виявити**, і без жодної магії: 0.63 точності
  на 39 подіях, 0.91 на 60 подіях, 0.98 на 100 — на верхівці 1 % оцінок.
- **Але це констатація із затримкою**, а не сигнал: 21, 25 і 31 подія
  після півота відповідно.
- **Скоротити вікно не виходить**: на 10 подіях точність падає до 0.115.
  Злам має вмістися у вікно, і половина вікна — це вже сама затримка.
- **Розпізнає модель кінець старої ноги, а не початок нової**: найсильніші
  ознаки — з попереднього вікна.

## Результат етапу 7

| Мова опису вікна | Клас | Колонок | X | Частка | AUC | Точність 1 % | Затримка |
| ---------------- | ---- | ------: | -: | -----: | --: | -----------: | -------: |
| ціна (етап 6) | — | 30 | 39 | 0.079 | **0.830** | 0.628 | 21 |
| ціна (етап 6) | — | 30 | 100 | 0.189 | **0.830** | 0.981 | 31 |
| клас | `клас210х10х7` | 112 | 39 | 0.079 | 0.759 | 0.484 | 24 |
| клас | `клас210х10х7` | 112 | 100 | 0.189 | 0.746 | 0.687 | 27 |
| клас | `клас210х14х4` | 64 | 39 | 0.306 | 0.719 | 0.476 | 6 |
| клас | `клас210х14х4` | 64 | 100 | 0.528 | 0.667 | 1.000 | 16 |

Читати можна лише **AUC**: частка мітки в ряді різна (у `клас210х14х4`
свій, розріджений ряд і свій набір ніг), тому точності між класами не
порівнюються.

- **Ціна бʼє клас**: 0.830 проти 0.759 на тому самому ряді, тих самих
  мітках і тому самому вікні. Дванадцять чисел про хід ціни несуть більше,
  ніж 112 колонок рівнів і обʼємів.
- **Перший клас датасету слабший за робочий**: 0.719 проти 0.759 —
  але він і стоїть на вдвічі рідшому ряді.
- **Довше вікно класу не допомагає**: 0.746 проти 0.759 на
  `клас210х10х7` і 0.667 проти 0.719 на `клас210х14х4`. У ціни AUC від
  довжини не залежав узагалі; у класу він **падає**, тобто розмазування
  подій по восьми частинах губить те, що клас узагалі має.
- Найсильніші окремі колонки в обох класах — **рівні опори**
  (`support_1`, `support_2`, AUC 0.26 … 0.28, тобто зворотний звʼязок).
  Це та сама опора, яку етап 3 знайшов на ногах росту.

### Усі класи проєкту

13 класів, що є в датасеті всіх шести монет. Дві сітки подій: щільна
(`t_start`, 70 647 подій BTC) і розріджена (`timestamp`, 34 466 —
класи, що вимагають 210 с суцільної історії).

| Клас | Діри | Подій | Колонок | AUC 39 | AUC 100 | Точність 1 % (39 / 100) |
| ---- | ---- | ----: | ------: | -----: | ------: | ----------------------: |
| **ціна (етап 6)** | sum | 70 647 | 30 | **0.830** | **0.830** | 0.628 / 0.981 |
| `class210x14x5` | max | 34 466 | 80 | **0.785** | 0.701 | 0.762 / 1.000 |
| `class210x10m1x7dc` | sum | 70 647 | 112 | **0.764** | 0.753 | 0.633 / 0.891 |
| `class210x10m1x7dd` | sum | 70 647 | 112 | 0.760 | 0.740 | 0.618 / 0.948 |
| `class210x10x7` | sum | 70 647 | 112 | 0.759 | 0.746 | 0.484 / 0.687 |
| `class210x10x7dc` | sum | 70 647 | 112 | 0.757 | 0.756 | 0.580 / 0.987 |
| `class210x10x9` | sum | 70 647 | 144 | 0.752 | 0.746 | 0.242 / 0.591 |
| `class210x10m1x2d` | sum | 70 647 | 32 | 0.726 | 0.721 | 0.451 / 0.802 |
| `class210x10m1x3p1dc` | sum | 70 647 | 64 | 0.722 | 0.733 | 0.319 / 0.733 |
| `class210x14x4` | max | 34 466 | 64 | 0.719 | 0.667 | 0.476 / 1.000 |
| `class210x14x4c` | max | 34 466 | 64 | 0.693 | 0.686 | 0.524 / 1.000 |
| `class210x210x4c` | max | 34 466 | 64 | 0.693 | 0.686 | 0.524 / 1.000 |
| `class210x4bema10x10x130` | max | 34 466 | 64 | 0.689 | 0.529 | 0.714 / 0.810 |
| `class210x14x3` | max | 34 466 | 48 | 0.662 | 0.654 | 0.619 / 1.000 |

Точності між класами не порівнюються — у кожного своя частка мітки в
ряді. Порівнюється **AUC**.

- **Жоден клас не дістає до ціни.** Найкращий — `клас210х14х5` з 0.785
  проти 0.830, і він стоїть на розрідженому ряді, де мітка вчетверо
  частіша. З класів на спільній сітці найкращий `клас210х10-1х7дц`
  (0.764).
- **Довше вікно класам шкодить.** У ціни AUC не міняється від довжини
  (0.830 на обох), а в класів падає майже скрізь: `клас210х14х5`
  0.785 → 0.701, `клас210х4бема10х10х130` 0.689 → 0.529. Вісім частин
  на 100 подій — це 12–13 подій у частині, і те, що клас має, у такому
  усередненні зникає.
- **`клас210х210х4ц` і `клас210х14х4ц` дають однакові числа** (0.693 і
  0.686 на обох вікнах) — і це не збіг: після згортки блоків у середнє
  вони збігаються з точністю 3e−8. Перший — це буквально другий,
  усереднений по 210 с.
- **Розмір входу нічого не вирішує**: 32 колонки `клас210х10-1х2д` дають
  0.726, а 144 колонки `клас210х10х9` — 0.752.

## Результат етапу 8

382 ноги в замірі (train 324, val 58), ноги коротші за 130 подій не
рахуються. Виграш — наскільки менша медіанна помилка проти train-медіани
цілі; перенос — те саме для правила «те саме число, що на попередній
нозі».

### Середина ноги, десятини 4–7

| Що прогнозуємо | Кращий набір | Спірмен за датою | Виграш за датою | Спірмен монетою | Виграш монетою | Перенос |
| -------------- | ------------ | ---------------: | --------------: | --------------: | -------------: | ------: |
| модуль руху події | попередня + позаминула | **+0.691** | **+0.323** | **+0.627** | **+0.271** | −0.073 |
| розкид рухів події | попередня + позаминула | +0.619 | −0.035 | +0.547 | +0.124 | −0.154 |
| скільки подій | попередня + позаминула | +0.474 | +0.011 | +0.340 | −0.233 | −0.419 |
| частка подій у бік ноги | попередня + позаминула | +0.168 | +0.119 | +0.152 | −0.072 | −0.460 |
| напрямлений хід | попередня + позаминула | −0.318 | −0.413 | +0.139 | −0.138 | −0.385 |
| пройдений шлях | початок + попередня | −0.136 | −0.303 | +0.110 | −0.178 | −0.463 |

### Кінець ноги, десятина 10

| Що прогнозуємо | Кращий набір | Спірмен за датою | Виграш за датою | Спірмен монетою | Виграш монетою | Перенос |
| -------------- | ------------ | ---------------: | --------------: | --------------: | -------------: | ------: |
| модуль руху події | попередня + позаминула | **+0.599** | **+0.302** | +0.412 | −0.085 | −0.166 |
| модуль руху події | початок + попередня | +0.419 | +0.029 | +0.412 | **+0.040** | −0.166 |
| розкид рухів події | попередня + позаминула | +0.479 | +0.092 | +0.340 | −0.107 | −0.173 |
| скільки подій | попередня + позаминула | +0.489 | −0.161 | +0.337 | −0.233 | −0.422 |
| напрямлений хід | початок + попередня | +0.119 | −0.214 | +0.262 | −0.275 | −0.417 |
| пройдений шлях | початок + попередня | +0.221 | −0.187 | +0.200 | −0.198 | −0.370 |
| частка подій у бік ноги | власний початок | +0.071 | +0.128 | +0.060 | −0.122 | −0.559 |

### Що з цього виходить

- **Прогнозується тільки розмір події, не її напрямок.** Модуль руху
  події середини ноги вгадується наперед: Спірмен +0.69 за датою і +0.63
  відкладеною монетою, помилка на 27–32 % менша за медіану. Це єдина ціль,
  де обидва ділення дають додатний виграш.
- **Хід, шлях і частка подій у бік ноги не прогнозуються нічим.** Виграш
  відʼємний на всіх чотирьох наборах і в обох діленнях: модель гірша за
  одне число. Тобто **що саме зробить ціна в середині ноги — невідомо**,
  відомо лише, наскільки великими будуть окремі події.
- **Це не памʼять про попередню ногу, а рівень волатильності.**
  Позаминула нога додає скрізь: `попередня + позаминула` бʼє `попередню`
  майже на кожній цілі (+0.63 проти +0.53 на модулі руху середини). Якби
  працював звʼязок «нога → наступна нога», друга нога назад тільки шумила б.
- **Просте перенесення числа через півот не працює** — перенос
  відʼємний скрізь (−0.07 … −0.56), тобто модель таки вчиться, а не
  копіює попередню ногу.
- **Власний початок ноги слабший за історію ніг.** На середині: +0.41
  проти +0.53 монетою. На кінці ноги він додає лише в парі з попередньою
  ногою (+0.04 виграшу — єдиний додатний на цій цілі відкладеною монетою).
- **Кількість подій ноги (її довжина) впорядковується, але не міряється**:
  Спірмен +0.34 … +0.49 при відʼємному виграші. Модель бачить, яка нога
  буде довшою за яку, і не бачить, на скільки.
- Обережність до чисел за датою: там **58 ніг**. Ділення відкладеною
  монетою міряє ті самі цілі на 382 ногах і збігається за знаком на
  кожній із них.

## Вкладка дашборду

Власний URL [`/edges`](http://localhost:8080/edges), дані з `/api/edges`
(`results/edge_profile.json` без переліку ніг — вкладці потрібне зведення).

| Що на вкладці | |
| ------------- | --- |
| Шапка | клас ряду, величина події, поріг і ема, скільки ніг і подій, скільки ніг відкинуто з дірами |
| Перемикач розрізу | усі ноги · вгору · вниз · чотири групи довжини · кожна монета |
| Перемикач частки | `пулом` · `по нозі` |
| Стовпчики | десятина ноги по осі X, частка величини по осі Y; колір — колір десятини, як на `/umap` і `/x7dc`; краї обведені |
| Рядок під перемикачем | ніг, подій, краї, середина і відношення край/середина для обраного розрізу |
| Гістограма | розподіл довжини ноги в подіях, поруч — медіана, квартилі й кореляція довжини з рухом |
| Таблиця | по монетах: ніг, медіана подій, краї, середина, відношення |

Перемикачі міняють лише стовпчики — дані вантажаться один раз.

### Розділ «Що видно з початку ноги»

Дані з `/api/edges/start` (`results/leg_start.meta.json` — той самий файл
без переліку ніг).

| Що на вкладці | |
| ------------- | --- |
| Шапка | скрипт, ряд, поріг і ема, скільки ніг у train і val, межа розбиття, медіана подій у початку |
| Перемикач початку | `перші 39 подій після півота` · `перші 10 % ноги` |
| Перемикач ознак | `усі` · `без довжини ноги` |
| Рядок під перемикачем | напрямок: точність, база, AUC і правило «знак руху початку» |
| Стовпчики | кореляція Спірмена на val по кожній числовій цілі |
| Таблиця | ціль, Спірмен, медіанна похибка, базова, виграш, квартилі й край цілі на val |

### Розділ «Початок ноги: ріст проти падіння»

Дані з `/api/edges/kind` (`results/head_by_kind.meta.json`).

| Що на вкладці | |
| ------------- | --- |
| Шапка | скрипт, довжина початку, скільки ніг росту й падіння в train і val, межа розбиття |
| Графік | середній рух події на кожній позиції початку: зелена лінія — ноги росту, синя — ноги падіння |
| Таблиця ознак | 12 ознак із найбільшою дельтою Кліффа: медіана на рості, медіана на падінні, дельта, p |
| Перемикач | `ріст` · `падіння` |
| Таблиця звʼязків | ознака, ціль, Спірмен на train і на val — тільки ті, що витримали val |
| Таблиця моделей | ціль, Спірмен моделі нарізно, моделі на всіх ногах, і що з них краще |

### Розділ «Хвіст ноги і початок наступної»

Дані з `/api/edges/next` (`results/next_head.meta.json`).

| Що на вкладці | |
| ------------- | --- |
| Шапка | скрипт, довжина хвоста й початку, скільки пар ніг у train і val, межа розбиття |
| Стовпчики | на кожну ціль дві смуги: модуль Спірмена моделі й модуль Спірмена переносу |
| Таблиця | ціль, Спірмен моделі, виграш над медіаною, яке число переноситься, його Спірмен, що з них краще, квартилі цілі на val |

### Розділ «Подія краю ноги проти звичайної події»

Дані з `/api/edges/events` (`results/event_edges.meta.json`).

| Що на вкладці | |
| ------------- | --- |
| Шапка | скрипт, довжина вікна, скільки подій у train і val, межа розбиття |
| Таблиця | мітка, частка в ряді, AUC, точність на верхніх 5 % оцінок, приріст, покриття |
| Перемикач мітки | останні 10 подій · перші 10 подій · ±10 від півота · остання десятина · перша десятина |
| Криві | середня оцінка моделі по десятинах ноги і по позиції після півота; пунктир — частка мітки в ряді |
| Легенда | сторона краю: AUC і точність «до півота чи після» |

### Розділ «За скільки подій видно, що почалась нова нога»

Дані з `/api/edges/newleg` (`results/new_leg.meta.json`).

| Що на вкладці | |
| ------------- | --- |
| Шапка | скрипт, питання, поріг і ема, межа розбиття |
| Перемикач порога | верхівка оцінок: 0.1 · 0.5 · 1 · 2 · 5 · 10 % |
| Стовпчики | точність на кожній довжині вікна; лінія поверх них — затримка сигналу в подіях, права шкала |
| Таблиця | довжина вікна, частка мітки в ряді, AUC, точність, приріст, покриття, затримка і найсильніша окрема ознака |

### Розділ «Нова нога на подіях кожного класу»

Дані з `/api/edges/classes` (`results/class_new_leg_all.meta.json`).

| Що на вкладці | |
| ------------- | --- |
| Перемикач вікна | 39 подій (2.3 год) · 100 подій (5.8 год) |
| Таблиця | клас, режим фільтра дір, подій у його ряді, колонок на вході, частка мітки, AUC, точність на верхівці 1 %, приріст, затримка і найсильніша окрема колонка |
| Легенда | чому порівнюється AUC, а не точність, і скільки дає та сама модель на ході ціни |

### Розділ «Видача моделей рядом на val»

Дані з `/api/edges/newleg/series` (перелік монет і моделей) і
`/api/edges/newleg/series/<PAIR>` (ряд однієї монети — окремим файлом,
щоб вкладка не тягнула всі шість одразу).

| Що на вкладці | |
| ------------- | --- |
| Перемикач монет | шість монет, на кнопці — точність цієї монети |
| Перемикач видач | рядок на кожну мову опису — `ціна` і кожен клас на сітці ціни, у рядку кнопки довжин вікна (39 і 100 подій). Спершу показані `ціна` і `клас210х10х7`; решта — за вибором, одна видача лишається завжди |
| Верхня смуга | ема10 ціни із зігзагом 2.3 % на вікні val |
| Плашка видач | **усі чотири видачі на одній шкалі 0…1**, кожна своїм кольором, пунктир того самого кольору — її поріг із train |
| Смуги сигналу | на кожну видачу своя: вгору влучив, вниз хибний |
| Легенда | на кожну модель — скільки сигналів, скільки влучань, точність |

Колір видачі береться за її місцем у переліку: `ціна 39` синій,
`ціна 100` фіолетовий, далі класи по колу палітри.

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

Шістнадцять видач: ціна і сім класів на сітці ціни × два вікна. Пороги
з `train` (верхівка 1 % його оцінок) і що вони дають на val шести монет:

| Мова опису | Поріг 39 / 100 | Сигналів 39 / 100 | Точність 39 | Точність 100 |
| ---------- | -------------: | ----------------: | ----------: | -----------: |
| ціна | 0.6883 / 0.9085 | 447 / 1 083 | **0.651** | **0.917** |
| `class210x10m1x2d` | 0.2669 / 0.5778 | 581 / 774 | 0.430 | 0.767 |
| `class210x10m1x7dc` | 0.3458 / 0.6606 | 2 038 / 2 141 | 0.439 | 0.733 |
| `class210x10x7dc` | 0.3416 / 0.6673 | 2 172 / 2 324 | 0.394 | 0.723 |
| `class210x10m1x7dd` | 0.3559 / 0.6516 | 1 902 / 2 278 | 0.442 | 0.720 |
| `class210x10x7` | 0.4115 / 0.7170 | 1 860 / 2 324 | 0.397 | 0.659 |
| `class210x10m1x3p1dc` | 0.2771 / 0.5783 | 613 / 1 031 | 0.313 | 0.645 |
| `class210x10x9` | 0.4426 / 0.7231 | 800 / 638 | 0.266 | 0.560 |

Порядок той самий, що за AUC у таблиці класів, і ціна попереду всіх на
обох вікнах. На короткому вікні жоден клас не переходить 0.45, тоді як
ціна дає 0.65.

По монетах розкид великий на всіх чотирьох: `ціна 39` дає від 0.03 на
`SOL_USDT` до 0.81 на `XRP_USDT`, `клас 100` — від 0.09 на `BTC_USDT` до
1.00 на `BNB_USDT`. Один поріг на всі монети — груба настройка, і це
видно тільки на ряді.

Усі смуги мають спільну вісь X і скейляться під свої дані; колесо миші —
масштаб, перетягування — зсув, подвійний клік — скинути.

### Розділ «Прогноз середини й кінця ноги»

- Ендпоінт `/api/edges/ahead`, файл `results/leg_ahead.meta.json`
  (перелік ніг вкладці не потрібен і не віддається).
- Перемикач **відрізка**: середина ноги (десятини 4–7) · кінець ноги
  (десятина 10).
- Перемикач **що видно моделі**: попередня нога · попередня + позаминула ·
  власний початок · початок + попередня.
- Таблиця: рядок — ціль, стовпці — Спірмен і виграш за датою, Спірмен і
  виграш відкладеною монетою, перенос, медіанна помилка й помилка
  медіани. Додатний виграш виділений.
- У легенді сказано, чим ділення за датою відрізняється від ділення
  монетою і скільки ніг у кожному.

## Приклади

Вхід — подія ряду:

```
t_start 1771137394 · price_open 70650.12 · price_close 70663.44
```

Величина події: `v = ln(70663.44 / 70650.12) = +0.000189`.

Вихід — профіль у `results/edge_profile.json`:

```json
{"pooled": [0.193, 0.085, 0.076, 0.071, 0.058, 0.063, 0.070, 0.053, 0.132, 0.198],
 "edges": 0.391, "middle": 0.262,
 "edge_to_middle": 2.98}
```

Етап 2 — вихід у `results/leg_start.json`, чесний замір (`fixed_head`):

```json
{"direction": {"accuracy": 0.978, "base_accuracy": 0.506, "auc": 0.998},
 "events_left": {"spearman": 0.436, "gain": 0.038},
 "against_p90": {"spearman": 0.602, "gain": 0.221},
 "against_max": {"spearman": -0.033, "gain": -0.159}}
```

## Перевірка перед завершенням

- [x] всі етапи підтверджені (1–8, 2026-09-09), непідтверджене видалено
- [ ] логіка послідовна
- [ ] відтворюється з цього файлу + даних
