Okama 2.0: продвинутые стратегии изъятий и новая Граница эффективности
Мы выпустили "юбилейную" версию okama 2.0. В релизе много важных изменений. Основные темы: новые продвинутые стратегии снятия денег из портфеля и новая логика оптимизации портфелей для Границы эффективности.
Установить библиотеку или обновить версию можно уже сейчас:
pip install okama -U
В okama 2.0 мы сознательно сделали шаг от учебных и академических кейсов к более прикладным и реалистичным сценариям. С одной стороны, библиотека получила новые инструменты, которые хорошо подходят для разработки "пенсионных стратегий" с регулярными изъятиями.
С другой стороны, изменилась логика работы с Границей эффективности: теперь многопериодная оптимизация с ребалансировкой стала поведением по умолчанию. И этот более сложный вид оптимизации работает кратно быстрее! Теперь не надо оставлять работать компьютер и уходить пить чай, пока идут расчеты… Это сделало okama гораздо пригодной для WEB приложений. Изменения на okama.io не за горами.
Стратегии с денежными потоками и дисконтированием
Новые стратегии изъятий встроены в уже существующую архитектуру анализа денежных потоков с дисконтированием в классе PortfolioDCF. Портфель остаётся отдельным объектом, а стратегия денежных потоков подключается через pf.dcf.cashflow_parameters. Такая схема позволяет независимо тестировать структуру портфеля, правила ребалансировки и логику изъятий.
Простейший инвестиционный портфель создается из двух строчек кода:
import okama as ok
pf = ok.Portfolio() # по умолчанию это портфель из одного фонда SPY
Стратегия снятий Vanguard Dynamic Spending (VDS)
В версии 1.5.0 появилась стратегия изъятия портфеля, основанная на процентном снятии (PercentageStrategy). Новый класс VanguardDynamicSpending (VDS) развивает идею, где снятия определяются фиксированным процентом от баланса портфеля. Но вводит дополнительные ограничения. Это важный момент: новая стратегия не заменяет старую процентную модель, а расширяет её. Идеи этой стратегии разработаны в исследовании Vangard (прилагается).
Новый параметр, который вводит VDS, это floor_ceiling. Он ограничивает изменение снятия относительно предыдущего года. Например, пара (-0.025, 0.05) означает, что новое изъятие не может быть больше чем на 5% выше и не может быть больше чем на 2.5% ниже прошлогоднего значения. За счёт этого стратегия не допускает слишком резких скачков расходов вслед за рынком.
Дополнительно можно задать абсолютные ограничения через min_max_annual_withdrawals. Если включён adjust_min_max=True, эти границы индексируются, например на инфляцию. Параметр adjust_floor_ceiling работает похожим образом: сначала прошлогоднее снятие может быть проиндексировано, а затем к нему применяются floor и ceiling. В итоге VDS сочетает процентную привязку к портфелю и контроль над волатильностью потребления.
Ограничения: VDS работает только с регулярными снятиями (без пополнений), частота снятий – всегда раз в год.
Создается стратегия следующим образом:
vds = ok.VanguardDynamicSpending(
parent=pf,
initial_investment=1_000_000, # размер стартового капитал
percentage=-0.08, # процент снятия денег
floor_ceiling=(-0.025, 0.05), # процент, на который может изменяться размер снятий
)
pf.dcf.cashflow_parameters = vds
В терминах прикладного моделирования стратегия VDS полезна там, где инвестор хочет сохранить связь между расходами и размером капитала, но не готов мириться с тем, что сумма изъятий будет слишком сильно изменяться от года к году. Для пенсионных стратегий это гораздо ближе к реальному поведению, чем чистая процентная схема без ограничителей.
Стратегия снятий Cut Withdrawals If Drawdown (CWD)
Это несколько другая философия снятий. Размер зависит от реальных потребностей пенсионера и не зависит от размера портфеля. Этот подход был создан в версии 1.5.0 через класс IndexationStrategy.
Новая стратегия позволяет ограничить снятия в случае просадок рынка. Эта ситуация близка к реальным рекомендациям многих советников и академических исследований, так как портфель часто "убивают" снятия в период глубоких просадок.
Класс CutWithdrawalsIfDrawdown (CWD) задает параметры такой стратегии через ограничения снятий, которые зависят от глубины просадки портфеля.
Параметр crash_threshold_reduction задаётся списком пар вида (порог просадки, коэффициент сокращения). Например, запись (0.20, 0.40) означает: если просадка портфеля превышает 20%, текущее снятие сокращается на 40%. А пара (0.35, 1) означает фактическую остановку изъятий при просадке глубже 35%.
Такая стратегия особенно полезна в моделях, где пользователь хочет сохранить понятную базовую сумму расходов, но при этом заранее закодировать антикризисное поведение. Это уже не просто "снимать фиксированную сумму с индексацией", а управлять темпом изъятий в зависимости от глубины drawdown.
Создание CWD:
cwd = ok.CutWithdrawalsIfDrawdown(
parent=pf,
initial_investment=1_000_000, # стартовый капитал
frequency="year", # периодичность снятий (здесь – раз в год)
amount=-60_000, # целевой размер снятий в сегодняшних деньгах
indexation="inflation", # индексация размера снятий на размер инфляции
crash_threshold_reduction=[(.10, .25), (.20, .50), (.35, 1)], # список ограничений
)
pf.dcf.cashflow_parameters = cwd
Аккуратное ограничение на случай глубоких просадок позволяет использовать в пенсионных стратегиях агрессивные портфели с высокой ожидаемой доходностью, но и с более высокой волатильностью.
В следующих публикациях мы расскажем более подробно, как применять на практике стратегии VDS и CWD.
EfficientFrontier: единый класс для оптимизации с учетом ребалансировки
Второй ключевой блок релиза — обновление EfficientFrontier. Мы объединили EfficientFrontier и EfficientFrontierReb в единый класс EfficientFrontier. Теперь Граница эффективности по умолчанию строится в многопериодной логике, с ребалансировкой.
За счет кэширования находимых решений, использования параллельных вычислений и оптимизации целевых функций удалось значительно ускорить расчеты.
Кроме того, оптимизация ребалансируемых портфелей теперь поддерживает bounds — ограничения на веса активов. Для прикладных задач это критично: реальные модели почти всегда требуют нижних и верхних ограничений, а не абстрактного решения без ограничений.
ef = ok.EfficientFrontier(
assets=["SPY.US", "GLD.US"],
first_date="2004-12",
last_date="2020-10",
ccy="USD",
rebalancing_strategy=ok.Rebalance(period="year"),
n_points=40,
ticker_names=True,
bounds=((0.0, 1.0), (0.0, 0.20)), # процент золота в портфелях ограничен 20%
)
Быстрый поиск решений для заданной доходности:
ef.minimize_risk(target_value=0.11)
{ 'SPY.US': np.float64(0.9101000447520419),
'GLD.US': np.float64(0.08989995524795805),
'CAGR': 0.11,
'Mean return': np.float64(0.11403419643168483),
'Risk': np.float64(0.15083978371568296),
'Weights': array([0.91010004, 0.08989996]),
'iterations': 5 }
Произвольные снятия и пополнения во всех стратегиях
Любая стратегия снятий/пополнений теперь включает параметр time_series_dic, который позволяет задавать любый снятия и пополнения по календарному принципу.
time_series_dic = {
"2027-02": 2_000, # пополнение портфеля в феврале 2027 года
"2030-03": -4_000 # изъятие денег в марте 2030
}
Бэктестинг распределения
Бэктестинг распределения – важный этап подготовки к прогнозированию. Для его удобства появились новые инструменты.
Автоматический выбор распределения
В версии 2.0 появился метод kstest_for_all_distributions, который "прогоняет" тест Колмогорова-Смирнова для всех поддерживаемы распределений и определяет, какое из них подходит лучше.
pf.dcf.mc.kstest_for_all_distribution

Подгонка параметров распределения
Любой параметр распределения теперь может быть задан в ручном режиме. Полностью или частично.
Это особенно важно для распределения Стьюдента, которое обычно подходит лучше всего для прогнозирования "толстых хвостов".
Например, параметры распределения Стьюдента можно теперь задать следующим образом:
pf.dcf.mc.distribution_parameters = (4.26, None, None) # df, loc, scale
Уровень свободы (df) задается вручную, а остальные параметры – автоматически.
Более того, теперь уровень свободы можно "подогнать" автоматически под прогноз для определенной перцентили:
pf.dcf.mc.optimize_df_for_students(var_level=5) # подгон уровня свободы для 5й перцентили
4.260007759068121
Q-Q Plot
Точность бэктестинга распределения удобно визуализировать на графике Квантиль-Квантиль (Q-Q Plot), где сравниваются исторические данные и сгенерированные.
Для этого в версии 2.0 появился метод plot_qq:
pf.dcf.mc.plot_qq(var_level=5) # 5 – это доверительный уровень для VAR и CVAR

Если теоретические перцентили и эмпирические расходятся слишком сильно на заданной перцентили, лучше подогнать параметры распределения для более точного прогноза. Подробно расскажем, как это делается в отдельном материале.
Документация okama
Документация okama стала опрятнее и содержит подробную информацию по всем новшествам и примеры.
Сам раздел примеров на GitHub существенно доработан:
- 04 investment portfolios with DCF.ipynb — много новых примеров для стратегий изъятий VanguardDynamicSpending и CutWithdrawalsIfDrawdown
- 07 efficient frontier multi-period.ipynb — Добавлены примеры для унифицированного класса EfficientFrontier и оптимизации с учетом ребалансировки
- 10 forecasting.ipynb — обновлены примеры прогнозирования методом Монте-Карло, включая методы подгонки распределений в Монте-Карло
Дальнейшие планы okama
В ближайшее время мы начнем переносить самые важные изменения на okama.io.
В новых версиях okama появится поддержка Pandas 3 и Python 3.14.
Несколько более далекая перспектива – это создание аналога Личного финансового плана (ЛФП). ЛФП будет состоять из последовательности инвестиционных стратегии. Например, агрессивный портфель для создания пенсионных накоплений и консервативный портфель для расходования средств на пенсии. Конечно, всю последовательность портфелей надо будет прогнать сквозь прогнозирование Монте-Карло. И мы уже придумали, как это сделать.
Источники
- Форум проекта на русском языке: Новые релизы okama
- GitHub okama
- Документация okama
- Примеры использования в Jupyter Notebook
Если проект оказался вам полезен, поддержать его можно очень просто — поставить звезду на GitHub.
Файлы для скачивания
Vanguard Dynamic Spending VDS (PDF)
Размер: 568872 байт
Для скачивания файлов необходимо зарегистрироваться или авторизоваться
Теги:
Похожие материалы:
- Инвестировать по взрослому. Телеграм-бот на библиотеке okama
- Библиотека Python для доступа к данным ЦБ: cbrapi
- Okama 1.5.0 - Новая версия финансовой библиотеки для Python. Продвинутые стратегии ребалансировки портфеля
- Дивидендная доходность Индекса Московской биржи за последние 10 лет
- Загрузка исторических данных в EXCEL через API okama
- Поиск по бесплатной финансовой базе данных на okama.io
- Сайт okama.io – Инструменты портфельного инвестора и альтернатива PortfolioVisualizer.com
- Interactive Brokers на Московской бирже в 2018 году
- Okama 1.3.1. Новая версия финансовой библиотеки для Python
- Минимальная сумма для инвестиций через Interactive Brokers
- Okama: финансовая библиотека для Python и бесплатная база исторических данных
- Покупка ценных бумаг через Interactive Brokers
- Открытие брокерского счета в Interactive Brokers
- Сайт Okama.io - инструменты портфельного инвестора
- Индекс депозитов OKID - новые возможности
- Индекс депозитов: все банки (OKID)
Комментарии