Releases: mbk-dev/okama
Okama 2.0.1
Okama 2.0.1 is a maintenance-focused release that improves compatibility with pandas 3.x and Python 3.14, refines PortfolioDCF cash flow calculations, and makes several plotting and sharing APIs easier to integrate.
New features
pandas 3.x and Python 3.14 compatibility
- okama now supports
pandas3.x and Python 3.14. - Compatibility updates were applied across
Asset,AssetList,Portfolio,PortfolioDCF,MacroABC,Rebalance, and related helpers to keep timestamp conversion, grouping, and resampling behavior working with the new pandas aliases.
Plotting and integration improvements
PortfolioDCF.plot_forecast_monte_carlo(),MonteCarlo.plot_qq(), andMonteCarlo.plot_hist_fit()now return matplotlibAxesobjects, which simplifies embedding okama charts into custom figures.Portfolio.plot_assets()andEfficientFrontier.plot_assets()now accept extramatplotlib.pyplot.scatter()keyword arguments for custom styling.Portfolio.okamaio_linknow serializes the fullRebalanceconfiguration, includingRebalance.period,Rebalance.abs_deviation, andRebalance.rel_deviation.
Performance and analytics improvements
EfficientFrontieradds caching for intermediate calculations to speed up repeated optimization runs.AssetList.get_monthly_geometric_mean_return()andPortfolio.get_monthly_geometric_mean_return()add direct monthly geometric mean return calculations.Asset.first_dateandAsset.last_dateare now used more consistently byListMaker, which improves control over downloaded history ranges.
Bugs fixed
PortfolioDCF.wealth_index()andPortfolioDCF.cash_flow_ts()no longer apply reverse discounting in present-value mode.PortfolioDCF.find_the_largest_withdrawals_size()was fixed for Monte Carlo period validation and now works correctly withVanguardDynamicSpendingandCutWithdrawalsIfDrawdown.PortfolioDCF.plot_forecast_monte_carlo()no longer mutatesPortfolioDCF.cashflow_parameterswhile plotting.MonteCarlodistribution fitting and plotting fixes improve float dtype handling and restore compatibility in QQ/histogram workflows.pandascompatibility fixes also cover deprecatedDataFrame.applymap(),pd.concat(..., copy=...), and updatedpd.Grouperfrequency aliases.
Developer experience
- Linting and formatting migrated from
flake8+blacktoruff check, including GitHub workflows, pre-commit configuration, andAGENTS.mdinstructions for contributors. - Added
.pre-commit-config.yamlwith ruff hooks and a top-levelrequirements.txtmirroring runtime dependencies frompyproject.toml. - Added
CHANGELOG.mdfollowing the Keep a Changelog format and Semantic Versioning. - README now shows GitHub and pepy.tech download badges and an updated project roadmap.
Documentation and examples
Updated documentation and notebooks reflect the current API changes:
- 04 investment portfolios with DCF.ipynb
- 10 forecasting.ipynb
- 11 rebalancing portfolio.ipynb
- Read the Docs navigation and API pages were refreshed for
okama.search()andokama.symbols_in_namespace().
Okama 2.0.0
Unified Efficient Frontier with multi-period optimization and advanced withdrawal strategies for retirement planning.
- Merged
EfficientFrontierandEfficientFrontierRebinto a singleEfficientFrontierclass - Significantly faster Efficient Frontier calculations with caching, parallel computations, and objective function optimization
- New advanced withdrawal strategies: Vanguard Dynamic Spending (VDS) and CutWithdrawalsIfDrawdown (CWD)
Major Changes
Unified EfficientFrontier class with multi-period optimization
EfficientFrontier and EfficientFrontierReb have been merged into a single EfficientFrontier class. Every Efficient Frontier is now computed with rebalancing (multi-period) by default. Optimization of rebalanced portfolios now supports weight constraints (bounds), allowing users to set minimum and maximum allocation limits for each asset.
The calculation speed has been significantly improved through:
- Caching of intermediate results
- Parallel computations
- Objective function optimization
- Fast vectorized methods in
Rebalanceclass
WARNING:
The legacy single-period class has been renamed to EfficientFrontierSingle. If you were using the old EfficientFrontier (single-period), switch to EfficientFrontierSingle.
import matplotlib.pyplot as plt
# New unified EfficientFrontier (multi-period with rebalancing)
ls = ["SPY.US", "GLD.US"]
curr = "USD"
y = ok.EfficientFrontier(
assets=ls,
first_date="2004-12",
last_date="2020-10",
ccy=curr,
rebalancing_strategy=ok.Rebalance(period="year"), # set rebalancing period to one year
ticker_names=True, # use tickers in DataFrame column names (can be set to False to show full assets names instead tickers)
n_points=40, # number of points in the Efficient Frontier
)
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")
# Plot the assets
y.plot_assets(kind="cagr")
# Set axis labels
ax.set_xlabel("Risk (Standard Deviation)")
ax.set_ylabel("CAGR")
ax.legend();
Advanced Withdrawal Strategies
Two new cash flow strategies for retirement planning and endowment fund management:
Vanguard Dynamic Spending (VDS)
Implementation of the Vanguard Dynamic Spending rule that adjusts withdrawals based on portfolio performance with floor and ceiling guardrails.
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 = vdsCutWithdrawalsIfDrawdown (CWD)
Risk-based withdrawal strategy that reduces the withdrawal amount when portfolio drawdown exceeds defined thresholds.
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 = cwdDetailed explanation of new withdrawal strategies is at 04 investment portfolios with DCF.ipynb.
New Classes and Methods
first_date & last_date parameters in Asset
first_date&last_dateparameters are available in theAssetclass. Using these parameters could significantly improve the speed of downloading historical data.
Cash flow strategies
IndexationStrategy,PercentageStrategy,TimeSeriesStrategy— base cash flow management classesVanguardDynamicSpending— dynamic spending rule with floor/ceiling guardrails and min/max annual withdrawal adjustmentsCutWithdrawalsIfDrawdown— drawdown-based withdrawal reduction strategy with configurable threshold/reduction pairs
EfficientFrontier improvements
EfficientFrontier.plot_transition_map()— visualization of asset allocation across the Efficient FrontierEfficientFrontier.plot_cml()— Capital Market Line plottingEfficientFrontier.get_most_diversified_portfolio()— Most Diversified Portfolio (MDP) optimization based on diversification ratioEfficientFrontier.get_monte_carlo()generates random portfolios with Monte Carlo simulation respectingboundsEfficientFrontier.plot_assets()now accepts**kwargsfor matplotlibscatter()
AssetList
AssetList.get_monthly_geometric_mean_return()— new method for geometric mean return calculation
MonteCarlo
MonteCarlo.plot_forecast_monte_carlo()now returns matplotlibAxesobjectMonteCarlo.get_parameters_for_distribution()— distribution fitting with parameters for normal, lognormal, and Student's t distributionsMonteCarlo.kstest()andMonteCarlo.kstest_for_all_distributions()— Kolmogorov-Smirnov goodness-of-fit testsMonteCarlo.plot_hist_fit()— histogram with fitted distribution overlayMonteCarlo.plot_qq()— QQ-plot for visual distribution fit assessment
Portfolio architecture
- New
MonteCarloclass for advanced Monte Carlo simulations and statistical distribution analysis (moved fromPortfolio) - New
PortfolioDCFclass for discounted cash flow analysis, portfolio survival analysis, and withdrawal strategy testing - New
Rebalancehelper class encapsulating rebalancing logic withwealth_ts_efandreturn_ror_ts_efmethods for fast optimization
Documentation and Examples
New and updated Jupyter Notebook examples in the /examples directory:
- 04 investment portfolios with DCF.ipynb — many new examples for
PortfolioDCF,VanguardDynamicSpending, andCutWithdrawalsIfDrawdownstrategies - 07 efficient frontier multi-period.ipynb — significantly reworked with examples for the unified
EfficientFrontierclass and multi-period optimization - 10 forecasting.ipynb — updated Monte Carlo forecasting examples including
MonteCarlodistribution fitting methods - 11 rebalancing portfolio.ipynb — several new examples
All existing notebooks have been refreshed to reflect the latest API changes in okama 2.0.0.
Bug Fixes
- Fixed
AssetList.annual_return_tsandPortfolio.annual_return_tsannual arithmetic mean return compounding calculation - Fixed
PortfolioDCF.wealth_index(discounting="pv")calculation - Fixed
PortfolioDCF.cashflow_parametersbeing modified afterplot_forecast_monte_carlo() - Fixed
PortfolioDCF.find_the_largest_withdrawals_sizenot preserving original CashFlow parameters - Fixed
PortfolioDCFcash flow adjustments in first and last year for partial periods - Fixed
Portfolio.mean_returncalculation to useror.mean()formula - Fixed
MonteCarlo._get_params_for_lognormalparameter calculation - Fixed
MonteCarlo.kstest()fitting to lognormal distribution to use gross returns - Fixed Pandas
FutureWarningforconcatwith empty DataFrame inRebalanceclass - Fixed
MonteCarlo.mc_numbersetter parameter name - Fixed
PortfolioDCF._target_cagr_range_leftcalculation
Other Changes
- Python 3.10 is no longer supported
- API connection switched to HTTPS with SSL verification
- Updated all Jupyter Notebook examples in
/examplesdirectory - Significant increase in test coverage for DCF, Monte Carlo, and cash flow strategy modules
Full Changelog: v1.5.0...v2.0.0
Okama 1.5.0
Rebalancing bands - new rebalancing strategies for investment portfolios.
- Calendar-based rebalancing
- Rebalancing bands (threshold-based)
Mean-variance optimization with rebalancing-strategy-adjusted Efficient Frontier and asset weight bounds.
New features
Rebalance - new class to define rebalancing strategies
Rebalancing strategies are now defined in both Portfolio and EfficientFrontierReb with Rebalance class.
rs = ok.Rebalance(period="year", abs_deviation=0.10, rel_deviation=0.30)
pf = ok.Portfolio(['SPY.US', 'AGG.US'], rebalancing_strategy=rs)WARNING:
The previous Portfolio class initialization method is now deprecated.
ok.Portfolio(rebalancing_period="year") will not work anymore.
However, as the default rebalancing strategy is monthly calendar-based. The simple definition without rebalancing strategy is still working:
ok.Portfolio(['SPY.US', 'AGG.US'], weights=[.6, .4])Rebalance class
- New
Rebalanceclass has 3 parameters: period, abs_deviation, rel_deviation Rebalance.wealth_ts()calculates wealth index time series of rebalanced portfolio (optionally with assets wealth time series)Rebalance.assets_weights_ts()calculates assets weights monthly time series for rebalanced portfolioRebalance.return_ror_ts()returns monthly rate of return time series of rebalanced portfolio
New methods and properties in Portfolio class
- new property
rebalancing_strategyto configure rebalancing period, absolute and relative deviations - new property
rebalancing_eventsreturns time series of rebalancing events and type of rebalancing
Changes in PortoflioDCF class
PortfolioDCF.monte_carlo_wealth_pvcalculates discounted random wealth indexes with cash flowsPortfolioDCF.monte_carlo_wealth_fvcalculates not discounted (nominal) random wealth indexes with cash flowsPortfolioDCF.find_the_largest_withdrawals_size()now uses bisection method to find the largest withdrawals size.PortfolioDCF.find_the_largest_withdrawals_size()has 3 possible goals: 'maintain_balance_pv', 'maintain_balance_fv' and 'survival_period'PortfolioDCF.find_the_largest_withdrawals_size()new attributewithdrawals_rangedefines the possible range for withdrawals to speed up the calculationsPortfolioDCF.find_the_largest_withdrawals_size()hasiter_maxattribute to limit the intermediate steps when searching for resolutionPortfolioDCF.find_the_largest_withdrawals_size()returnsResultclass. If the solutions is not found it is still possible to see the intermediate steps
New methods and properties in EfficienFrontierReb class
EfficienFrontierReb class now uses rebalancing_strategy parameter for initialization (the same as Portfolio).
It supports bounds to define the weight limitations for the assets.
- new
rebalancing_strategyparameter to define the rebalancing strategy - new
boundsparameter defines the bounds for the assets weights - new
EfficienFrontierReb.plot_pair_ef()method plots the Efficient Frontier of every pair of assets
Changes in EfficientFrontier class
EfficientFrontier.get_monte_carlomethod generates random rebalanced portfolios with Monte Carlo simulation according toboundslimitations.
New Jupyter Notebook with examples for Rebalancing strategies
New Jupyter Notebook with examples of investment portfolios with different rebalancing strategies:
10 rebalancing portfolio.ipynb
Okama 1.4.4
New examples for investment portfolios with cash flow in 04 investment portfolios with DCF.ipynb.
Several bugs in Portfolio and PortfolioDCF are fixed.
Fixed:
Portfolio.dcf.initial_investment_pvmust return None if cash flow parameters are not defined- add
use_discounted_valuesparameterto helpers.Frame.get_wealth_indexes_with_cashflow - use
self.use_discounted_values = Falseinplot_forecast_monte_carlofor any value of backtest parameter - clean up Portfolio dat cache if symbol changed
Okama 1.4.3
Okama 1.4.3 is dedicated to Cash Flow strategies and Monte Carlos simulations.
New features
3 new classes to set up Cash Flow strategies
Cash flow parameters for investment portfolios are now configured in the corresponding classes.
IndexationStrategyfor strategies with regular indexed withdrawals / contributionsPercentageStrategyfor strategies weith regualr fixed percentage withdrawals / contributionsTimeSeriesStrategyfor strategies with user-defined withdrawals and contributions. Withdrawals, contributions, as well as their dates, are defined in the dictionary.
All 3 classes are inhereted from parent class CashFlow.
Portfolio class does not have cash flow parameters (initial_amount, cashflow, discount_rate) anymore.
New class to set up Monte Carlo simulation parameters
MonteCarlos class has several properties:
distribution- the type of a distribution to generate random rate of returnperiod- forecast period in years for portfolio wealth index time seriesnumber- number of random wealth indexes to generate with Monte Carlo simulation
All Monte Carlos properties are linked to PortfolioDCF instance and can be accessed by Portfolio().dcf.mc construction. For example the type of random distribution is available through Portfolio().dcf.mc.disctribution.
New methods and properties in PortfolioDCF
PortfolioDCF has a new parameter use_discounted_values (default is False). Id defines whether to use discounted values in backtesting wealth indexes (initial investments, withdrawal or contribution size). discount_rate parameter is shifted from Portfolio to PortfolioDCF.
find_the_largest_withdrawals_size- find the largest withdrawals size for Monte Carlo simulation according to Cashflow Strategy. This method works withIndexationStrategyandPercentageStrategyinitial_investment_fvproperty to calculate the future value (FV) of the initial investments at the end of forecast period.initial_investment_pvproperty to calculate the discounted value (PV) of the initial investments at the historical first datewealth_index_with_assetsworks as the same property ofPortfoliobut considers cash flow (contributions and withdrawals)set_mc_parametersmethod is a shortcut to add Monte Carlo simulation parameters
Changes in methods and properties in PortfolioDCF
monte_carlo_survival_period,survival_date_histandsurvival_period_histmethods have now new parameterthreshold. The threshold defines the percentage of the initial investments when the portfolio balance considered voidedplot_forecast_monte_carlonumber of parameters is reduced to:backtestandfigsize
Okama 1.4.1
Okama 1.4.1 adds custom exceptions for time period and Student's t distribution for Monte-Carlo methods in Portfolio and AssetList.
New features
Custom exceptions for time periods issues
ShortPeriodLengthErroris raised when an asset has less then 3 months of history in AssetList, Portfolio and EfficentFrontier classesRollingWindowLengthBelowOneYearErroris raised when rolling windows size is below one yearLongRollingWindowLengthErroris raised when rolling window size is more than data history depth
Student's t distribution in Monte-Carlo methods
- set
distr="t"in methods likePortfolio.dcf.monte_carlo_wealthorAssetList.kstest
Changes in existing methods & properties
Portfolio.dcf.monte_carlo_wealthusesinitial_amountvalue by default.
Bugs fixed
- wrong formula for 0 period rate of return in
helpers.Rebalance.return_ror_ts
Okama 1.4.0
Okama 1.4.0 introduces investment strategies with contributions and withdrawals in Portfolio class. New methods support discounted cash flows (DCF) and Monte Carlo simulation for portfolio longevity.
New features
DCF methods for contributions and withdrawals in Portfolio class
New Portfolio class attributes (all are optional):
initial_amount- Portfolio initial investment FV (at last_date)cashflow- portfolio monthly cash flow FV (at last_date). Negative value corresponds to withdrawals.
Positive value corresponds to contributions. Cash flow value is indexed each month by inflation.discount_rate- cash flow discount rate required to calculate PV values.
New dcf. methods in Portfolio class:
dcf.plot_forecast_monte_carlo()method to plot Monte Carlo simulation for portfolio future wealth indexes optionally together with historical wealth index.dcf.monte_carlo_survival_period()method to generate a survival period distribution for a portfolio with cash flows by Monte Carlo simulation.dcf.wealth_indexproperty to calculate wealth index time series for the portfolio with contributions and
withdrawals.dcf.survival_periodproperty to calculate the period when the portfolio has positive balance considering withdrawals on the historical data.dcf.survival_dateproperty to get the date when the portfolio balance become negative considering withdrawals on the historical data.dcf.cashflow_pvproperty to calculate the discounted value (PV) of the cash flow amount at the historicalfirst_date.dcf.initial_amount_pvproperty to calculate the discounted value (PV) of the initial investments at the historicalfirst_date.
New properties in Portfolio class
assets_dividend_yieldproperty to calculate last twelve months (LTM) dividend yield time series (monthly) for each assetdividends_annualproperty to get calendar year dividends sum time series for each asset.
New methods and properties in AssetList class
get_rolling_risk_annual()method to calculate annualized risk rolling time series for each asset.get_dividend_mean_yield()method to calculate the arithmetic mean for annual dividend yield over a specified period.dividend_yield_annualproperty to calculate last twelve months (LTM) dividend yield annual time series.
Changes in existing methods & properties
Asset_List.risk_annualreturns expanding risk time series (not float)Portfolio.recovery_periodreturns time series of recovery periods over historical data (not a single period)describe()method shows the rate of return arithmetic mean (expected return) inPortfolio,AssetListclasses- new
xy_textargument inplot_assets()method to position better point labels
inPortofolio,AssetListclasses
New Jupyter Notebooks with examples
- 04 investment portfolios with DCF.ipynb for investment strategies with cash flow - portfolio withdrawals / contributions. Backtest the portfolio and forecast portfolio longevity with Monte Carlo simulation.
- 05 macroeconomics - inflation rates.ipynb to analyze inflation, key rates and other macro indicators historical data.
Bugs fixed
- Duplicate tickers in the assets are no longer allowed and are automatically corrected (
AssetList,Portfolio,EfficientFrontier,EfficientFrontierReb)
Okama 1.3.2
Okama now supports Panadas 2.0.0 and further versions. There is no backward compatibility with previous Pandas versions.
New features:
- New rebalancing periods for portfolios: "half-year" and "quarter"
- new
set_values_monthly()method in Inflation to forecast data and change previos values - new
dividend_yield_annualproperty in AssetList calculates dividend yield time series for calendar years - new
get_dividend_mean_yield()method in AssetList shows mean dividend yield for a given period plot_cml()has newy_axeparameter to switch from CAGR to mean rate of returns in the plotsasset_dividend_yieldproperty renamed todividend_yieldin AssetList
Okama 1.3.1
okama works with Python 3.11 now.
FIX:
- aliases
symbols_in_namespaceandno_dividends_namespaceswere not imported in__init__.py
Okama 1.3.0
New features:
- rolling_window parameter in AssetList functions:
index_corr(),index_beta(),tracking_error() index_corr()andindex_rolling_corr()are combined into a single functionindex_corr()in the AssetList- AssetList, Prtfolio, EfficentFrontier and EfficentFrontierReb are now sequences and has
__getitem__,__iter__methods.
Fix:
- Avoid running
get_namspaces()and other aliases in init.py (this resulted in the database requests during library import) EfficientFrontier.plot_pair_ef()faled if inflation=False- Tickers with dot "." like BRK.B
