Hello World Example#
This is a simple example that showcases the main usage of the library. We define a market simulator with some stocks, two trading policies (one simple, and one optimization-based), backtest them in parallel, and show the results. This example script is available in the repository.
import os
import cvxportfolio as cvx
import matplotlib.pyplot as plt
# risk aversion parameter (Chapter 4.2)
# chosen to match resulting volatility with the
# uniform portfolio (for illustrative purpose)
gamma = 2.5
# covariance forecast error risk parameter (Chapter 4.3)
# this can help regularize a noisy covariance estimate
kappa = 0.05
objective = cvx.ReturnsForecast() - gamma * (
cvx.FullCovariance() + kappa * cvx.RiskForecastError()
) - cvx.StocksTransactionCost()
constraints = [cvx.LeverageLimit(3)]
policy = cvx.MultiPeriodOptimization(objective, constraints, planning_horizon=2)
simulator = cvx.StockMarketSimulator(
['AAPL', 'AMZN', 'UBER', 'ZM', 'CVX', 'TSLA', 'GM', 'ABNB', 'CTAS', 'GOOG'])
results = simulator.backtest_many([policy, cvx.Uniform()], start_time='2020-01-01')
# print statistics result of the backtest
print("\n# MULTI-PERIOD OPTIMIZATION\n", results[0])
print("\n# UNIFORM ALLOCATION:\n", results[1])
# plot value and weights of the portfolio in time for MPO
results[0].plot()
# we use this to save the plots for the documentation
if 'CVXPORTFOLIO_SAVE_PLOTS' in os.environ:
plt.savefig('hello_world.png')
# plot value and weights of the portfolio in time for uniform
results[1].plot()
if 'CVXPORTFOLIO_SAVE_PLOTS' in os.environ:
plt.savefig('hello_world_uniform.png')
else:
plt.show()
This is the output printed to screen when executing this script. You can see many statistics of the back-tests. The timestamps of the back-test are the open times of the New York stock market (9.30am New York time) expressed in UTC.
Updating data..........
# MULTI-PERIOD OPTIMIZATION
#################################################################
Universe size 11
Initial timestamp 2020-01-02 14:30:00+00:00
Final timestamp 2023-11-08 14:30:00+00:00
Number of periods 971
Initial value (USDOLLAR) 1.000e+06
Final value (USDOLLAR) 3.149e+06
Profit (USDOLLAR) 2.149e+06
Avg. return (annualized) 35.9%
Volatility (annualized) 35.1%
Avg. excess return (annualized) 34.3%
Avg. active return (annualized) 34.3%
Excess volatility (annualized) 35.1%
Active volatility (annualized) 35.1%
Avg. growth rate (annualized) 29.8%
Avg. excess growth rate (annualized) 28.2%
Avg. active growth rate (annualized) 28.2%
Avg. StocksTransactionCost 0bp
Max. StocksTransactionCost 2bp
Avg. StocksHoldingCost 1bp
Max. StocksHoldingCost 3bp
Sharpe ratio 0.98
Information ratio 0.98
Avg. drawdown -13.9%
Min. drawdown -43.7%
Avg. leverage 153.7%
Max. leverage 240.0%
Avg. turnover 0.7%
Max. turnover 31.0%
Avg. policy time 0.005s
Avg. simulator time 0.003s
Total time 7.404s
#################################################################
# UNIFORM ALLOCATION:
#################################################################
Universe size 11
Initial timestamp 2020-01-02 14:30:00+00:00
Final timestamp 2023-11-08 14:30:00+00:00
Number of periods 971
Initial value (USDOLLAR) 1.000e+06
Final value (USDOLLAR) 2.048e+06
Profit (USDOLLAR) 1.048e+06
Avg. return (annualized) 23.9%
Volatility (annualized) 32.3%
Avg. excess return (annualized) 22.2%
Excess volatility (annualized) 32.3%
Avg. growth rate (annualized) 18.6%
Avg. excess growth rate (annualized) 17.0%
Avg. StocksTransactionCost 0bp
Max. StocksTransactionCost 3bp
Avg. StocksHoldingCost 0bp
Max. StocksHoldingCost 0bp
Sharpe ratio 0.69
Avg. drawdown -13.2%
Min. drawdown -39.7%
Avg. leverage 99.9%
Max. leverage 100.0%
Avg. turnover 0.9%
Max. turnover 50.0%
Avg. policy time 0.000s
Avg. simulator time 0.003s
Total time 2.542s
#################################################################
And these are the figure that are plotted.
The result of the cvxportfolio.MultiPeriodOptimization
policy:
![hello_world.py result figure](_images/hello_world.png)
This figure is made by the plot()
method of cvxportfolio.BacktestResult
#
And result of the cvxportfolio.Uniform
policy, which allocates equal
weight to all non-cash assets:
![hello_world.py result figure](_images/hello_world_uniform.png)
This figure is made by the plot()
method of cvxportfolio.BacktestResult
#