Open Source в финансах. Проект Okama
В области финтех проектов наблюдается интересный парадокс. С одной стороны, вряд ли можно найти область, куда приходит больше инвестиций. Поэтому именно в финтехе сосредоточены самые продвинутые технологии: блокчейн, искусственный интеллект, биг дата, ML и др. С другой стороны, именно в финансовой области наблюдается наименьшее количество хорошо развитых open source проектов. Есть продвинутые программные продукты вроде терминала Bloomberg, специальные языки программирования, которые разрабатывались для решения финансовых задач. Однако в GitHub вы сможете по пальцам пересчитать популярные финансовые проекты с открытым кодом. Не слишком хорошо обстоят дела и с доступностью финансовых данных. Конечно, есть прекрасная база данных Всемирного банка. Но такие проекты уникальны. Их тоже немного. Сложно получить актуальные макроэкономические данные. А если речь идет об исторической рыночной информации, то за редким исключением возможны только платные варианты. В 21 м веке, почти каждая большая компания поддерживает проекты с открытым кодом, зачастую отдаёт данные с удобными программными интерфейсами… даже в Майкрософт изменили своё мнение об open source. Но в мире финансов всё остается примерно на уровне 90-х. Почему так? Для меня этот вопрос остается открытым. Возможно, финтех-проекты слишком сосредоточены на быстром зарабатывании денег. Для них гораздо важнее мифические единороги. Мало кто готов работать, если проект рассчитан на окупаемость больше 2–3 лет. Может быть, дело в традициях этой индустрии, которые пока не удаётся сломать.
У меня есть ощущение, что в финансовых проектах так же, как и в любой другой области давно пора понять, что конкурентное преимущество не обязательно должно заключаться в каком-то уникальном программном обеспечении и эксклюзивном доступе к закрытым базам данных. Важна экспертность и опыт команды, которая пользуется инструментом (в данном случае программным продуктом). Финансовые данные рынков давно пора сделать максимально открытыми и бесплатными. Те, кто привык мыслить старыми категориями, возможно станут жертвами ИИ. Последние рассуждения СЕО компании NVIDIA Дженсена Хуанга о незавидном будущем программирования как профессии меня в этом ещё больше убеждают.
Место СТП в Quantitative Finance
Я математик по образованию и уже примерно 15 лет интересуюсь Quantitative Finance (в дальнейшем кванты). Когда начинаешь изучать эту область человеческого знания на поверхности лежит всё, что связано с трейдингом и техническим анализом. Трейдинг популярен и хорошо продаётся. С ним связано много проектов.
Но взгляните на содержание наиболее признанного и престижного в мире финансов квалификационного экзамена Chartered Financial Analyst (CFA). Примерно 60% всего, что связано с квантами в CFA, это Современная теория портфеля (СТП). Иногда это направление называют «распределением активов» (Asset Allocation). Еще две большие темы квантов в CFA — фундаментальный анализ и дисконтирование денежных потоков. Ещё в учебниках CFA много разделов по статистике финансов и прогнозированию. Трейдинг и спекуляции — это лишь одна небольшая глава трехтомника.
Меня лично СТП интересует, так как я занимаюсь анализом долгосрочных инвестиционных стратегий. С точки зрения практической полезности ничего более эффективного не находил. Кроме того, математика СТП интересна и увлекательна… возможно, это основной личный мотив, а остальное просто попытка обосновать всё рационально :)
Существующие проекты про СТП
Для меня ориентиром по качеству и полезности всегда являлся проект Portfolio Visualizer. В нём реализовано много всего из области СТП и её продолжения (CAPM, Факторный анализ). Значительная часть функционала доступна бесплатно. Но проект коммерческий, и некоторые вещи отдаются по подписке. Это нормально. У Визуалайзера, на мой взгляд, есть два недостатка.
Доступные для анализа данные — это только история фондового рынка США и некоторых международных индексов. Базовая валюта портфеля только одна — доллар США. Нельзя собрать инвестиционный портфель, состоящий из ценных бумаг разных рынков (вне американского).
Это проект с закрытым кодом. Этим всё сказано. Пользуйся как есть. Что и как считается непонятно. Заявки на новые фичи не принимаются. Нет комьюнити.
В российской действительности Визуалайзер попросту неприменим. Ценных бумаг Мосбиржи в базе данных нет. Российских биржевых индексов тоже. А так это отличный проект. Много лет им пользовался и иногда заглядываю туда, чтобы подсмотреть полезные идеи.
Open source проекты по СТП
В опенсорсе по квантам всё не очень весело. Нет, конечно, есть довольно известные проекты вроде QuantLib. Но это опять про трейдинг.
Open source проекты по СТП, которые мне нравятся:
FinQuant — анализ инвестиционных портфелей, оптимизация
PyPortfolioOpt — оптимизация инвестиционных портфелей
Riskfolio-Lib — управление риском портфеля, оптимизация
Ни один из известных мне проектов с открытым кодом не предоставляет ничего похожего на Визуалайзер. В редком случае есть доступ к историческим данным. Обычно это и так всем доступные временные ряды из Yahoo Finance.
Проект okama
Наш проект okama — это библиотека с открытым кодом на Python и бесплатная база финансовых данных.
Несколько лет назад мы решили собрать воедино общепринятые финансовые алгоритмы для СТП и смежных областей (статистика, дисконтирование, факторный анализ и т.п.). Больше не хотелось ежедневно думать о том, где загрузить данные того или другого индекса, валюты или ценной бумаги. Поэтому важная часть проекта — это бесплатная база исторических данных.
Okama даёт возможность работать с наборами активов, номинированных в разных валютах. Все расчетные метрики доходности и риска приводятся к базовой валюте портфеля.
Что сегодня умеет okama? Здесь список основных возможностей:
Оптимизация инвестиционного портфеля (Mean-Variance Analysis — MVA)
Построение границы эффективности с учетом различных периодов ребалансировки
Прогнозирование показателей портфеля с использованием метода Монте-Карло
Бэктестинг распределений доходности
Прогнозирование с использованием типов распределений (нормальное, логнормальное)
Расчет популярных метрик риска: волатильность, полудисперсия, VaR, CVaR и др.
Расчет дивидендной доходности различных активов
Бэктестинг произвольных инвестиционных портфелей
Приведение показателей портфеля к единой валюте
Сравнения показателей индексных фондов: отклонение, ошибка следования, бета, корреляция и др.
Макроэкономические показатели различных рынков: инфляции, ставки банков, ставки ЦБ
Визуализация: граница эффективности, карта переходов (Transition Map), графики для прогнозирования и отображения исторических данных
База данных okama (доступ через REST API) содержит следующие исторические данные:
Цены акций и фондов для различных рынков (Россия, США, ЕС, Израиль и др.)
Стоимость пая и СЧА паевых инвестиционных фондов (ПИФ)
Стоимость товарных активов (золото, серебро, нефть и т.д.)
Котировки валют (ЦБ и FX)
Котировки криптовалют
Значения индексов
Инфляция различных стран
Ставки центральных банков мира
Цены на недвижимость
В качестве примера использования библиотеки создан простой сайт okama.io с финансовыми виджетами и возможностью поиска по базе данных.
Примеры использования okama
Установка библиотеки:
pip install okama
Импортируем её…
import okama as ok
Теперь можно создать простейший портфель из индексов российских акций и облигаций:
pf1 = ok.Portfolio(['RGBITR.INDX', 'MCFTR.INDX'], ccy='RUB')
pf1
RGBITR.INDX
— Индекс полной доходности облигаций федерального займа (ОФЗ). MCFTR.INDX
— Индекс Московской биржи полной доходности
Исторические данные подтягиваются автоматически из базы данных. В этом примере есть 21 год истории, что неплохо для российского рынка.
По умолчанию ценные бумаги имеют одинаковые веса. Но, если требуется создать портфель, например, 60/40, то это тоже просто:
pf2 = ok.Portfolio(['RGBITR.INDX', 'MCFTR.INDX'], ccy='RUB', weights=[.60, .40])
В портфеле pf2 все параметры считаются в рублях. Но можно создать аналогичный портфель и получить риск и доходности в другой валюте (USD, EUR, PND, CNY и т.п.).
Составим портфель из популярных зарубежных ETF и поменяем базовую валюту портфеля на доллар США:
pf3 = ok.Portfolio(['AGG.US', 'SPY.US', 'GLD.US'], weights=[.40, .30, .30], ccy='USD')
pf3
Полные названия бумаг, их тикеры и веса можно посмотреть в одной таблице:
pf3.table
История изменения баланса портфеля смотрится через свойство класса wealth_index
:
pf3.wealth_index.plot()
На графике отображается история баланса портфеля и накопленная инфляция.
Сводная таблица с основными показателями риска и доходности портфеля на исторических данных:
pf3.describe([1, 5, 10]) # получаем статистику доходности за 1, 5 и 10 лет
Если хочется чего-то более продвинутого, то можно создать стратегию со снятиями или пополнениями и задать период ребалансировки портфеля.
weights = [0.60, 0.30, 0.10]
pf4 = ok.Portfolio(
['RGBITR.INDX', 'MCFTR.INDX', 'GC.COMM'], # Индекс ОФЗ, Индекс Мосбиржи, золото
ccy='RUB',
weights=weights,
inflation=True, # загружаем данные по инфляции
symbol="Cons_portf.PF", # внутренний тикер портфеля для отображения на графике
rebalancing_period='year', # период ребалансировки - один раз в год
cashflow=-50_000, # размер ежемесячных изъятий денег
initial_amount=10_000_000, # стартовые инвестиции
discount_rate=None # для дисконтирования будет использоваться размер инфляции
)
pf4
В этой стратегии создаётся консервативный портфель 60/30/10 из российских облигаций (индекс ОФЗ), российских акций (Индекс Мосбиржи) и золота (спотовые цены). Стартовые инвестиции равны 10 млн. руб. Ежемесячно планируется снятие 50 тыс. руб. Ребалансировка портфеля осуществляется один раз в год. Можно считать это «пенсионным портфелем».
Тестируем стратегию на исторических данных. Это баланс портфеля с учётом ежемесячного снятия наличных:
pf4.dcf.wealth_index.plot() # методы с дисконтированием начинаются с префикса Portfolio.dcf.
Баланс инвестиционного портфеля и инфляция
За более чем 20 лет истории баланс портфеля не «обнулился», несмотря на изъятия. Более того, портфель шел ровно с инфляцией большую часть времени. Но ситуация 2021–2023 его немного «подкосила». Виной тому затянувшийся период роста ставок, и как следствие падение индекса ОФЗ. Уже по этому графику понятно, что индекс ОФЗ — не идеален для пенсионного портфеля. Он слишком волатилен и чувствителен к колебанию ставок.
Попробуем спрогнозировать возможные сценарии в будущем для пенсионной стратегии:
pf4.dcf.plot_forecast_monte_carlo(
distr="norm", # тип распределения случайной величины - распределение Гаусса
years=30, # делаем прогноз на 30 лет
backtest=True, # график включает тестирование на исторических данных
n=50 # количество сценариев
)
Прогнозирование сценариев инвестиционной стратегии методом Монте-Карло
Здесь мы генерируем методом Монте-Карло 50 случайных сценариев и смотрим, на сколько хватило сбережений. Горизонт прогнозирования равен 30 годам. При создании сценариев используется нормальное распределение.
Не трудно заметить, что в большинстве сценариев баланс портфеля обнуляется на промежутке 2035 — 2050 гг. Но есть оптимистичные сценарии, когда портфель остаётся на плаву и после 30 лет. Этот пример показывает, как можно визуализировать тестирование стратегий на исторических данных и прогнозирование методом Моне Карло. Для профессионального применения, конечно, визуализации недостаточно. Нужен количественный анализ, который можно сделать с помощью других методов библиотеки.
Гораздо больше примеров применения okama можно увидеть в блокнотах Jupyter Notebook (ссылка ниже).
Основные ссылки проекта okama
P.S.
Это первая публикация нашего проекта. Не забудьте подписать на наш блог Habr, плейлист «Python и финансы» на YouTube. Мы всегда рады новым друзьям :) .