Блог им. evgeniym_956

Мой сканер объёмов пропускал аномалии. Норма догоняла всплеск

Пишу сканер аномальных объёмов по MOEX. Логика простая: считаем норму объёма
для инструмента, сравниваем с текущим, превышение — сигнал. Всё работало.
Сигналы приходили, ложных было немного, я был доволен.

Потом полез в логи разбираться, почему на очевидном движении не было сигнала.
И выяснил, что система его видела. Посчитала. И сама же выбросила.

## Почему EMA казалась хорошей идеей

Норму я считал через экспоненциальную скользящую по объёму. Аргумент был
железный: рынок меняется, режимы меняются, статистика за 90 дней устаревает.
EMA подстраивается под текущий режим — если объёмы выросли в целом, порог
поднимется сам, и мы не завалим канал сигналами на ровном месте.

Звучит разумно. Так делают многие. Это и есть ошибка.

## В чём проблема

EMA обновляется той же свечой, с которой вы её сравниваете.

Прилетает аномальный объём. Система его фиксирует, но этой же свечой EMA идёт
вверх. Следующая аномальная свеча сравнивается уже с задранной нормой —
превышение меньше. Третья ещё меньше. К четвёртой-пятой свече EMA догнала
аномалию, и всплеск стал новой нормой.

Детектор аномалий адаптировался к аномалии. Ровно то, чего он делать не должен.

Особенно больно это било по самому интересному сценарию — растянутому входу
крупного объёма. Разовый выброс на одной минуте система ловила. А набор позиции
в течение дня — нет.

## OZON, 30 июля, часовой таймфрейм

Вот как это выглядит на живых данных. Оба столбца — сырые значения из журнала
сканера за один торговый день. Слева объём на момент замера, справа норма,
с которой система его сравнивала.

```
время    оборот       норма
07:38      974 млн ₽    196 млн ₽
09:43      650 млн ₽    296 млн ₽
10:54    1322 млн ₽    343 млн ₽
11:53    1081 млн ₽    411 млн ₽
12:42      930 млн ₽    458 млн ₽
17:52      728 млн ₽    510 млн ₽
19:43      750 млн ₽    747 млн ₽
```

Две оговорки, чтобы цифры можно было сверить. Это рублёвый оборот, а не число
бумаг: в терминале тот же час покажет сотни тысяч акций. И это оборот на момент
замера, а не за час целиком — сканер не ждёт закрытия свечи, иначе сигнал
приходил бы с опозданием до часа. Так что с закрытым часовым баром в терминале
эти числа сойдутся только по порядку величины.

Смотрите не на левый столбец, а на правый.

Объём весь день держится в диапазоне 650–1300 млн ₽. Он не растёт и не падает,
крупный игрок ровно работает с позицией с утра до вечера.

А норма за этот же день выросла со 196 до 747 млн. Почти вчетверо. К вечеру она
догнала объём вплотную — 750 против 747, — и последний замер система засчитала
как совершенно обычный день.

Утренняя норма 196 млн накоплена за предыдущие дни, до начала истории. То есть
объём в 750 млн вечером был выше обычного почти в четыре раза. Система этого
уже не видела. Не потому, что рынок успокоился, — потому что она к нему привыкла.

Старый порог на часовике стоял на +200%. Из семи замеров его прошли два: утренний
и в 10:54. Причём не подряд — между ними замер, который до порога не дотянул.
Вместо растянутой аномалии на весь день система показала два разрозненных
всплеска.

## Почему это не заметно

Худший класс бага. Не падение, не исключение в логе. Система работает, отвечает,
сигналы шлёт — просто не те. Причём фильтр не был «слишком строгим»: строгий
режет всё подряд, и ложные срабатывания тоже, по ним проблему видно. Этот резал
избирательно. Пропускал ровно то, ради чего система писалась, и почти не давал
взамен ложных, по которым можно было бы спохватиться.

Такое не находится, пока не пойдёшь проверять руками конкретный случай, про
который точно знаешь ответ.

## Что теперь

Норма считается через статистику Уэлфорда — среднее и дисперсия обновляются
одним проходом, всю историю хранить не нужно.

Ключевое: **на коротких таймфреймах норма для 10:00 строится только из данных
за 10:00 других дней.** Она не может подтянуться к сегодняшнему всплеску, потому
что сегодняшний всплеск в неё не входит. Он попадёт в выборку завтра,
разбавленный всей накопленной историей. На 4h и 1d разбивки по часам нет —
там считается общее среднее, глубина истории своя для каждого таймфрейма.

EMA осталась, но в роли мягкого пола — отсекать шум на неликвиде, где статистика
по часам сама по себе разболтанная.

## Мораль, если она нужна

Адаптивная норма и детектор аномалий — противоречащие друг другу вещи. Чем
быстрее ваш baseline подстраивается под рынок, тем меньше событий он считает
необычными. В пределе идеально адаптивная норма не находит аномалий вообще:
для неё всё нормально.

Если у вас в системе что-то считается «относительно скользящего среднего» —
проверьте, не обновляется ли это среднее тем же значением, с которым вы его
сравниваете.

Сигналы выкладываю в @Volume_Scanner_MOEX, если интересно посмотреть на результат.

Кто как решает эту задачу? Интересно, есть ли подход лучше, чем разделение
выборки по времени суток.


 

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
172
#149 по плюсам

Читайте на SMART-LAB:
Фото
💼 Positive Technologies планирует размещение облигаций
Этот выпуск станет уже шестым для компании и будет направлен на повышение финансовой устойчивости компании, создание резервного портфеля...
Фото
MCP API OsEngine V1 beta. Для кого это и что теперь могут ИИ
Друзья мои, всем привет! У нас большое событие — в OsEngine появился MCP API. Это не очередной «разъём для галочки», а штука, которая меняет сам...
Фото
Ближайшие события. Как к ним подготовиться инвестору
Рассказываем, на какие события в России и мире стоит обратить внимание инвесторам в ближайшие недели. Есть способы заработать на будущем, если...
Фото
Россети Ленэнерго. РСБУ за Q2 26г. Стабильность - признак мастерства
Компания Россети Ленэнерго опубликовала финансовый отчет за Q2 2026г. по РСБУ: 👉Выручка — 35,60 млрд руб. (+12,4% г/г) 👉Себестоимость —...

теги блога евгений м

....все тэги



UPDONW
Новый дизайн