Okama 2.0.0
Вот и дождались юбилейного релиза ![]()
В этот раз изменений накопилось много… Основные темы релиза такие:
EfficientFrontierиEfficientFrontierRebобъединены в единый классEfficientFrontier- Существенно ускорены расчёты Границы эффективности благодаря кэшированию, параллельным вычислениям и оптимизации целевой функции
- Добавлены новые продвинутые стратегии изъятия средств: Vanguard Dynamic Spending (VDS) и CutWithdrawalsIfDrawdown (CWD). О них будет отдельная статья.
Подробности изменений
Единый класс EfficientFrontier с многопериодной оптимизацией
EfficientFrontier и EfficientFrontierReb были объединены в единый класс EfficientFrontier. Теперь любая Граница эффективости по умолчанию рассчитывается с ребалансировкой (многопериодный подход). Оптимизация ребалансируемых портфелей теперь поддерживает ограничения на веса (bounds), позволяя пользователям задавать минимальные и максимальные пределы распределения для каждого актива.
Скорость расчётов была значительно увеличена благодаря:
- кэшированию промежуточных результатов
- параллельным вычислениям
- оптимизации целевой функции
- быстрым векторизованным методам в классе
Rebalance
ПРЕДУПРЕЖДЕНИЕ:
Устаревший класс с классической оптимизацией Марковица (без ребалансировки) был переименован в EfficientFrontierSingle. Если вы использовали старый EfficientFrontier (однопериодный), перейдите на EfficientFrontierSingle.
import matplotlib.pyplot as plt
y = ok.EfficientFrontier(
assets="SPY.US", "GLD.US"],
first_date="2004-12",
last_date="2020-10",
ccy="USD",
rebalancing_strategy=ok.Rebalance(period="year"), # календарная ребалансировка раз в год
ticker_names=True, # использовать наименование ценных бумаг вместо тикеров
n_points=40, # количество точек на Границе эффективности (детализация графика)
)
fig, ax = plt.subplots(figsize=(12, 10))
# Plot the Efficient Frontier
ax.plot(df_reb_year.Risk, df_reb_year.CAGR, label="Annually rebalanced")
ax.plot(df_not_reb.Risk, df_not_reb.CAGR, label="Not rebalanced")
# Отрисовка точек активов
y.plot_assets(kind="cagr")
ax.set_xlabel("Risk (Standard Deviation)")
ax.set_ylabel("CAGR")
ax.legend();
Продвинутые стратегии изъятия средств из портфеля
Две новые стратегии денежного потока для пенсионного планирования и управления целевыми фондами:
Vanguard Dynamic Spending (VDS)
Реализация правила Vanguard Dynamic Spending, которое корректирует изъятия средств в зависимости от результатов портфеля с использованием нижних и верхних ограничителей.
pf = ok.Portfolio(['SPY.US', 'BND.US'], weights=[.6, .4], first_date='2010-01', last_date='2024-10', ccy='USD', inflation=True)
vds = ok.VanguardDynamicSpending(
parent=pf,
initial_investment=1_000_000,
frequency="year",
percentage=-0.05,
floor_ceiling=(-0.05, 0.10), # -5% floor / +10% ceiling
)
pf.dcf.cashflow_parameters = vds
CutWithdrawalsIfDrawdown (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
Подробное описание новых стратегий изъятия средств приведено в 04 investment portfolios with DCF.ipynb.
Новые классы и методы
Параметры first_date и last_date в Asset
- Параметры
first_dateиlast_dateдоступны в классеAsset. Использование этих параметров может значительно ускорить загрузку исторических данных.
Улучшения в классе EfficientFrontier
EfficientFrontier.plot_transition_map()— визуализация границы переходовEfficientFrontier.plot_cml()— построение линии рынка капиталаEfficientFrontier.get_most_diversified_portfolio()— оптимизация Most Diversified Portfolio (MDP) на основе коэффициента диверсификацииEfficientFrontier.get_monte_carlo()генерирует случайные портфели с помощью моделирования Монте-Карло с учётом ограничения по весам (bounds)EfficientFrontier.plot_assets()теперь принимает**kwargsдля matplotlibscatter()
AssetList
AssetList.get_monthly_geometric_mean_return()— новый метод для расчёта геометрической средней доходности за месяц
MonteCarlo
MonteCarlo.plot_forecast_monte_carlo()теперь возвращает объект matplotlibAxesMonteCarlo.get_parameters_for_distribution()— подбор распределения с параметрами для нормального, логнормального распределений и распределения СтьюдентаMonteCarlo.kstest()иMonteCarlo.kstest_for_all_distributions()— тесты согласия Колмогорова — СмирноваMonteCarlo.plot_hist_fit()— гистограмма с наложением подобранного распределенияMonteCarlo.plot_qq()— QQ-график для визуальной оценки качества подгонки распределения
Архитектура портфеля
- Новый класс
MonteCarloдля продвинутого моделирования Монте-Карло и статистического анализа распределений (перенесён изPortfolio) - Новый класс
PortfolioDCFдля анализа дисконтированных денежных потоков, анализа выживаемости портфеля и тестирования стратегий изъятия средств - Новый вспомогательный класс
Rebalance, инкапсулирующий логику ребалансировки, с методамиwealth_ts_efиreturn_ror_ts_efдля быстрой оптимизации
Документация и примеры
Новые и обновлённые примеры Jupyter Notebook в каталоге /examples:
- 04 investment portfolios with DCF.ipynb — множество новых примеров для
PortfolioDCF,VanguardDynamicSpendingи стратегииCutWithdrawalsIfDrawdown - 07 efficient frontier multi-period.ipynb — существенно переработан, добавлены примеры для единого класса
EfficientFrontierи многопериодной оптимизации - 10 forecasting.ipynb — обновлённые примеры прогнозирования методом Монте-Карло, включая методы подгонки распределений
MonteCarlo - 11 rebalancing portfolio.ipynb — несколько новых примеров
Все существующие ноутбуки были обновлены в соответствии с последними изменениями API в okama 2.0.0.
Исправления ошибок
- Исправлен расчёт капитализации годовой средней арифметической доходности в
AssetList.annual_return_tsиPortfolio.annual_return_ts - Исправлен расчёт
PortfolioDCF.wealth_index(discounting="pv") - Исправлена проблема, при которой
PortfolioDCF.cashflow_parametersизменялся послеplot_forecast_monte_carlo() - Исправлено поведение
PortfolioDCF.find_the_largest_withdrawals_size, из-за которого не сохранялись исходные параметрыCashFlow - Исправлены корректировки денежного потока
PortfolioDCFв первом и последнем году для неполных периодов - Исправлен расчёт
Portfolio.mean_return, теперь используется формулаror.mean() - Исправлен расчёт параметров
MonteCarlo._get_params_for_lognormal - Исправлена подгонка логнормального распределения в
MonteCarlo.kstest(), теперь используются валовые доходности - Исправлен
FutureWarningPandas дляconcatс пустым DataFrame в классеRebalance - Исправлено имя параметра сеттера
MonteCarlo.mc_number - Исправлен расчёт
PortfolioDCF._target_cagr_range_left
Прочие изменения
- Python 3.10 больше не поддерживается
- Подключение к API переведено на HTTPS с проверкой SSL
- Обновлены все примеры Jupyter Notebook в каталоге
/examples - Существенно увеличено покрытие тестами для модулей DCF, Monte Carlo и стратегий денежного потока
Полный список изменений: v1.5.0…v2.0.0