Привет, коллеги!
Хочу поделиться историей о том, как мы столкнулись с типичной проблемой в количественных финансах и что из этого вышло.
Проблема, знакомая каждому, кто строил риск-моделиПредставьте: у вас портфель из тысяч инструментов. Вы считаете Value-at-Risk (VaR), ожидаемые потери (Expected Shortfall), греки для опционов, скоринговые модели. Данные обновляются постоянно — новые цены, ставки, волатильности.
Как это обычно работает?
Либо вы пересчитываете всё с нуля каждый раз (дорого, медленно, особенно если инструментов много)
Либо вы строите сложные триггеры и кэши, которые потом отлаживаете месяцами
В обоих случаях вы либо жертвуете скоростью, либо тратите уйму времени разработчиков.
Как мы пытались решить эту проблемуМы начали с простого вопроса: «А что, если пересчитывать только то, что реально изменилось?»
Звучит очевидно, но реализация оказалась нетривиальной. Когда у вас многослойная модель (например: цены → греки по инструментам → агрегация по секторам → портфельные метрики → общебанковские лимиты), одно изменение в цене может затронуть десятки тысяч зависимых значений.
Мы перепробовали разные подходы:
Самописные кэши с инвалидацией — получили спагетти-код
Потоковые движки вроде Apache Flink — мощно, но тяжеловесно и не оптимизировано под иерархии
Реляционные БД с материализованными представлениями — медленно для real-time
В результате родился PhiFlow — библиотека для .NET, которая делает ровно одну вещь, но делает её хорошо: инкрементально пересчитывает иерархические модели и даёт мгновенные ответы на аналитические запросы.
Представьте, что ваша риск-модель — это многослойная сеть. Когда меняется цена одного инструмента, PhiFlow определяет минимальную область влияния этого изменения (конус влияния) и пересчитывает только те узлы, которые действительно зависят от этого инструмента.
Остальная часть модели остаётся нетронутой.
Мы прогнали библиотеку через бенчмарки на реальных сценариях. Вот что получилось:
| Сценарий | Обычный подход (полный пересчёт) | PhiFlow (инкрементальный) | Ускорение |
|---|---|---|---|
| 1 изменение, сложные вычисления (KWork=50) | 10.7 секунды | 0.195 секунды | 55x |
| 4 изменения, сложные вычисления | 10.8 секунды | 0.75 секунды | 14x |
| 1 изменение, лёгкие вычисления (KWork=10) | 1.8 секунды | 0.035 секунды | 51x |
| Запросы Top-K (50 наибольших значений) | 1.74 секунды | 0.034 секунды | 51x |
| Подсчёт количества элементов > порога | 1.83 секунды | 0.035 секунды | 52x |
Другими словами: то, что раньше занимало секунды или десятки секунд, теперь занимает миллисекунды.
Где это может пригодиться трейдерам и аналитикамПредставьте, что вы мониторите VaR портфеля. Каждое изменение цены требует пересчёта. С PhiFlow это происходит мгновенно, а не раз в минуту.
Сценарий:
Слой 0: цены инструментов, ставки, волатильности
Слой 1: греки по каждому инструменту
Слой 2: агрегация по секторам (например, нефтегаз, финансы)
Слой 3: портфельные метрики (VaR, ES)
Слой 4: контроль лимитов и алерты
При изменении цены фьючерса на Brent обновляются только:
сам инструмент (слой 0)
его греки (слой 1)
сектор «нефтегаз» (слой 2)
портфельные метрики (слой 3)
проверка лимитов (слой 4)
Всё остальное (финансовый сектор, технологический и т.д.) не трогается.
Вы строите торговые сигналы на основе иерархии: тики → свечи → признаки → сигналы → решения.
Каждый новый тик запускает пересчёт. С PhiFlow это происходит достаточно быстро, чтобы использовать в HFT-системах с субмиллисекундными задержками.
Транзакция → пользователь → счёт → кластер → флаг риска.
При поступлении новой транзакции вы мгновенно получаете обновлённый риск-скор и можете принимать решение «пропустить/блокировать» в реальном времени.
Запускаете Монте-Карло? Отлично. Каждая симуляция меняет входные параметры. Вместо полного пересчёта каждой симуляции с нуля, PhiFlow обновляет только то, что изменилось относительно предыдущей итерации.
Почему это лучше, чем писать самому?Мы тоже начинали с попытки написать свой велосипед. Быстро поняли, что:
Корректность — легко ошибиться в логике инвалидации и получить неконсистентные данные
Производительность — наивная реализация может оказаться медленнее полного пересчёта
Индексация запросов — если вы ещё и хотите быстро отвечать на вопросы вроде «сколько элементов превысило порог», нужно строить индексы и поддерживать их в актуальном состоянии
PhiFlow даёт готовое, проверенное решение с гарантированной корректностью.
Технические детали для интересующихсяДискретный домен: все значения в ограниченном диапазоне (0..N-1) — это позволяет использовать точные структуры данных, а не вероятностные
Fenwick tree (дерево Фенвика) для быстрых подсчётов количества элементов больше порога
Гистограммы для Top-K запросов (сумма K наибольших значений)
Интервальное представление затронутых узлов — оптимально для кэша процессора
Никаких аллокаций на горячем пути — подходит для 24/7 сервисов с высокими требованиями к стабильности задержек
Библиотека доступна на NuGet:
bashdotnet add package PhiFlow
Есть бесплатная Community-версия для разработки и тестирования. Этого достаточно, чтобы поиграться и понять, подходит ли подход под ваши задачи.
Для продакшна — коммерческая лицензия от $500/мес (Startup) до enterprise-тарифов.
Буду рад обратной связи и идеям! Если хотите покопаться в коде или задать вопросы — пишите в телеграм @vipvodu.
PhiFlow — инкрементальные вычисления для финансовых приложений. Пересчёт рисков за миллисекунды вместо минут.
Добрый день!
Есть ли где‑то в открытом доступе (или может здесь добавите) отработанные примеры использования этой библиотеки с наглядной демонстрацией возможностей? Интересно посмотреть живые кейсы и выгоду применения, чтобы не «ковырять» всё с нуля и лучше понять, в каких задачах это может пригодиться.
Я тебя не упрекаю за попытку оседлать коммерцию через вайбкодинг. Но попробуй подумать на перед. Один ли ты знаешь про вайбкодинг. А если не один, насколько твоя библиотека в целом уместа в мире вайбкодинга.