Данный пост рассказывает о моём первом опыте вайб-кодинга.
Old File Delete (OFD) — это легкая и эффективная утилита, разработанная для тех, кто ценит минимализм и порядок. Приложение помогает мгновенно очистить выбранные папки от накопившегося цифрового мусора.
Написано на Python, библиотека Tkinter.
Само приложение состоит из 1 экрана:
Написано с помощью GPT-5-mini. Использовались всего 5 запросов, моих правок абсолютно нет:
Сделай приложение Old File Delete. Используй следующее описание:
Приложение сканирует папку и удаляет файлы, которые не изменялись более $N$ дней.
• os: Основная библиотека для работы с операционной системой. Используется для листинга файлов в директории (os.listdir) и их удаления (os.remove).
• pathlib: Современный интерфейс для работы с путями. Позволяет легко получить время последнего изменения файла (path.stat().st_mtime) и удобно манипулировать путями независимо от формата Windows.
• tkinter.filedialog: Часть стандартной библиотеки GUI. Нужна для вызова стандартного окна Windows, чтобы пользователь мог выбрать папку для очистки, а не вводить путь вручную.
Работаешь на питоне. Библиотека ткинтер. Вверху главного окна название, справа от него кнопка настроек.
Далее кнопка выбора папки, которую надо проверить. Далее текстовое поле для ввода времени в днях. Далее кнопка очистить. После очистки создаётся маленькое окошко, в котором написано, что все ок. В настройках возможность настройти язык. В самом начале работы читается файд "language.txt". В нём только 1 число. Если 1 то язык английский, если 2 то русский.
Убери из этого приложения настройки. Переделай все в бело-серые тона. Фон белый-очень светлый серый. Текст на фоне средне серый. Кнопка средне серый. Текст на кнопке очень светлый серый. фон окошка для числа дней также как и фон, только чуть светлее. Текст такой же. Название по центру. Снизу убери лишнее пространство
Язык только английский
Сделай текст больше до 24. Ужми побокам
Ширина 350
Можете скачать и протестировать его. Буду благодарен за конструктивную критику и идеи.
### Эффект свечения при наведении - **Неоновое свечение** вокруг элементов при наведении курсора - Полностью настраиваемый эффект: - Размер свечения (от 0 до 50px) - Цвет свечения (любой цвет палитры) - Плавная анимация мигания с настраиваемой скоростью - Поддержка всех форм элементов (круг, квадрат, скруглённый, шестиугольник и.т.д.)
### Система бейджей уведомлений - **Визуальные счётчики** непрочитанных сообщений на элементах - Автоматическое определение уведомлений из приложений (Telegram и др.) - Полная настройка внешнего вида: - Цвет бейджа - Размер бейджа - Размер текста - Включение/выключение - Умное форматирование чисел (99+ для больших значений)
## Технические улучшения
### Улучшенная стабильность - **Автоматический перезапуск** системных listeners при обнаружении конфликтов - Умное определение проблемных приложений - Мониторинг состояния в реальном времени - Защита от зависаний при работе с глобальными горячими клавишами
### Улучшения интерфейса - Исправлены тексты заголовков в настройках - Оптимизировано позиционирование элементов - Улучшена производительность рендеринга
## Ключевые преимущества
**Более информативный интерфейс** — видите количество непрочитанных сообщений сразу **Высокая стабильность** — автоматическое восстановление при сбоях **Полная настройка** — каждый эффект можно настроить под себя
*Версия 5.3 — делаем работу с компьютером удобнее и красивее!*
Home Assistant позиционирует себя как локальную систему. Но я столкнулся с ситуацией, когда локальная функция (Samba) не работает из-за облачного сбоя. При этом я вообще не использую облако. В статье описываю как обошёл эту проблему за 5 минут, когда за день разобрался в причине.
Мне очень нравится Home Assistant как система управления умным домом, потому что она позволяет не зависеть от облаков и от падений интернета. Это не просто слова - с 2017 года я использую умный дом в обычной двухкомнатной хрущевке, и в основном всё работает. Но это скорее тестовый полигон для меня - я сам там не живу и поэтому очень ценю то что Home Assistant можно настроить один раз и если не обновлять, то несколько лет всё может спокойно проработать. А на этих новогодних каникулах у меня было время и я решил полностью обновить все дополнения и прошивки. Как оказалось зря - паранойя безопасности ломает определение Home Assistant как автономного сервиса, который можно использовать локально.
В первых числах января 2026 решил удаленно обновить все зависимости - за несколько раз всё обновилось, но мне ещё понадобилось включить дополнение Samba share, чтобы из под Windows проверить пару конфигов, которые не хотели работать. А я отключил Samba share ещё год назад. Удаленно не смог включить - всё какая-то ошибка вылазила, хотя все остальные компоненты работают. Пришлось ехать на квартиру и думал что может быть Raspberry Pi 3 2015 года уже старая стала или флешка сдохла. У меня было ещё несколько запасных - прихватил и чистую флешку и новый микрокомпьютер 2017 года и новый блок питания.
"Стенд проверки"
Поставил чистую систему - в 2026 году это происходит через Raspberry Pi Imager, хочу с Windows компьютера подключиться, а там та же ошибка Не удалось сохранить конфигурацию дополнения, Unknown error, see supervisor logs. И непонятно из-за чего.
Ошибка Home Assistant Не удалось сохранить конфигурацию дополнения, Unknown error, see supervisor logs
Только в логах на чистой системе подробно рассмотрел что WARNING (MainThread) [supervisor.utils.pwned] Can’t fetch HIBP data: Timeout
Стал разбираться и оказалось что Home Assistant абсолютно все пароли проверяет на скомпромитированность через онлайн сервис, а поскольку мы в России, то этот сервис не даёт ответа видимо из-за санкций или политики, а в интерфейсе ничего внятного не пишет - просто неизвестная ошибка.
И я в своём полностью локальном Home Assistant не могу к нему по локальной сети подключиться из-за того что этот онлайн сервис HIBP не отвечает. Сервис HIBP (Have I Been Pwned) проверяет были ли заново создаваемые пароли в утечках данных.
Но какая-то нестыковка кажется с заявленной полной локальностью Home Assistant?
Home Assistant пользуется этим сервисом и это нельзя отключить для проверки безопасности паролей. Но я даже не знал что такая проверка есть, а у сервиса проблемы с доступностью в России из-за санкций или Роскомнадзора, что вызывает ошибки и блокирует работу всей домашней системы.
Поскольку у меня уже был физический доступ к SD карте - раз я приехал на удаленную квартиру, на которой установлен Home Assistant, то решил через физическое подключение к Linux провести все манипуляции, потому что функция PwnedConnectivityError блокирует абсолютно всё.
SD карта, подключенная к Linux
Нашёл проблему в файле pwned.py, он файл лежит внутри контейнера Supervisor, в моём случае по адресу admin:///media/mike/hassos-data/docker/overlay2/0e05ec32ffef35caed1b7184eefcfdda5eb1a35ad60e68e5d14f3a73996b18ea/diff/usr/src/supervisor/supervisor/utils.
Картридер в Ubuntu
Но у вас будет другой путь, надо искать внутри внутри контейнера Supervisor: /usr/src/supervisor/supervisor/utils/pwned.py
async def check_pwned_password(websession: aiohttp.ClientSession, sha1_pw: str) -> None: """Check if password is pwned.""" sha1_pw = sha1_pw.upper()
# Chech hit cache sha1_short = sha1_pw[:5] if sha1_short in _CACHE: raise PwnedSecret()
_LOGGER.debug("Check pwned state of %s", sha1_short) try: async with websession.get( _API_CALL.format(hash=sha1_short), timeout=aiohttp.ClientTimeout(total=10) ) as request: if request.status != 200: raise PwnedError( f"Pwned service response with {request.status}", _LOGGER.warning ) data = await request.text()
buffer = io.StringIO(data) for line in buffer: if not sha1_pw.endswith(line.split(":")[0]): continue _CACHE.add(sha1_short) raise PwnedSecret()
except (aiohttp.ClientError, TimeoutError) as err: raise PwnedConnectivityError( f"Can't fetch HIBP data: {str(err) or 'Timeout'}", _LOGGER.warning ) from err
async def check_pwned_password(websession: aiohttp.ClientSession, sha1_pw: str) -> None: """Check if password is pwned.""" return None
""" sha1_pw = sha1_pw.upper()
# Chech hit cache sha1_short = sha1_pw[:5] if sha1_short in _CACHE: raise PwnedSecret()
_LOGGER.debug("Check pwned state of %s", sha1_short) try: async with websession.get( _API_CALL.format(hash=sha1_short), timeout=aiohttp.ClientTimeout(total=10) ) as request: if request.status != 200: raise PwnedError( f"Pwned service response with {request.status}", _LOGGER.warning ) data = await request.text()
buffer = io.StringIO(data) for line in buffer: if not sha1_pw.endswith(line.split(":")[0]): continue _CACHE.add(sha1_short) raise PwnedSecret()
except (aiohttp.ClientError, TimeoutError) as err: raise PwnedConnectivityError( f"Can't fetch HIBP data: {str(err) or 'Timeout'}", _LOGGER.warning ) from err """
После того как внёс изменения и вставил SD карту обратно в Raspberry Pi все пароли стало успешно сохранять и работоспособность полностью восстановилась.
Работоспособность сохранения паролей восстановилась
Мне кажется подобные решения очень сильно бьют по новичкам, которым реально сложно разобраться в подобных системах и ещё больше вопросов вызывает то что Home Assistant всегда был полностью локальной автономной системой, которую можно было настроить даже на даче и тут вылазит такая фишка.
Вообще мне кажется что стремление к безопасности — это хорошо, но вот делать зависимость от внешнего API для базовых локальных функций — это архитектурная ошибка.
Обычный код с надписью "Привет, Мир!" выводится сразу:
print("Привет, Мир!")
Это не так хорошо будет выглядеть в консольной игре.
Так что добавляем функцию print_slow():
import time
def print_slow(text): for i in range(len(text)): print(text[i], end="") time.sleep(0.5)
print_slow(input("Введите текст: ")) # Если пробелы не расставлены, то это вина Пикабу
Теперь, любой введённый нами текст будет выводиться в скорости 1 символ в 0.5 секунд.
Чтобы настроить время, надо изменить 6-ую строку кода:
time.sleep(Введите время в секундах)
Пожалуйста.
UPD: Вот готовый код:
import time
def print_slow(text, speed): for i in range(len(text)): print(text[i], end="") time.sleep(speed)
def main(): while True: s = input("Введите текст (exit - выход): ") if s == "exit": break else: speed = float(input("Введите скорость текста в секундах: ")) print_slow(s, speed) print() if __name__ == '__main__': main() # Если пробелы не расставлены, ЭТО НЕ МОЯ ВИНА!!!
С первой серьезной трудностью я столкнулся спустя пару минут (образно говоря) как я решил начать учить ЯП. После некоторых «исследований» выбор пал на пайтон (или питон?). Слово за слово, кодом по столу, я приступил к установке змея на комп. Все шло гладко до момента установки змея в ВС код. Он просто не скачивался.
Казалось бы, решение трудности очевидно: ВПН. В итоге несколько часов танцев с бубном (да, я в курсе что есть и другие IDE) не дали НИЧЕГО.
Благо начал я с курса на степике и там есть встроенный змей, отложив затею на неопределенный срок, я наконец научился писать Hello world.
И вот, спустя буквально 2-3 дня, я на работе решил попробовать накатить змея в ВС код ииии …. Он встал
Вечером я пришел домой и попробовал еще раз поставить его себе на комп и он тоже встал
Я так и не понял что все это было, но во всем этом есть определенно некий философский смысл, надеюсь осознать его в будущем
Всем привет, я мужчина в самом закате сил и здесь начинается мой путь в айти. Надеюсь нас всех ждет увлекательное приключение, ребята!
Скоро Новый год, и мне хотелось бы поздравить вас всех с этим прекрасным праздником! 🎄 Год был нелёгкий, но каким бы он ни был — он заканчивается. А значит, мы с вами будем верить в лучшее.
В качестве небольшого подарка хочу поделиться с вами приложением, которое пилю уже довольно давно. Ну как «сам»… программист из меня — как из пластилина пуля, так что пилю вместе с Cursor: я тут скорее менеджер проекта и тестировщик 😄 (Сочувствую всем тестировщикам — я теперь реально понимаю, через что вы проходите.)
Началось всё с того, что в продажу вышла мышь Logitech MX Master 4. Мне очень понравилась идея боковой кнопки, которая вызывает кастомное меню. Удобно же, когда всё нужное под рукой. Но покупать такую мышку по цене почки за 10к (на момент выхода) мне было дороговато. И я решил создать…
Нет, Бендер, другое.
...свою менюшку😎
Для начала я набросал небольшое ТЗ. В старте использовал DeepSeek — код он пишет неплохо, но сильно ограничен по длине чата. Приходилось постоянно переносить ТЗ и описания в новые диалоги, что было жутко неудобно. Потом попробовал Qwen: поначалу всё ок, но в какой-то момент он не мог найти простую ошибку и повторял её снова и снова. С этим наброском я пришёл к Grok — сначала писал нормально, а потом начал ломать код и выпиливать функции. Горело у меня знатно)) В итоге все мои изыскания привели меня к Cursor. Не буду его нахваливать — у него тоже хватает проблем, но основные задачи он помог решить и довести это безобразие до ума)
Основные настроки
Теперь, собственно, о самой программе. Это кастомная менюшка, которая собирает всё самое нужное и кладёт вам буквально «в одну руку»: программы, горячие клавиши, команды, ссылки, папки, файлы — всё для быстрого доступа.
Когда программа была почти готова, вылезла проблема: в некоторых играх и приложениях меню могло вызываться из-за совпадения клавиш. А выпрыгивающее поверх игры меню — то ещё удовольствие 😅 Поэтому я добавил возможность указывать приложения-исключения.
У меня, к сожалению, нет Helldivers — если кто-то сможет протестировать вызовы подкрепления и прочие штуки, буду рад 👀
В программах вроде Blender, Photoshop, AutoCAD меню может быть полезно как кастомная панель горячих клавиш. Если вы программист и вам нужны свои команды — в окне «Команды» можно прописать их, сохранить, подписать и назначить на любой элемент.
В процессе разработки я понял, что одного меню может быть мало: в одной программе нужно одно, в другой — другое. Так появилась идея сценариев, между которыми можно переключаться на лету.
Каждый сценарий можно подписать и настроить под конкретные задачи. Между сценариями можно быстро переключаться с помощью Ctrl+1, Ctrl+2, Ctrl+3 (в зависимости от количества сценариев). Для каждой настройки есть описание — что это и зачем. Можно отключать надоедливые подсказки в настройках)) Меню полностью настраивается под вкус и цвет. Так как я немного пишу музыку, добавил звуки.
Винда при запуске может ругаться на программу, так как программа отслеживает нажатие клавишь. И это логично, иначе как вызывать программу. Так что просьба не паниковать) Прогамма ни каких данных не собирает, никуда ничего не передаёт.
Так как у каждого монитора свой DPI пришлось сделать для этого отдельный ползунок в настройках. Есть светлая тема и ̶п̶о̶ж̶а̶л̶е̶й̶т̶е̶ ̶м̶о̶и̶ ̶г̶л̶а̶з̶а̶ тёмная тема🌚 Все элементы я рисовал сам. В будущем, возможно, буду добавлять новые элементы и звуки. Если вы умеете работать в Adobe Illustrator — могу в следующем обновлении добавить открытую папку для ваших эскизов (формат SVG). Да, я знаю что вы сейчас напишите, что таких програм много. Знаю. Но это моя программа, я делал её сам и делюсь с вами. Программа бесплатная. Есть ссылка на донат, если кто захоет отблагодарить и скинуть на чашку кофе)). А так же почта для обратной связи, если есть идеи и предложения.
Если будут какие-то ошибки, ошибки, можете написать в комментарии или на почту. И ещё раз, я не программист)) Делал как мог, стестировал как мог, так что сильно не пинайте😄 Программа ещё в процесе разработки, так что буду ещё допиливать потихоньку. На счёт ссылки на яндекс, я так понял, что там нельяз обновлять файл, а в гугл диске можно.
В общем, всех с наступающим Новым годом! 🎄 Пусть в новом году вам сопутствует удача, а беды обходят стороной. И пусть случится всё хорошее! 🍾🥂🎁🎆
На прошлой неделе я не внес значительных изменений. Однако я всё же успел реализовать несколько важных задач.
Типы транспорта
Ранее я уже говорил о необходимости добавить типы транспорта для более точного расчёта закрытия объекта. Это также пригодится в будущих анализах.
К сожалению, в тулбаре теперь отображается на один объект больше. Но, к счастью, тулбар анимирован, поэтому место для новых элементов ещё есть.
Кнопка "Транспорт" в тулбаре
Нажимая на "Транспорт" открывается диалоговое окно, которое показывает полный список созданных типов транспорта и их вместимость.
Пользователь может:
Создать новый тип
Редактировать
Удалить
Окна создания и редактирования между собой похожи
Создание и редактирования типа транспорта
При создании записи с данными в SQLite каждый пользователь, работающий с исходным файлом, видит изменения в своём интерфейсе.
Пользователь также может привязать типы транспорта к региону с уникальной ценой за трак. Важно понимать, что цена за трак не всегда отражает реальную стоимость перевозки. Существует KPI по проценту утилизации трака, который показывает, насколько эффективно используется транспорт.
В транспортной и складской логистике успешная транспортировка считается, когда процент утилизации трак стремится к 100%. Однако это редкое явление, так как часто перевозят воздух в коробках, а упаковка, например, стрейч, также влияет на утилизацию. Если же транспортировка осуществляется паллетами, то процент утилизации обычно ниже 85%.
С учётом этих факторов мы рассчитываем реальную стоимость перевозки. Например, трак объёмом 70 кубических метров стоит 300 тысяч рублей, а его утилизация составляет 90%. В этом случае перевозка одного кубического метра в среднем будет стоить 4,7 тысячи рублей. Различные цены на разные автомобили позволяют нам получить разные средние цены перевозки 1 кубического метра.
Как это работает. Пользователь выбирает склад, нажимает «Рисовать регион» и обводит на карте зону доставки. Затем он указывает типы автомобилей, которые могут использоваться для перевозки, и среднюю стоимость доставки одного кубического метра.
Эти данные попадают в расчёты «Анализ закрытия» и «Анализ открытия» (начал его разрабатывать).
Анализ расчета стоимости перевозки товара
Мы понимаем, что машина может следовать по рейсу, поэтому в отчёте программа автоматически рассчитывает рейсы. Но возникает вопрос: что делать, если машина утилизирована не полностью? Например, если товары для магазинов А и В попали в один маршрут, но их хватило только на 70% утилизации?
На этот случай тоже есть решение. Логика учитывает ближайшие объекты и дополняет рейс товарами для них. Если объём отгрузки небольшой, программа определяет оптимальный тип транспорта. В итоге мы получаем более-менее верное решение.
Данную логику сидел, проверял вручную в EXCEL и с помощью обычной карты. Попадание в 97% точности. Где-то не учла верность перераспределения и тем самым занизила на 3% стоимость перевозок. Но 3% (а вообще до 5%) в рамках погрешности, поэтому можно сказать что "Успех".
Доработка с транспортом - не сама тяжелая, она отняла у меня буквально 3 вечера.
Декомпозиция старого кода
Когда начинал писать программу, особо еще не знал правильность. Был такой юношеский максимализм. Писал огромные модули в одном файле, вследствие чего те же «Дашборды» разрослись на 5 файлов по 4к строк кода в каждом.
Сидел на прошлой неделе и думал: «Надо добавить пару новых графиков, а как делать-то? Я уже не помню этот код, куча вызовов, да и он больше на монолит похож». Пытался добавить спарку «График + гистограмма» — получил ошибку методов, начал ковырять глубже — так вообще пришлось откат из репозитория делать.
Новая структура выглядит более удобной, и можно вносить изменения с минимальными правками:
Новая структура
Для сравнения вот старая модель:
Старая структура
Это был настоящий кошмар. Стили, логика и подключения были объединены в один файл. Оркестратор "Менеджер" тоже содержал много лишнего..
Пример декомпозиции
UI — это то, что мы видим на экране. При любом взаимодействии с интерфейсом система вызывает посредника, который отправляет сигнал в логику. Логика получает сигнал и решает, нужно ли ей работать с хранилищем. Если да, она собирает данные и отправляет их обратно посреднику. Посредник проверяет, нет ли ошибок, и передает данные в UI, который их отображает.
Такая структура позволяет легко и быстро вносить изменения. Новые стили, графики, страницы и меню можно добавить за один вечер, не нарушая логику работы всей системы.
В целом вообще сейчас стараюсь переписывать часть старого кода, с опытом многое понял про правильность и оптимизацию. Старые методы которые я писал с кучей подключений на 200-300 строк, получается сократить до 100-150. Первое - много принтов для логирования (часть убрал), второе - лишние проверки переменных. Добавлял на случай "Что бы на верняка".
Анализ открытия
Вечером пятницы сидел и понимал что пора развивать новый отчет. В начале набросал UI составляющую сотканную из заглушек.
Новый отчет
На скриншоте выше - это только концепт-макет.
Структура отчета
Накидал быстро файловую структуру которая будет для данного анализа.
По структуре видно что планируются такие логики как "Каннибализации". Это когда объект может забрать часть продажи у другого объекта
ROI с учетом всяких вводных типа "ФОТ, Аренда, опексы, стоимость транспортировки товара на магазин". Так как программа для компаний с большой историей, то и считать она будет исторические данные для точки. Например ближайшие магазины и какие продажи, какие тут были доставки и тп. Исходя из этого, строится предполагаемая модель продаж, выручка, считаются долгосрочные вложение и получаем сколько надо месяцев на окупаемость магазина.
Продуктовая матрица - как раз в ROI частично описал. Смотрим ближайшие магазины, смотрим что уходило в эту зону на доставку, считаем ABC, смотрит запас товара в регионе - формируем матрицу.
Логистическая карта - обратная функция от закрытия. Как измениться зона курьерских доставок и времени если именно тут открыть магазин.
И т.д.
Сейчас даже не знаю сколько потребуется времени на реализацию всей задумки. Пока что закладываю месяц на стартовый отчет и еще недели 2 на правки. Но впереди праздники, возможно стоит приступить к этому после Нового Года, а до этого момента исправить старые недочеты.
Как обычно, всем спасибо за прочтение. Если есть какие-то идеи, предложения по улучшению UI или логики программы - пишите, буду рад принять что-то новое!😊
Следующие новости - после праздников. Всех с Наступающим Новым Годом!☃️
Обычный трейдер смотрит на свечной график, но свеча — это уже тень прошлого, постфактум. Между тем настоящая динамика рождается в глубине торгового стакана — Limit Order Book, где борьба заявок определяет будущий импульс.
Проблема в том, что историю стакана почти нигде не увидеть: розничные терминалы для частных клиентов дают лишь текущую таблицу DOM ( Depth of Market ) и это статичный срез без прошлого.
Чтобы увидеть то, на что обычный трейдер не обращает внимание я собрал инструмент, который превращает исторические данные L2 Order Book (стакан заданной глубиной) и Trades Stream (обезличенные сделки) в тепловые карты и позволяет изучать эволюцию заявок на Московской бирже через браузер с Deep Zoom — плавно, как в Google Maps.
Знаете Bookmap?
Если вы когда‑либо видели Bookmap, то идея проекта вам покажется знакомой. Bookmap — это профессиональный инструмент, который рисует тепловую карту ликвидности стакана и сделок в реальном времени: где стоят крупные заявки, как они двигаются, исчезают или наоборот «притягивают» цену. Но Bookmap дорог, закрыт и не работает с Московской биржей.
Что мы на самом деле видим?
Биржевой стакан — это не таблица в терминале и не набор случайных чисел. Это живая очередь намерений. Тысячи алгоритмов и людей размещают заявки на покупку (bid) и продажу (ask), формируя хрупкий баланс спроса и предложения. В каждый момент времени стакан отражает то, что участники хотят сделать, но ещё не сделали. И именно эти несовершившиеся действия двигают рынок.
Когда‑то впервые открыть глаза на это помогли работы Nanex. Их система NxCore показала, что HFT‑алгоритмы оставляют следы — характерные узоры, вспышки ликвидности, провалы, которые на свечном графике просто растворяются. В их визуализации «Disturbing Liquidity» исчезновение 80% заявок за одну секунду выглядело как цифровой обвал — видимый только тем, кто смотрит внутрь книги ордеров, а не на результат на графике.
Nanex ~ 14-Sep-2012 ~ Disturbing Liquidity. Prices and depth of book (top). Size map (bottom).
Другой источник — исследования Parasec, где анализировали глубину и «дыхание» ликвидности на биткоин‑биржах. Их визуализации тоже показали, что стакан — это не плоская таблица, а многослойная структура, где заявки добавляются, исчезают и перестраиваются, создавая паттерны, похожие на биение пульса.
Визуализация высокочастотной торговли в Bitcoin. Источник: parasec.net
Визуализация высокочастотной торговли в Bitcoin. Источник: parasec.net
В моей реализации я пытаюсь сделать так же. Код берет L2 Order Book (стакан глубиной 50) и Trades Stream (обезличенные сделки) и проходит путь от «хаоса массивов» до карты эволюции рынка.
Сначала все события объединяются во временные блоки, чтобы уместить недели данных в шаблон по горизонтали — без потери структуры. Далее строятся две тепловые карты: верхняя показывает абсолютные уровни цен и ликвидности, нижняя — относительное смещение вокруг mid‑price, чтобы видеть деформации книги ордеров независимо от тренда. Яркость пикселей кодирует объём (после логарифмической нормализации), а цвет — насыщенность ликвидности. Сделки накладываются поверх — как тонкая линия и серия точек разных размеров, привязанных к реальным объёмам.
Мой черновик реализации. Большой пример с увеличением есть в репозитории
Временно развернул как сервис у себя. Ссылку публично не буду давать, боюсь что мой сервер просто упадёт, но если вы напиши мне лично, то я сброшу ссылку вам посмотреть. Долго держать включенным сервис не буду - у меня нет идеи создать такую услугу, я лишь хочу посмотреть закономерности для самого себя.
Мой черновик реализации. Все данные которые у меня были - в этом черновике сервиса
Зачем это нужно?
Например для поиска аномалий:
Flash Crashes. Когда цена внезапно проваливается, трейдеры ищут виноватых в свечах или новостях. Но иногда причина банальна: на стороне bid просто исчез слой ликвидности, и рынок провалился в пустоту. Визуализация показывает это мгновенно — пустые коридоры, резкие «дыры» в глубине, которые на обычном графике не видны.
Spoofing. Ложные крупные заявки, которые появляются и исчезают, чтобы напугать участников или двинуть цену в нужную сторону. В стакане это выглядит как рваные полосы «жирных» уровней, которые никогда не исполняются. Понять такую манипуляцию по свечам невозможно, но на тепловой карте она читается моментально. Польза? Видеть то, что скрыто от большинства — а значит принимать решения раньше толпы.
Отличная книга издана на русском на обе эти темы и написана относительно недавно в 2020 году: Flash Crash. История о трейдере‑самоучке, обвалившем финансовый рынок на 1 трлн $ (Лиам Воган).
Отличная книга на русском на обе эти темы — Flash Crash Лиам Воган
Анализ микроструктуры. Стакан показывает, как именно цена проходит путь от уровня к уровню. Когда рынок упирается в крупную «плиту» заявок, визуализация помогает понять: это реальный интерес или просто бутафория? Цена отскакивает от плотных уровней, если там стоит живой спрос, и наоборот — легко «проедает» их, когда объёмы фиктивны. Дисбаланс bid/ask перед импульсом становится заметен как изменение наклона и плотности тепловой карты.
Обучение и Research. Для ML‑инженеров такой инструмент — находка. Прежде чем закармливать модель признаками, полезно глазами увидеть структуру данных: как меняется ликвидность, где возникают аномалии, какие зоны повторяются. Это позволяет строить более осмысленные фичи и проверять гипотезы не в абстракции, а на живой микроструктуре рынка.
Техническая часть
Стек: NumPy и Matplotlib для чисел и генерации PNG, Pillow (PIL) для оптимизации графики и, наконец, OpenSeadragon для работы в браузере. Эта комбинация позволяет эффективно обрабатывать гигабайты потенциальных данных.
Данные хранятся в.npz — это бинарные архивы NumPy, идеальные для хранения огромных многомерных массивов. Структура проста и быстра: A/B — 50 уровней цен Ask/Bid (цены спроса и предложения), vA/vB — соответствующие им объемы. Такая структура, близкая к матрице, максимально эффективна для Data Engineering и скоростного анализа.
Временный сервис работает и с телефона
Пайплайн: от тика до тепловой карты
Биннинг (агрегация). Чтобы стабилизировать визуальное разрешение (ось X = 12 000px) и справиться с хаосом необработанных тиков (событий), мы агрегируем данные в фиксированные временные слоты. Это позволяет уместить неделю биржевой активности в HD карту без потери общей структуры и видимых аномалий.
Математика объемов (np.log1p). Ключевая деталь: логарифмирование объемов. Разница между ритейл‑заявкой и крупным фондом может достигать 4-х порядков. Линейная шкала убивает детали, делая мелкие, но важные намерения невидимыми. Функция np.log1p() сжимает этот разброс, позволяя на одной тепловой карте видеть как «бумажные» ордера, так и реальные ликвидные «плиты».
Генерация и Тайлинг. Мы создаем огромный PNG (до 12 000 пикселей в ширину), который затем Pillow нарезает на пирамиду мелких (256px) тайлов с манифестом.dzi. Это суть Deep Zoom: браузер загружает только видимые плитки, обеспечивая плавный, Google Maps‑подобный скроллинг и масштабирование (через OpenSeadragon) без необходимости загружать весь гигабайтный файл.
Примеры
Акции Газпром GAZP в августе на MOEX (TQBR)
МКПАО «Т‑Технологии» (T) — котировки на MOEX (TQBR) в декабре
ПАО «Татнефть» им. В.Д. Шашина (TATN) — в декабре
Как запустить у себя?
Процесс максимально прост и понятен для любого разработчика:
Клонируйте репозиторий и установите зависимости: git clone ..., затем pip install -r requirements.txt.
Поместите файлы с историей стакана (ваши .npz) в папку npz_data/.
Запустите оркестратор: python main.py (он нарежет данные, создаст Ultra‑HD карты и Deep Zoom тайлы).
Запустите локальный сервер и откройте http://localhost:8000.
Важный дисклеймер: мой код — это «плеер» (визуализатор), который умеет работать с готовым форматом. «Кассета» (исторические данные Московской Биржи) является платной. Скрипт ждет готовые .npz файлы, которые вы должны предоставить самостоятельно. Если нет доступа к платным данным, то можно самостоятельно накопить историю через API брокера — это бесплатно и доступно для частного лица.
Заключение
Мы привыкли смотреть на рынок через свечи — удобную, но упрощённую проекцию сложной динамики. Однако за каждым движением цены скрывается куда более интересный мир микроструктуры: заявки, очереди, исчезающие уровни, вспышки ликвидности, невидимые на обычном графике. Этот визуализатор — это попытка сделать этот скрытый слой таким же доступным, как карты в браузере: приблизить, отдалить, задержать взгляд и увидеть то, что раньше пролетало мимо.
Если вам интересно покопаться внутри рынка — забирайте репозиторий, улучшайте, экспериментируйте, дополняйте. Чем больше мы делаем таких инструментов, тем меньше рынок остаётся «чёрным ящиком» и тем больше у частных инвесторов появляется возможностей понимать происходящее, а не гадать.
Спасибо, что дочитали до конца. Если хотите увидеть живые примеры или пообщаться — пишите в Telegram. Буду рад обсудить, подсказать и услышать ваши идеи.