Хабрахабр

«Предложили ознакомиться с расчетами одного показателя, а там два листа с интегралами и вторыми производными»

Мы поговорим о том, чем занимаются финансовые математики, откуда берутся данные в банках, как обрабатываются и оптимизируются. Это интервью с Антоном Батяевым (batiaev) из Технологического Центра Дойче Банка. О сложности попадания в финансовую сферу, торговле на бирже и общей необходимости в банках.

— Представься, пожалуйста: расскажи, кто ты, чем занимаешься.

Я перешел в ТехЦентр Дойче Банка в начале января этого года и сейчас занимаюсь разработкой серверной части на проекте, который считает различного рода риски по финансовым инструментам для множества разных трейдеров по всему миру и иных команд, которым требуются эти данные.

Также мы работаем с гридом на десятки тысяч CPU, используем различные кастомные проекты, оптимизируем работу с protobuf, реализуем расчеты в финансовой математике, В рамках проекта построена довольно обширная инфраструктура, которая использует много популярных стандартных фреймворков, нереляционные базы данных, работает с большими данными на Kafka.

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

Ты сказал, что в ТехЦентре вы занимаетесь расчетами для глобальной банковской платформы. — Давай по порядку. А что вообще можно считать в банке?

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

Она рассчитывается по множеству различных формул. Если говорить о деривативах (производных финансовых инструментах), там цена — размер премии, которую надо уплатить за этот инструмент. Есть формула Black-Scholes, которая оценивает стоимость опционов — это функция, которая зависит от функции текущей котировки, базового актива, волатильности, времени до экспирации и множества других факторов.

У отдела или компании есть набор сделок, производных финансовых инструментов в портфеле, и нужно посчитать, сколько они сейчас стоят. Есть модели, которые позволяют рассчитать стоимость портфеля трейдера. По отдельности может быть одна цена, а в совокупности — они могут как-то коррелировать, давать скидки и так далее. В отдельности может быть одна цена, а в совокупности они могут как-то коррелировать, давать скидки и так далее. Это подходит, например, для нелинейных активов типа опционов, но не обязательно верно для всех типов деривативов. Например, синтетические позиции: как из опционов собрать позицию, эквивалентную фьючерсной. Например, котировка одной или нескольких валютных пар. Оценка строится на основании котировки базового актива, на котором построен дериватив. Деривативы могут быть построены на разных базовых активах: для валютных базовыми активами будут евро, доллар и так далее; для товарных деривативов – нефть, золото, пшеница; для спотовых – различные акции и облигации.

Или что случится, если доллар будет стоить по отношению к одной или всем другим валютам не 60, а 100 рублей. Помимо оценки деривативов также считаются риски — что случится, если цены на рынке будет штормить сильнее (изменится волатильность). Что произойдет с конкретным инструментом, портфелем.

Для этого строим матрицу всех возможных изменений, которая показывает, что есть сейчас, что произойдет завтра и что будет, если случится кризис на рынке. Нужно рассчитывать это в режиме реального времени, а также аппроксимировать текущее состояние портфеля на различные неблагоприятные исходы движения цены по каждой из валют, изменению волатильности на рынке.

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

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

Ты говорил про кучу всяких алгоритмов анализа, откуда эти алгоритмы берутся? — Прежде чем мы перейдем к инфраструктурной части, хочется поспрашивать о том, что ты уже рассказал. Это какие-то книжные знания или ваши наработки?

Во-первых, берутся общеизвестные формулы, алгоритмы, придуманные математиками. Тут есть несколько моментов. Но, помимо этого, есть свои внутренние доработки: в частности, используем другие законы распределения цен, подкручиваем коэффициенты в этих формулах. Например, общепринятая модель ценообразования опционов — формула Блэка-Шоулза. Формула кривой распределения цен, сделок и других показателей может сильно отличаться.

Например, разработчики могут вместо того, чтобы рассчитывать показатели в каждой точке, считать ключевые значения и заниматься аппроксимацией, которая будет стоить в 20 раз меньше компьютерного времени, но при этом даст допустимую и достаточную точность. Если говорить про оптимизации, это уже внутренние доработки.

Все данные постоянно меняются, и нам это важно не только для отчетности, а также для того, чтобы давать трейдерам актуальную картину состояния рынка.

Какой у вас размер команды, и как вы передаете знания между собой? — Это довольно сложная информация, и её, наверное, довольно сложно передать от человека к человеку.

Это несколько команд, которые занимаются теми или иными кусочками функциональности: UI, бэкенд, инфраструктура, финансовая математика. На нашем проекте в Москве работает 35 человек. Но помимо этих людей есть еще столько же человек, которые занимаются связанными с нашим проектом системами. Каждая такая команда обладает глубокой экспертизой в функционале конкретного модуля.

Примеры использования функциональности можно найти в тестах. Вся информация о нашем проекте описана аналитиками на Confluence, также она содержится в описаниях задач в JIRA, где есть ссылки на стандартные механизмы и публичные формулы. Ну и человеческое общение никто не отменял.

Какие-то важные ученые? — Финансовые математики: сколько их и кто это такие?

Чаще всего у них PhD в области финансов или математики. Да, в основном это специалисты (кванты), которые сидят в Лондоне и строят финансовые модели того, как работает рынок. Они знают, как работает рынок, что необходимо трейдерам, и могут придумать какую-то математическую модель, которая описывает состояние рынка, алгоритмы расчетов рисков и корректной оценки деривативов.

Например, мой коллега Александр написал статью на Хабре, где уже упоминал опыт работы с квантом.

Как это общение происходит? — А обычные разработчики могут с ними общаться? Ведь у математики и обычной разработки миры совсем разные.

Могут общаться и общаются: понятно, что какие-то верхнеуровневые бизнесовые задачи и концепции обсуждаются с лидами, но в рамках конкретных расчетов рисков или иных показателей происходит прямое общение разработчика с трейдером или квантом, который строил эту модель.

Поэтому разработчики могут предлагать изменения в модели, чтобы она ложилась на текущую архитектуру приложения. Но на самом деле это обоюдный процесс взаимодействия, поскольку не всегда теоретический алгоритм реализуем на практике.

Способов взаимодействия много — тот же скайп, телефон, все стандартные инструменты связи.

Это роботы или есть что-то для трейдеров, которые техническим анализом занимаются — графики или что-то ещё такое? — Софт, который получается в результате, — автоматический?

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

С одной стороны спектра, как я понимаю, какие-то микросекунды, а с другой — анализ больших данных, которые могут неделями идти. — Другая метрика — частота анализа данных, как часто вы это делаете?

А в случае если мы рассчитываем стоимость портфелей, то обновления происходят раз в секунду, чтобы человеческий взгляд успевал это воспринимать. В зависимости от сложности и важности показателей, это могут быть live-показатели, которые пересчитываются на каждый тик, и тогда расчет идет на миллисекунды.

Общий механизм выглядит следующим образом: ты считаешь все новые сделки в рамках определенного цикла, потом делаешь тяжелую задачу на гриде на пересчет показателей по всей совокупности сделок на текущем состоянии рынка. Если описывать долгие расчеты (например, какие-то сложные риски), данные по которым нужны в течение дня, то задачи отправляются на грид, считается сценарий изменения котировок валют.

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

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

Там, где пинг до грида дольше, чем время самого расчета, мы будем делать это на бэкенде, где уже развернут мини-кластер для таких маленьких задач. В общем, задача о рюкзаке и прочие оптимизации.

Насколько я понимаю, в зависимости от объема задач применяются разные методы оптимизации. — Можно это как-то уложить в какую-то структуру? Расскажи, какие есть области задач и какие методы там используются для ускорения и оптимизации. На маленьких задачах имеет смысл оптимизировать JIT-компилятор, а на больших что-то другое.

В этом случае оптимизация будет заключаться в группировке сделок в пачки таким образом, чтобы в рамках одной пачки были сделки на один тип портфеля или одну валюту. Пример большой задачи — расчет всех финансовых инструментов и рисков при изменении котировок каждой из валют на 1-2-3-10%.

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

Допустим есть две пары «рубль-доллар» и «рубль-евро». Ещё пример оптимизации — на этот раз с валютными парами. По факту это одно и то же. В первой паре можно представить, что рубль падает, а можно — что доллар растет. Соответственно, разные на первый взгляд пары мы можем считать в одной пачке, исходя из того, что рубль меняется в обоих случаях. То же самое и с парой «рубль-евро».

Вроде бы поменяли одну валюту (в нашем примере — рубль), а на деле посчитали риски по разнородным активам. Уменьшается количество расчетов и ускоряется результат.

— А можно решить задачу в лоб и раскатать её на огромный-огромный кластер?

Кластер не резиновый, несмотря на десятки тысяч CPU, которые там сейчас есть. Такой кластер есть, но он уже загружен множеством расчетов.

— А с точки зрения софта, In-Memory DataGrid или Hadoop?

В плане укладки данных понятно, что гонять JSON-ы, мягко говоря, неэффективно. Да, есть и Hadoop, и Kafka для процессинга всего этого, и база данных ClickHouse для оптимизации работы с большими данными. Нам важно не просто уложить бинарные данные, но при этом сделать это максимально плотно, используя словари. В связи с этим появляются моменты оптимизации работы с Protobuf.

За счёт этой оптимизации со словарями коллега сэкономил 30% занимаемой памяти. В них мы будем хранить, например, однотипные для всех сделок спецификации контрактов.

— Это словари лежат на конкретных нодах и дублируются или находятся в центральной базе?

В основном в центральной базе. По-разному. Её хочется иметь максимально компактную, чтобы не тащить множество данных, так как интернет-каналы не резиновые. А есть словари, которые передаешь на грид вместе с пачкой расчетов.

Ты отправляешь на грид задачу расчета со всей необходимой для нее информацией, которую упаковываешь в словари, чтобы избежать дубликатов. Как это работает. Это экономит сетевой трафик и уменьшает задержки в расчетах. Внутри уже будет весь контент, и не нужно ходить в дополнительные хранилища.

И подход с единой базой данных не прокатит? — Насколько я знаю, в банках есть анализ на исторических данных, который представляет собой одну огромную пачку данных на гигабайты-терабайты. Ты можешь по ключу положить 2 ТБ, но это же нехорошо.

У тебя будут лежать локальные кэши по странам, разложенные по биржевой информации, потому что переслать информацию о всех сделках из Нью-Йорка в Сингапур ресурсоемко. Да, такие моменты решаются порционированием. Аналогичная ситуация с котировками — нужно строить роутинг и определять, что это за сделка, к какому региону принадлежит, чтобы понять, где лежат кэши, отправлять её на нужные хранилища и базы данных и не гонять лишний раз данные. Понятно, что тут разделение по страновому признаку логично: например, сделки в США будут размещаться в американских датацентрах.

— А бывает так, что нужно джойнить данные из разных регионов?

Понятно, что мы не будем выкачивать терабайты данных из всех регионов, чтобы получить агрегированные результаты. Да, бывает, и это сложная задача. Скорее всего в каждом регионе ты посчитаешь локальный агрегат этого региона и потом соберешь уже все эти результаты для получения суммарных данных.

И как их обрабатывать? — Скорее всего, есть внешние данные, например, биржевая история. Зеркалируете себе внутрь, или есть способы их обработки?

Те данные, которые необходимы, мы сохраняем на внутренних хранилищах, но часть вещей можно перезапросить у поставщика данных. Есть протоколы и подключения к стандартным провайдерам данных: Reuters, Bloomberg, которые предоставляют биржевую информацию. Опять же по регионам, чтобы не гонять трафик.

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

Если на запись, не страшно ворочать такими объемами? — А данные на чтение или чтение/запись?

В основном расчеты для внутренних нужд: риски, стоимость портфелей и так далее. В основном, на чтение, запись идет во время фиксации информации о сделках и иной информации, требуемой регуляторами. Это внутренняя кухня, ты ворочаешь данные какого-то региона или дата-центра, не отправляя вовне.

Всё, конец? — Если от Луны отломится кусок и прилетит в датацентр, то что произойдет?

Понятно, что в рамках региона данные не лежат на одном жестком диске в одном датацентре. Данные в датацентрах зеркалируются. Всё копируется в онлайне: есть поток данных в обе стороны, ты считаешь с ближайшего зеркала, а на запись синхронизируешься, чтобы обеспечить консистентность. Иначе как в той байке, любая уборщица случайно могла бы вырубить сервер.

Если он увидит пересчет не сейчас, а на 2 секунды позже и с другого источника, грустно, но жить можно. Но, как правило, на запись доступно куда меньше информации, потому что надо отображать пользователю. Понятно, что данные, которые нужны для регуляторов, внешних маркетеров и участников рынка, дублируется и синхронизируется в нескольких источниках, чтобы ничего не потерять.

Насколько понимаю, каждый источник имеет свой формат, и мгновенно конвертировать их — не самая лучшая идея. — Вопрос про подготовку данных. Вы их как-то предварительно подготавливаете для расчетов?

Понятно, что удобнее работать с однотипными данными, но это выливается в необходимость конвертировать их. Есть внутренний единый формат. Они формируют и обогащают данные в наш единый формат. Тут есть потоки данных и команды, которые отвечают за биржевую информацию, подключение к поставщикам. Благодаря этому реже случается необходимость ходить в различные хранилища и формировать стандартную структуру. Для решения проблем с производительностью будет два потока данных, один из них — это быстрый цикл, который будет отдавать информацию, поступающую из биржевого потока данных. На ней можно посчитать показатели, необходимые в режиме реального времени.

На нем проводятся все более медленные расчеты, которые требуют кучу дополнительной информации, полей и всего остального. И есть более медленный цикл, который обрабатывает тот же поток, но со всем необходимым набором полей, в нашем формате.

Ты всегда знаешь, какую область базы данных затронут «тяжелые» расчёты? — Как это выглядит с точки зрения разработчика?

На быстрых событиях ты считаешь показатели, которые пересчитываются в онлайне, быстро. Тебе прилетает какое-то событие, поля в котором могут быть заполнены как на 100%, так и лишь частично. Это если не углубляться, так как всё зависит от специфики задач. На долгом и более медленном цикле с полным набором данных, ты пересчитываешь задачи, которые требуют всех показателей.

HDD, SSD, RAM, целиком и полностью в RAM? — А данные хранятся на чем?

Мы работаем с большими хипами на бэкендах, которые потребляют и хранят у себя данные либо в стандартных структурах в Java, либо на каких-то In-Memory Data Grid ­— в зависимости от того, насколько быстро и насколько близкие данные тебе нужны. В основном в памяти. Но то, что надо или может понадобиться для расчетов, будет подгружаться в кэш, в память. Понятно, что исторические данные уже прошедших дней будут храниться на SSD и дисках.

— Возможно ли что-то делать не кэшируя, а с потерей информации, используя неточные вычисления?

Я немного упоминал, что иногда нужно посчитать риск на цепочке изменения какого-то актива от 0 до 100%, как изменились показатели. Да. Ты строишь ключевые точки и занимаешься аппроксимацией. График распределения строится по процентам, согласно формуле или линейной зависимости. Получаются приближенные результаты, которые не будут совпадать с реальным значением на 100%, если бы мы считали в каждой конкретной точке графика, но будут достаточны для работы с этими данными.

Ты вычисляешь либо двигаясь с редким шагом, либо выбрав несколько конкретных точек, а остальное интерполируешь. Этот подход часто используется, потому что позволяет, например, не делать все расчеты при изменении стоимости каждой валюты по отношению ко всем остальным валютам, с шагом в одну копейку. Значения по точности будут достаточные.

— Это всегда большие хипы в Java или всё лежит на оффхипе?

В основном лежит на хипе.

— Как тогда вы боретесь со сборкой мусора?

Например, можно попробовать использовать Shenandoah. Помимо стандартного мониторинга аллокаций и частоты срабатывания сборщика мусора, ты начинаешь подкручивать какие-то вещи вроде huge pages, занимаешься рядом моментов вроде выбора правильного сборщика мусора и так далее. Часть компонентов строится и тюнится из расчёта на отсутствие full GC как явления.

Это итеративный процесс: каждый день вживую собираешь flame graph, смотришь, кто и где потребляет ресурсы, смотришь частоту аллокаций и на что они выпадают, и начинаешь заниматься переписыванием горячих алгоритмов в коде на более оптимальные либо оптимизировать расчет в целом.

— А чем вы собираете метрики, чем строите flame graph?

Есть механизмы для заворачивания событий в ELK-стек, есть логи со сборкой метрик по GC-паузам и показателям потребления памяти, есть ручные или полуавтоматические запросы по выгрузке состояния хипа, показателей дампов и их обработка. В инструментарии ничего фантастического нет, это либо какие-то написанные нами Java-агенты, которые подключаются и собирают информацию, либо стандартные средства профилирования и другие инструменты. Коллеги написали статью на Хабре о том, как разбираться с мусором на 150 ГБ и что из этого получается. Снять хип на 150 ГБ и обработать — задача, которая требует определенных ухищрений. Я глубоко не копал, поэтому в деталях не расскажу.

— Какая у вас Java и какие GC используются?

Сравниваем производительность. Java 8, сейчас тестируется 11-я на некоторых бэкендах. В качестве сборщика мусора используется, в основном, G1.

— Старых коллекторов нет вообще?

Ну и подкручиваем их ключами JVM. Да, используем новые.

Можно ли как-то протестировать оптимизации, и можно ли это делать автоматически? — Как я понял, большая часть работы связана с оптимизацией, перформансом.

У нас есть свой тестовый фреймворк, который позволяет подключаться к тестовым контурам и измерять расчеты каждого показателя. Да, можно. Можно замерить скорость на проде и юате (UAT — user acceptance testing) — посмотреть, не просела ли производительность. У нас выделенная команда занимается его созданием. Если на проде работает 2 минуты, а на юате — 3 минуты, нужно понять, почему так происходит. Можно проверить корректность математики, частоту запросов и время их выполнения, можно проверить работу с гридом.

Производится подключение к двум контурам, измеряются показатели, и дальше можно кидать кастомные запросы, сравнивать результаты по времени ответа и задержки на разных версиях прода. Процедура тестирования запускается автоматически. Можно сравнивать, насколько чаще стала срабатывать сборка мусора и так далее.

Или это всё микробенчмарки? — Ты рассказал про большое количество компонентов, есть какие-то тесты, которые захватывают всю систему, глобальные интеграционные тесты?

Она прогоняется по всей системе в целом: можно узнать размер хипа, время срабатывания GC, размер live set в памяти и прочее. Это комплексная инфраструктурная штука. Ключевая особенность этой системы — возможность отловить даже малейшие изменения в числах на всем пути расчетов. Какие-то комплексные вещи. Мы можем быть уверены, что не внесли неожиданных изменений нигде внутри всей этой огромной системы. По сути, это наша последняя линия обороны.

Посмотреть, как быстро и часто они считаются. Данные о производительности можно детализировать по определенной бизнес-функциональности, каким-то показателям. В этом JSON находятся изменившиеся данные и показатели производительности. Можно создавать кастомные запросы, запускать их на разных копиях и выдавать JSON diff.

Например, подключение к разным окружениям, поддержку визуализации и другой функциональности. Есть отдельная команда, которая всё это разрабатывает. Это внутренняя разработка.

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

Хотя с хипом под 100 ГБ они не очень «микро», но тем не менее. Сделать так не получится, потому что подобными изменениями не затрагиваются все приложения сразу, ведь у нас используется модульная система с микросервисами. Вряд ли ты сможешь повлиять на всю систему целиком и кардинально сломаешь производительность. Они могут быть чуть меньше или больше по размеру, в зависимости от решаемых задач.

И просадку в производительности за счет того, что тестовый фреймворк покрывает не только корректную часть расчетов, но и работу с производительностью, памятью и всем остальным, можно будет заметить. Ты закоммитил в master, по нажатию кнопки запускается развертывание на боевых серверах, всё это разворачивается и прогоняется через регрессионное тестирование, и далее проблемы могут выявляться при ручном и других видах тестирования. В инвестиционной деятельности скорость расчетов и принятия на их базе торговых решений имеет существенную роль.

Ты понимаешь, какой код приводит к проблемам, где произошла просадка производительности и всё остальное. Даже по флеймграфам, которые выгружаются раз в день по итогам, ты заметишь, что вчера был один результат, а сегодня совершенно иной. Я уж и не говорю про стандартные тесты и CI, которые решат явные логические баги.

— А что с логическими багами на уровне финансовой математики?

Сам — если хватает экспертизы, или с аналитиками и квантами, которые придумывали математику. Ты за счет тестового фреймворка сверяешь расхождения в показателях. Если кто-то ошибся, это нужно исправлять и перепроверять. Вы разбираетесь, корректны ли изменения, почему они такие, прогоняете на реальных и синтетических сделках, чтобы проверить результат.

Я подготавливаю запросы к этим условным калькуляторам, отправляю их туда, получаю ответы по рискам, стоимости портфеля и показателям, делаю какие-то преобразования. — Напомни, чем ты в этой огромной системе занимаешься.
Я занимаюсь бэкендом — системой, которую использует сервис, реализующий саму математику.

Это такой бэкенд, который строит данные расчетов, ходит в систему, непосредственно обсчитывающую всю самую жесткую математику, и отправляет результаты на UI. Условно говоря, в одном месте нужно считать стоимость риска по какому-то инструменту, а в другом месте — делать на основе какого-то одного базового риска его вариации, то есть расширять этот результат на варианты и отправлять на UI, чтобы отобразить данные.

Это чисто ваши собственные наработки или можно работать и с «общечеловеческими» вещами вроде Spring? — А что там за технологии используются?

Ещё всякие UI на React, взаимосвязи через gRPC со внешними системами, чтобы отдавать им данные. Там стандартные вещи типа Spring, Java, MongoDB и Protobuf, различные стандартные системы для dependency injection.

У вас есть полномасштабная реляционная база данных или что-нибудь такое? — Я услышал Mongo, но не услышал Oracle.

На бэкенды прилетает обновление биржевой информации в виде отдельных сообщений и событий. Да, есть, но используется в другом формате. Здесь нет каких-то более высокоуровневых библиотек вроде SpringData и всего остального, только чистые запросы к JDBC. И если ты ходишь в БД за какими-то данными за прошлые периоды, то соединяешься через стандартный JDBC драйвер. Это вопрос производительности, компактности запросов и всего остального, что трудно достигнуть, используя обычные фреймворки для высокоуровневых задач.

— А вы пробовали где-нибудь использовать CQRS?

Пробовали, есть, но это в основном биржевая информация.

Программист, математик… — А изначально ты на кого учился?

Я безопасник.

Если однажды занялся безопасностью, с этого тяжело слезть. — А как ты к этому пришел?

Я ей обучался, но по большей части с первого курса кодил, устроившись С++ разработчиком. Диплом безопасника не говорит, что я занимался только безопасностью. Писал стандартные бэкенды и бизнес-автоматизацию, работал в брокерской сфере в одной финансовой корпорации. Писал для касс со встроенным GNU/Linux, а потом перешел на Java. Был простым разработчиком, лидом, архитектором, начальником отдела. Реализовывал расчеты деривативов, расчеты рисков. Многое успел поделать.

Я здесь с января, а до этого около двух лет занимался финансовой математикой.

— Как тебя так бросило из математики в простую разработку?

Даже если ты не занимаешься непосредственно реализацией алгоритма, рассчитывающего оценку дериватива, какого-то риска или иного показателя, ты все равно занимаешься какими-то расчетами. На самом деле, трудно назвать финансовую математику «простой» разработкой. Иными словами, то, что я не затрагиваю сервисы, которые считают основную математику, еще не значит, что я вообще не занимаюсь расчетами. Тут не только чистый бэкенд, я ранее уже говорил, что на бэкендах есть мини-кластеры для «простых» быстрых расчетов.

— Что в этой работе интересного и клевого?

Меня
лично очень сильно это вдохновляет: финансовая математика, торговля, биржа и все такое. Во-первых, то, что ты можешь разбираться в финансах. Понятно, что ты на бэкенде не считаешь сложную математику, но так или иначе, стандартные финансовые вещи всё равно рассчитываешь сам. Мне очень нравится рассчитывать показатели. Никаких особых сложностей с этим нет, но это интересно.

Это перформанс-штуки по оптимизации вычислений. Это и большие объемы данных, ведь нечасто приходится в бэкенде работать с хипом по 150 гигабайт, который надо по байтам уложить. Увлекательно погружаться в математику бизнеса, в сущность процессов.

Как нагрузить грид и посчитать предагрегаты данных, чтобы не загружать терабайт данных из БД, а получить накапливаемый предагрегат, который отправляется одним легким запросом — это весьма интересно. Модели, потоки данных, реактивные стримы, обработка укладки данных. Понимаешь, как всё работает в банке, зачем это нужно и какие масштабы за всем этим стоят.

— А есть какие-то интересные вещи, которые обычные люди или разработчики не понимают, и ими можно поделиться, чтобы взорвать людям мозг?

Торговать на бирже, особенно какими-то деривативами, означает не просто взять цену с торгового терминала и выставить заявку на какой-то объем. Первое, что приходит на ум — это описание идеи и сложность задачи финансовых расчетов. Ты должен провести расчеты, которые могут представлять из себя формулы на два листа А4, исписанные интегралами. Необходимо определить, является ли цена правильной и актуальной.

Однажды мне предложили ознакомиться с расчетами одного показателя — а там два листа с интегралами и вторыми производными. Есть небольшая история из тех времён, когда я только пришел в эту сферу и начал что-то программировать. И вот тогда ты начинаешь понимать, зачем вообще в универе преподавали высшую математику и где она может пригодиться.

А тут ты видишь, что в реальной жизни действительно используются все эти показатели. С университетской программой проблема в том, что ты не понимаешь, зачем эти знания в реальной жизни нужны.

— Если какой-нибудь волк-одиночка решит потягаться во всей этой финансовой математике с банком, насколько тяжело ему придется?

Одно дело — повторить торговые алгоритмы с определенными ограничениями, и совсем другое дело — торговать на том же уровне, на котором торгует банк. Смотря что понимать под фразой «потягаться в финансовой математике».

Но торговать профессионально на том же уровне, что и банк, обычный человек не сможет. Обычный волк-одиночка может придумать какую-то торговую стратегию, подключиться к конкретной бирже, реализовать прайсинг публично торгуемых деривативов и возможно в чем-то даже оказаться быстрее банка.

Вдобавок, профессиональная торговля деривативами без использования безрисковой ставки невозможна, и зачастую даже средние банки не могут иметь доступ к ней. Банки торгуют на межбанковском рынке, куда просто так не попасть. Даже миллиардные хедж-фонды используют банки как посредников, чтобы избежать необходимости заключать соглашения со всеми участниками сделок. Поэтому инвестиционные банки — это всегда крупнейшие банки. Это такой прокси, в бизнес-смысле.

Если одиночка их перейдет, он уже точно будет не одиночкой, а какой-то организацией (инвестиционным или хедж-фондом, или чем-то подобным). Так что да, прийти поторговать одиночка сможет, но после некоторых объемов начинаются другие правила.

— В чём именно может помочь банк?

Ты можешь не уследить за рисками, и здесь банк дает возможность оценить финансовые показатели и результаты. Банк предоставляет ряд дополнительных вещей. Ты можешь начать торговать, но у тебя нет огромной базы знаний и опыта по историческим данным, показателям и ликвидности.

Нужна подушка ликвидности денежных средств, и если ты торгуешь через организацию — у них есть резервы, которые могут тебе это позволить. Когда ты — небольшой участник, который может торговать, могут возникнуть проблемы, если захочешь сделать что-то глобальное.

Опять же, контроль рисков и удобство: если ты будешь делать более сложную систему, то сам физически её не построишь из-за больших объемов данных, на обработку которых потребуются мощные сервера с кучей железа. Всё это ты не сможешь обеспечить своими деньгами.

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

Какие требования к такому человеку? — А если человек просто хочет заняться финансовой математикой и разработкой, он может просто пойти к вам на работу?

Нужно понимать механизмы вроде dependency injection, алгоритмы, стандартные коллекции, оптимизации — что будет работать быстрее, а что медленнее. Если ты хочешь разобраться и попробовать поучаствовать в написании подобных систем, понятно, у тебя должен быть сильный бэкграунд разработки на Java. Нужно решать сложные задачи и иметь аналитический склад ума. Как оптимально решить задачу формирования тех или иных кэшей, агрегатов и всего прочего. Пример задачи: у тебя есть набор данных, и необходимо за минимальный оверхед по памяти и времени получить какой-то агрегат.

Если начнешь параллелить вычисления, важно понимать, что будет вызывать установку барьеров, как правильно делать синхронизацию, где будет возникать happens-before. Очень важно заботиться о многопоточности, потому что будешь упираться в проблемы с производительностью. Нужно решать, в каком порядке будут запускаться вычисления, как использовать нестандартные вещи для большей и более плотной укладки.

Вроде не очень страшно, но на больших объемах данных массовый боксинг и анбоксинг будет заметен, память будет использоваться напрасно. Как вы знаете, такие штуки как IntStream#distinct подразумевают оборачивание примитивов в Java-типы и впоследствии — обратную операцию. А чтобы это вовремя заметить, нужно уметь пользоваться инструментами для оценки перформанса, сбора метрик и разбираться в других стандартных вещах. Нужно понимать кишки самой Java, ведь на мелочах вроде боксинга можно породить кучу дополнительных аллокаций, которые тебе не нужны.

— А надо ли знать банковскую специфику?

Все мы понимаем, что те люди, кто знает банковскую специфику, уже работают в банках. Да нет, в принципе. В самом начале можно изучить документы по общим моментам: что такое фьючерс, что такое опцион, чем они отличаются, какие есть риски. Когда приходишь из другой сферы, ты скорее всего её не знаешь. И ты просто погружаешься и начинаешь разбираться в бизнес-специфике.

Вначале ты можешь просто реализовывать функциональность, которая не привязана к определенной бизнес-специфике, но постепенно изучаешь более сложные и привязанные к предметной области вещи. Но тем не менее, она важна. Что здесь, что на прошлом месте работы (когда я, будучи начальником отдела, принимал на работу сотрудников) — замечаешь, что, если из десяти людей хотя бы один понимает, что такое фьючерс, это уже хорошо.

Это само получается, когда погружаешься в эту среду, читаешь документы и разбираешься. Если у тебя есть знания алгоритмов, многопоточности и Java в целом, то изучить бизнес-специфику не составит особого труда.

Это вообще реально? — Как вы собираетесь проверять такие глубокие знания Java на собеседовании?

Но есть стандартные задачи на логику, алгоритмы, понимание внутренних структур. Понятно, что их, скорее всего, не проверишь. Например, задание на реализацию кэша в очереди, которое даст понимание, разбирается ли кандидат в многопоточности — гонках, дедлоках и всём остальном. Это и тестовое задание, и whiteboard coding. Таким образом, решая одну общую задачу, можно пробежаться по моментам из разной специфики. По ходу дела можно задавать вопросы про то, сколько это потребляет памяти, почему TreeMap, а не HashMap. Тут, скорее, практика, по которой вычисляются определенные нюансы.

— Как думаешь, что нужно сделать, чтобы стать лучше как программист?

Кодить и смотреть, какие есть технологии и алгоритмы, какие новые языки, решать алгоритмические задачки. Развиваться! Если ты много решал задачи на алгоритмы, то сможешь найти что-то подобное из прошлых задач в новой незнакомой. По сути, многое зависит от опыта. Очень пригодится умение гуглить и находить решения на StackOverflow. Нужно развивать мышление, умение быстро находить ответы. Если не знаешь что-то, но знаешь, где это найти — это уже путь к успеху.

Приходят новые паттерны, но остаются и какие-то шаблоны, которые используют все. Языки меняются, технологии и фреймворки преобразуются. Сидеть в коконе и не понимать, что сейчас event sourcing, в каком-то смысле, постепенно захватывает мир — странно. Java-конференции без докладов про Reactive Streams и разговоров о Kotlin уже не проходят.

Например, книги Кнута до сих пор актуальны. Нужно нарабатывать бэкграунд. И нужно знать, где и что гуглить. База плюс новые технологии.

— В чем последнем сам разбирался?

Прикольно, мне нравится. В корутинах Kotlin. Смотрю, как работать в нем с многопоточностью и асинхронностью. И по синтаксису, и по логике. Сейчас я активно его изучаю, некоторые проекты его уже эксплуатируют. Раньше приходилось использовать Kotlin крайне мало. Он даже есть в некоторых небольших модулях на проде.

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»