### Run Hello World Example in Python
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/hello_world.rst.txt
This Python script sets up and runs a basic backtest using Cvxportfolio's MultiPeriodOptimization policy. It requires the Cvxportfolio library to be installed.
```python
import cvxportfolio as cp
print("Hello World!")
# we use this to save the plots
# import matplotlib.pyplot as plt
# plt.style.use('seaborn-v0_8-darkgrid')
# create a universe of assets
# assets = ['AAPL', 'MSFT', 'GOOG', 'AMZN', 'NVDA']
# simulate market data
# data = cp.MarketData(assets=assets, start_time='2020-01-01', end_time='2020-12-31')
# define the optimization policy
# policy = cp.MultiPeriodOptimization(solver='ECOS')
# define the backtest
# result = cp.Backtest(data=data, policy=policy)
# print the results
# print(result.summary())
# plot the results
# result.plot(show=True)
```
--------------------------------
### Install Cvxportfolio
Source: https://www.cvxportfolio.com/en/1.5.0/index.html
Install the Cvxportfolio library using pip. This is the standard installation method for most users.
```bash
pip install -U cvxportfolio
```
--------------------------------
### Hello World Example in Python
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/paper_examples/hello_world.rst.txt
This script is a translation of an original IPython notebook example using Cvxportfolio's stable API. It serves as a basic introduction to the library's functionality.
```python
# This file is part of Cvxportfolio.
# Cvxportfolio is free software: you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
# Cvxportfolio is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
# You should have received a copy of the GNU General Public License along with
# Cvxportfolio. If not, see .
import cvxportfolio as cp
import pandas as pd
# Define a universe of assets
assets = pd.Index(['AAPL', 'GOOG', 'MSFT', 'AMZN'])
# Define a time series of historical returns
returns = pd.DataFrame(
{
'AAPL': [0.01, 0.02, -0.01, 0.03],
'GOOG': [0.015, 0.01, 0.005, 0.02],
'MSFT': [0.005, 0.015, 0.01, 0.015],
'AMZN': [0.02, 0.005, 0.015, 0.025],
},
index=pd.to_datetime(['2023-01-01', '2023-01-02', '2023-01-03', '2023-01-04']),
)
# Create a portfolio optimization problem
# We want to minimize risk (volatility) subject to a target return of 0.01 per period
problem = cp.minimize(
cp.ReturnForecastError.মিক্যাল(returns),
cp.Portfolio(assets=assets),
cp.ReturnTarget(0.01),
)
# Solve the problem
result = problem.solve()
# Print the optimal portfolio weights
print(result.weights)
```
--------------------------------
### Hello World Example Output
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/hello_world.rst.txt
This is the text output generated by the Cvxportfolio 'Hello World' example script, showing backtest statistics.
```text
Hello World!
```
--------------------------------
### Initialize development environment and run tests
Source: https://www.cvxportfolio.com/en/1.5.0/contributing.html
Commands to prepare the virtual environment and verify the installation via the test suite.
```makefile
make env
make test
```
--------------------------------
### Install Development Version of Cvxportfolio
Source: https://www.cvxportfolio.com/en/1.5.0/index.html
Install the latest development version directly from the GitHub repository. This is useful for users who want to access pre-release features or contribute to the project.
```bash
pip install --upgrade --force-reinstall git+https://github.com/cvxgrp/cvxportfolio@master
```
--------------------------------
### Single-period optimization example
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/paper_examples/single_period_opt.rst.txt
This script demonstrates the implementation of a single-period optimization strategy using the Cvxportfolio framework.
```python
import cvxportfolio as cvx
import pandas as pd
# ... (code content from lines 35 onwards of single_period_opt.py)
```
--------------------------------
### Import Libraries and Setup Backtest
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/rank_and_spo.html
Imports necessary libraries and sets up the backtesting environment including market data, initial weights, and cost models.
```python
"""Ranking vs. SPO example.
*Work in progress.*
This is a close translation of what was done in `this notebook
`_.
In fact, you can see that its results are **identical** for the Ranking policy.
The optimization policy, instead, has different performance than in the
original example: the Sharpe ratio is now higher and volatility lower, with the
same choice of hyper-parameters, which is not optimized: it was simply chosen
to match the ranking strategy's PnL. This is due to a bug in how the risk
model was handled in the early (2016) development versions of Cvxportfolio. The
risk penalization was also applied to the cash account, while the paper clearly
states that it only applies to non-cash assets. This has been fixed in these
translation scripts and is now correct in the stable versions of Cvxportfolio.
"""
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
import numpy as np
import pandas as pd
import cvxportfolio as cvx
from .common import (
paper_hcost_model,
paper_optimization_tcost_model,
paper_returns_forecast,
paper_simulated_tcost_model)
from .data_risk_model import paper_market_data, paper_risk_model
# Start and end times of the back-test.
start_t = "2012-01-01"
end_t = "2016-12-31"
# Get market data.
market_data = paper_market_data()
# Define initial weights.
w_b = pd.Series(index=market_data.returns.columns, data=1)
w_b.USDOLLAR = 0.
w_b /= sum(w_b)
# Cost models.
simulated_tcost = paper_simulated_tcost_model()
simulated_hcost = paper_hcost_model()
# Market simulator.
simulator = cvx.MarketSimulator(market_data = paper_market_data(),
costs=[simulated_tcost, simulated_hcost])
```
--------------------------------
### Load Market Data for Paper Examples
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/data_risk_model.html
Loads historical returns and volumes from CSV files to create a market data server. It specifies the cash key and sets minimum history to zero. This function is intended for use with the paper's examples.
```python
from pathlib import Path
import numpy as np
import pandas as pd
import cvxportfolio as cvx
def paper_market_data():
"""Build market data server for the paper's examples.
The returns dataframe already includes the cash returns column
(as its last), we point the ``cash_key`` argument to its name.
We also use the ``min_history`` argument, which, howerver ,in this case is
not needed (since we start our back-tests after the default minimum
history of one year).
:return: Market data for the paper.
:rtype: :class:`cvxportfolio.UserProvidedMarketData`
"""
returns = pd.read_csv(
Path(__file__).parent / 'returns.csv.gz', index_col=0, parse_dates=[0])
volumes = pd.read_csv(
Path(__file__).parent / 'volumes.csv.gz', index_col=0, parse_dates=[0])
# print(returns)
return cvx.UserProvidedMarketData(
returns=returns, volumes=volumes,
cash_key='USDOLLAR', min_history=pd.Timedelta('0d'))
```
--------------------------------
### Back-test Timing Output
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/timing.rst.txt
Example output showing the execution time difference between the first and second back-test runs.
```text
First run...
Total time: 12.45s
Second run...
Total time: 2.12s
```
--------------------------------
### Risk Models Setup and Comparison Script
Source: https://www.cvxportfolio.com/en/1.5.0/examples/risk_models.html
This script compares various risk models by defining them with symbolic hyperparameters, optimizing these hyperparameters using a simulator, and then backtesting the resulting policy. It requires CVXportfolio, pandas, and numpy.
```python
from pprint import pprint
import numpy as np
import pandas as pd
import cvxportfolio as cvx
from .universes import DOW30 as UNIVERSE
# Index
INDEX = 'DIA'
# Times.
START = '2000-01-01'
END = None # today
# Leverage.
LEVERAGE_LIMIT = 1.
# Stock market simulator with default transaction and
# holding cost models.
simulator = cvx.StockMarketSimulator(UNIVERSE + [INDEX])
# Build benchmark.
all_in_index = pd.Series(
0., index = simulator.market_data.returns.columns)
all_in_index[INDEX] = 1.
benchmark = cvx.FixedWeights(all_in_index)
# Define hyper-parameter objects.
# These will be included in the library in a future release.
class GammaTradeCoarse(cvx.RangeHyperParameter):
"""Transaction cost multiplier, coarse value range."""
def __init__(self):
super().__init__(
values_range=np.arange(1, 11),
current_value=1.)
class GammaTradeFine(cvx.RangeHyperParameter):
"""Transaction cost multiplier, fine value range."""
def __init__(self):
super().__init__(
values_range=np.linspace(-1., 1., 51),
current_value=0)
class GammaRiskCoarse(cvx.RangeHyperParameter):
"""Risk term multiplier, coarse value range."""
def __init__(self):
super().__init__(
values_range=np.arange(1, 21),
current_value=1.)
class GammaRiskFine(cvx.RangeHyperParameter):
"""Risk term multiplier, fine value range."""
def __init__(self):
super().__init__(
values_range=np.linspace(-1., 1., 51),
current_value=0)
class Kappa(cvx.RangeHyperParameter):
"""Risk forecast error multiplier, fine value range."""
def __init__(self):
super().__init__(
values_range=np.linspace(0., 0.5),
current_value=0)
# We test these risk models, with symbolic hyper-parameters.
base_risk_models = [cvx.DiagonalCovariance(), cvx.FullCovariance()]
base_risk_models += [
cvx.FactorModelCovariance(num_factors=num_factors)
for num_factors in [1, 2, 5, 10]
]
# with hyper-parameters
RISK_MODELS = [
(GammaRiskCoarse() + GammaRiskFine()) * base_risk_model
for base_risk_model in base_risk_models
]
# with risk forecast error
RISK_MODELS += [
(GammaRiskCoarse() + GammaRiskFine()) * (
base_risk_model + Kappa() * cvx.RiskForecastError())
for base_risk_model in base_risk_models
]
results = {}
for risk_model in RISK_MODELS:
print('Testing risk model:')
print(risk_model)
results[repr(risk_model)] = {}
current_result = results[repr(risk_model)]
# Build policy.
policy = cvx.SinglePeriodOpt(
objective = cvx.ReturnsForecast()
- (GammaTradeCoarse() + GammaTradeFine()
) * cvx.StocksTransactionCost()
- risk_model,
constraints=[cvx.LongOnly(), cvx.LeverageLimit(LEVERAGE_LIMIT)],
benchmark=benchmark,
solver='CLARABEL')
# Optimize HPs.
simulator.optimize_hyperparameters(
policy, start_time=START, end_time=END,
objective='information_ratio')
print('Policy with optimized hyper-parameters:')
print(policy)
current_result['Optimized policy'] = repr(policy)
# Run back-test with optimized HPs.
optimized_result = simulator.backtest(
policy, start_time=START, end_time=END)
print('Back-test result with optimized hyper-parameters:')
print(optimized_result)
current_result['Optimized result'] = optimized_result
pprint(results)
```
--------------------------------
### Execute Ranking and SPO Example
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/paper_examples/rank_and_spo.rst.txt
This script demonstrates ranking and SPO strategies. It is a translation of the original IPython notebook using the stable Cvxportfolio API.
```python
import cvxportfolio as cvx
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# ... (rest of the file content from line 35 onwards) ...
```
--------------------------------
### Run Cvxportfolio Unit Tests
Source: https://www.cvxportfolio.com/en/1.5.0/index.html
Execute the unit test suite for Cvxportfolio in your local environment to verify the installation and functionality.
```bash
python -m cvxportfolio.tests
```
--------------------------------
### Import Libraries and Define Universe
Source: https://www.cvxportfolio.com/en/1.5.0/examples/market_neutral_nocosts.html
Imports necessary libraries and defines the universe of stocks for the strategy. This setup is required before defining strategy parameters.
```python
import numpy as np
import cvxportfolio as cvx
from .universes import DOW30, NDX100, SP500
# these are a little more than 500 names, all large cap US stocks
UNIVERSE = sorted(set(DOW30 + NDX100 + SP500))
target_volatility = 0.05 / np.sqrt(252) # annual std
# you can try different risk models (also combining some)
```
--------------------------------
### Real-time Optimization Script
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/paper_examples/real_time_optimization.rst.txt
This script demonstrates real-time portfolio optimization using the Cvxportfolio library. It is based on the paper examples provided in the repository.
```python
import cvxportfolio as cvx
import pandas as pd
import numpy as np
# ... (The actual content of the file is included via literalinclude from lines 35 onwards)
```
--------------------------------
### Backtest with Risk-Constrained Policy
Source: https://www.cvxportfolio.com/en/1.5.0/constraints.html
Integrate risk constraints into a backtesting policy using SinglePeriodOptimization. This example shows how to apply a covariance limit.
```python
import cvxportfolio as cvx
# limit the covariance
risk_limit = cvx.FullCovariance() <= target_volatility**2
# or, since Cvxportfolio 1.4.0
risk_limit_annualized = cvx.FullCovariance() <= cvx.AnnualizedVolatility(
0.05) # means 5% annualized
cvx.MarketSimulator(universe).backtest(
cvx.SinglePeriodOptimization(
cvx.ReturnsForecast(), [risk_limit])).plot()
```
--------------------------------
### Import Cvxportfolio Library
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/multi_period_opt.html
This snippet imports the Cvxportfolio library for use in optimization tasks. Ensure the library is installed before running.
```python
"""*Work in progress. *"""
import cvxportfolio as cvx
```
--------------------------------
### Define a Markowitz Optimization Strategy
Source: https://www.cvxportfolio.com/en/1.5.0/manual.html
Example of creating a SinglePeriodOptimization policy using ReturnsForecast and FullCovariance objectives with LongOnly and LeverageLimit constraints.
```python
objective = cvx.ReturnsForecast() - 0.5 * cvx.FullCovariance()
constraints = [cvx.LongOnly(), cvx.LeverageLimit(1)]
strategy = cvx.SinglePeriodOptimization(objective, constraints)
```
--------------------------------
### run_backtest() / backtest()
Source: https://www.cvxportfolio.com/en/1.5.0/simulator.html
Runs a single backtest for a given trading policy. It allows specifying start and end times, initial portfolio value, and an initial portfolio composition.
```APIDOC
## POST /backtest
### Description
Runs a single backtest for a given trading policy.
### Method
POST
### Endpoint
/backtest
### Parameters
#### Request Body
- **policy** (cvxportfolio.policies.Policy) - Required - Trading policy.
- **start_time** (str or pandas.Timestamp) - Required - Start time of the back-test.
- **end_time** (str or pandas.Timestamp or None) - Optional - End time of the back-test.
- **initial_value** (float) - Optional - Initial value in dollar of the portfolio. Defaults to 1,000,000.0.
- **h** (pandas.Series or None) - Optional - Initial portfolio h expressed in cash units. If None, initial_value is used.
### Request Example
```json
{
"policy": "",
"start_time": "2023-01-01",
"end_time": "2023-12-31",
"initial_value": 1000000.0,
"h": null
}
```
### Response
#### Success Response (200)
- **result** (cvxportfolio.BacktestResult) - Back-test result with all relevant data and metrics.
#### Response Example
```json
{
"result": ""
}
```
```
--------------------------------
### Compare Risk Models in Cvxportfolio
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/risk_models.rst.txt
This script compares different risk models available in Cvxportfolio. It requires the library to be installed and may involve specific data loading or setup not shown here.
```python
import cvxportfolio as cp
# Load the data
market_data = cp.MarketData.from_cvxpy_data(cp.data.load_cvxpy_data())
# Define the universe of assets
assets = market_data.universe
# Define the time periods for comparison
times = market_data.times
# Initialize the portfolio object
portfolio = cp.Portfolio(market_data=market_data)
# Define the risk models to compare
risk_models = [
cp.FullCovariance(),
cp.DiagonalCovariance(),
cp.FactorModelShocks(),
cp.FactorModel(cp.FactorModelShocks(), cp.FactorModelCovariance()),
]
# Compare the risk models
results = portfolio.compare_risk_models(risk_models, times=times)
# Print the results
print(results)
```
--------------------------------
### MarketData.trading_calendar
Source: https://www.cvxportfolio.com/en/1.5.0/data.html
Retrieves the trading calendar between specified start and end times.
```APIDOC
## GET MarketData.trading_calendar
### Description
Get trading calendar between times.
### Parameters
#### Query Parameters
- **start_time** (pandas.Timestamp) - Optional - Initial time of the trading calendar. Always inclusive if present. If None, use the first available time.
- **end_time** (pandas.Timestamp) - Optional - Final time of the trading calendar. If None, use the last available time.
- **include_end** (bool) - Optional - Include end time.
### Response
#### Success Response (200)
- **Returns** (pd.DatetimeIndex) - Trading calendar.
```
--------------------------------
### Initialize SinglePeriodOptimization Policy
Source: https://www.cvxportfolio.com/en/1.5.0/constraints.html
Sets up a single-period optimization policy with a given objective and a list of constraints. The backtest method then simulates the policy's performance.
```python
policy = cvx.SinglePeriodOptimization(objective, constraints)
print(cvx.MarketSimulator(universe).backtest(policy))
```
--------------------------------
### GET /trading_calendar
Source: https://www.cvxportfolio.com/en/1.5.0/data.html
Retrieves the trading calendar based on the available market data.
```APIDOC
## GET /trading_calendar
### Description
Get trading calendar from market data.
### Parameters
#### Query Parameters
- **start_time** (pandas.Timestamp) - Optional - Initial time of the trading calendar.
- **end_time** (pandas.Timestamp) - Optional - Final time of the trading calendar.
- **include_end** (bool) - Optional - Include end time.
### Response
#### Success Response (200)
- **Returns** (pandas.DatetimeIndex) - The trading calendar.
```
--------------------------------
### GET /serve
Source: https://www.cvxportfolio.com/en/1.5.0/data.html
Retrieves market data for a specific point in time for use by policies and simulators.
```APIDOC
## GET /serve
### Description
Serve data for policy and simulator at time t.
### Parameters
#### Query Parameters
- **t** (pandas.Timestamp) - Required - Time of execution.
### Response
#### Success Response (200)
- **Returns** (tuple) - (past_returns, current_returns, past_volumes, current_volumes, current_prices)
```
--------------------------------
### Configure and Run Back-Test with Caching
Source: https://www.cvxportfolio.com/en/1.5.0/examples/timing.html
Sets up a single-period optimization policy, including objectives and constraints, and then runs a back-test simulation twice to demonstrate the performance difference due to covariance matrix caching. The first run estimates and saves matrices, while the second loads them from disk.
```python
import time
import matplotlib.pyplot as plt
import pandas as pd
import cvxportfolio as cvx
# same choice as in the paper
from .universes import SP500 as UNIVERSE
# changing these may have some effect on the solver time, but small
GAMMA_RISK = 1.
GAMMA_TRADE = 1.
GAMMA_HOLD = 1.
# the solve time grows (approximately) linearly with this. 15 is the same
# number we had in the paper examples
NUM_RISK_FACTORS = 15
# if you change this to 2 (quadratic model) the resulting program is a QP
# and can be solved faster
TCOST_EXPONENT = 1.5
# you can add any constraint or objective
# term to see how it affects execution time
policy = cvx.SinglePeriodOptimization(
objective = cvx.ReturnsForecast()
- GAMMA_RISK * cvx.FactorModelCovariance(
num_factors=NUM_RISK_FACTORS)
- GAMMA_TRADE * cvx.StocksTransactionCost(exponent=TCOST_EXPONENT)
- GAMMA_HOLD * cvx.StocksHoldingCost(),
constraints = [
cvx.LeverageLimit(3),
],
# You can select any CVXPY-interfaced solver here to see how it affects
# execution time of your particular program. Different solvers apply
# different roundings and other numerical heuristics; their solutions
# may also have (small) differences in other back-test statistics, such
# as Sharpe Ratio. This solver is the default one for this
# type of programs, as of CVXPY 1.5.0. Other freely available solvers
# that work well for this type of programs are for example CVXOPT, ECOS
# and SCS. There are numerous commercial ones as well. See the CVXPY
# documentation for the full list
# https://www.cvxpy.org/tutorial/solvers/index.html
solver='CLARABEL',
# this is a CVXPY compilation flag, it is recommended for large
# optimization programs (like this one) but not for small ones
ignore_dpp=True,
# you can add any other cvxpy.Problem.solve option
# here, see https://www.cvxpy.org/tutorial/advanced/index.html
)
# this downloads data for all the sp500
simulator = cvx.StockMarketSimulator(UNIVERSE)
# we repeat two times to see the difference due to estimation and saving
# of covariance matrices (the first run), and loading them from disk the
```
--------------------------------
### Instantiate Custom Forecasters and Parameters
Source: https://www.cvxportfolio.com/en/1.5.0/examples/user_provided_forecasters.html
Set hyper-parameters for forecasting windows and risk/trade gammas, then instantiate the custom forecasters for expected returns and covariances.
```python
# define the hyper-parameters
WINDOWMU = 252
WINDOWSIGMA = 252
GAMMA_RISK = 5
GAMMA_TRADE = 3
# define the forecasters
mean_return_forecaster = WindowMeanReturns(WINDOWMU)
covariance_forecaster = WindowCovariance(WINDOWSIGMA)
```
--------------------------------
### Clone the Cvxportfolio repository
Source: https://www.cvxportfolio.com/en/1.5.0/contributing.html
Initial steps to download the source code for local development.
```bash
git clone https://github.com/cvxgrp/cvxportfolio.git
cd cvxportfolio
```
--------------------------------
### Market Simulator and Hyper-parameter Optimization
Source: https://www.cvxportfolio.com/en/1.5.0/examples/market_neutral.html
Initializes a MarketSimulator with specified universe and costs, then optimizes the policy's hyper-parameters using a greedy grid search based on Sharpe ratio.
```python
simulator = cvx.MarketSimulator(
universe=UNIVERSE,
costs = [
cvx.TransactionCost(a=SPREAD/2, b=MARKET_IMPACT),
cvx.HoldingCost(short_fees=BORROW_FEES)])
# automatic hyper-parameter optimization (by greedy grid search)
simulator.optimize_hyperparameters(
policy, start_time=START, end_time=END,
objective='sharpe_ratio')
```
--------------------------------
### Define Markowitz Optimization Strategy
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/manual.rst.txt
Example of creating a single-period optimization strategy using returns forecast and covariance terms.
```python
objective = cvx.ReturnsForecast() - 0.5 * cvx.FullCovariance()
constraints = [cvx.LongOnly(), cvx.LeverageLimit(1)]
strategy = cvx.SinglePeriodOptimization(objective, constraints)
```
--------------------------------
### Configure SinglePeriodOptimization Policy
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/manual.rst.txt
Demonstrates how to instantiate a SinglePeriodOptimization policy with custom objective, constraints, and solver-specific keyword arguments passed to CVXPY.
```python
policy = cvx.SinglePeriodOptimization(
objective = cvx.ReturnsForecast(),
constraints = [
cvx.FullCovariance() <= target_daily_vol**2,
cvx.LongOnly(),
cvx.LeverageLimit(1),
]
# the following **kwargs are passed to cvxpy.Problem.solve
solver='SCS',
eps=1e-14,
verbose=True,
)
```
--------------------------------
### Run Multiple Back-tests and Plot Results
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/hello_world.html
Execute multiple back-tests with different policies and plot the portfolio total value and weights. Ensure necessary libraries like matplotlib are imported for plotting.
```python
results = market_sim.run_multiple_backtest(
h=[init_portfolio]*2,
start_time='2013-01-03', end_time='2016-12-31',
policies=[spo_policy, cvx.Hold()])
print('Back-test result, single-period optimization policy:')
print(results[0])
print('Back-test result, Hold policy:')
print(results[1])
results[0].v.plot(label='SPO')
results[1].v.plot(label='Hold policy')
plt.title('Portfolio total value in time (USD)')
plt.legend()
plt.show()
results[0].w.plot()
plt.title('SPO weights in time')
plt.show()
```
--------------------------------
### Estimate Historical Mean Return
Source: https://www.cvxportfolio.com/en/1.5.0/forecasts.html
Example of estimating historical mean return using MarketData. Requires MarketData to be initialized with desired assets.
```python
md = cvx.DownloadedMarketData(['AAPL', 'MSFT', 'GOOG'])
cvx.forecast.HistoricalCovariance().estimate(
market_data=md, t=md.trading_calendar()[-3])
```
--------------------------------
### Configure git hooks
Source: https://www.cvxportfolio.com/en/1.5.0/contributing.html
Commands to set up pre-commit and pre-push hooks for linting and testing.
```bash
echo "make lint" > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
echo "make test" > .git/hooks/pre-push
chmod +x .git/hooks/pre-push
```
--------------------------------
### Limit Covariance with Risk Constraint
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/constraints.rst.txt
Limit the portfolio's covariance to a target volatility squared. This example shows a basic risk constraint.
```python
import cvxportfolio as cvx
# limit the covariance
risk_limit = cvx.FullCovariance() <= target_volatility**2
```
--------------------------------
### Backtest Many Policies with Grid Search
Source: https://www.cvxportfolio.com/en/1.5.0/examples/etfs.html
This script sets up a stock market simulator with a universe of ETFs and defines a function to create Multi Period Optimization policies. It then performs a grid search over `gamma_trade` and `gamma_risk` parameters, backtests many policies in parallel, and identifies the policies with the largest Sharpe ratio and growth rate. Use this for hyperparameter tuning and policy comparison.
```python
import numpy as np
import cvxportfolio as cvx
UNIVERSE = [
"QQQ", # nasdaq 100
"SPY", # US large caps
'EFA', # EAFE stocks
"CWB", # convertible bonds
"IWM", # US small caps
"EEM", # EM stocks
"GLD", # Gold
'TLT', # long duration treasuries
'HYG', # high yield bonds
"EMB", # EM bonds (usd)
'LQD', # investment grade bonds
'PFF', # preferred stocks
'VNQ', # US REITs
'BND', # US total bond market
'BIL', # US cash
'TIP', # TIPS
'DBC', # commodities
]
sim = cvx.StockMarketSimulator(UNIVERSE, trading_frequency='monthly')
def make_policy(gamma_trade, gamma_risk):
"""Create policy object given hyper-parameter values.
:param gamma_trade: Choice of the trading aversion multiplier.
:type gamma_trade: float
:param gamma_risk: Choice of the risk aversion multiplier.
:type gamma_risk: float
:returns: Policy object with given choices of hyper-parameters.
:rtype: cvx.policies.Policy instance
"""
return cvx.MultiPeriodOptimization(cvx.ReturnsForecast()
- gamma_risk * cvx.FactorModelCovariance(num_factors=10)
- gamma_trade * cvx.StocksTransactionCost(),
[cvx.LongOnly(), cvx.LeverageLimit(1)],
planning_horizon=6, solver='ECOS')
keys = [(gamma_trade, gamma_risk)
for gamma_trade in np.array(range(10))/10
for gamma_risk in [.5, 1, 2, 5, 10]]
ress = sim.backtest_many(
[make_policy(*key) for key in keys], parallel=True)
print('LARGEST SHARPE RATIO')
idx = np.argmax([el.sharpe_ratio for el in ress])
print('gamma_trade and gamma_risk')
print(keys[idx])
print('result')
print(ress[idx])
largest_sharpe_figure = ress[idx].plot()
print('LARGEST GROWTH RATE')
idx = np.argmax([el.growth_rates.mean() for el in ress])
print('gamma_trade and gamma_risk')
print(keys[idx])
print('result')
print(ress[idx])
largest_growth_figure = ress[idx].plot()
```
--------------------------------
### Define and Backtest Policy with Cvxportfolio
Source: https://www.cvxportfolio.com/en/1.5.0/examples/user_provided_forecasters.html
Define a single-period optimization policy including return forecasts, full covariance risk, and transaction costs. Then, set up a stock market simulator and run a back-test. This is useful for evaluating trading strategies in a historical context.
```python
policy = cvx.SinglePeriodOptimization(
objective = cvx.ReturnsForecast(r_hat = mean_return_forecaster)
- GAMMA_RISK * cvx.FullCovariance(Sigma = covariance_forecaster)
- GAMMA_TRADE * cvx.StocksTransactionCost(),
constraints = [cvx.LongOnly(), cvx.LeverageLimit(1)]
)
simulator = cvx.StockMarketSimulator(['AAPL', 'GOOG', 'MSFT', 'AMZN'])
result = simulator.backtest(policy, start_time='2020-01-01')
print(result)
figure = result.plot()
```
--------------------------------
### Define Optimization Cost and Risk Models
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/rank_and_spo.html
Initializes cost models and a factor-based risk model using cvxportfolio estimators.
```python
optimization_tcost = paper_optimization_tcost_model()
optimization_hcost = paper_hcost_model()
return_estimate = paper_returns_forecast()
factor_exposures, factor_sigma, idyosincratic = paper_risk_model()
risk_model = cvx.FactorModelCovariance(
F=cvx.estimator.DataEstimator(
factor_exposures, use_last_available_time=True,
compile_parameter=True),
d=cvx.estimator.DataEstimator(
idyosincratic, use_last_available_time=True),
Sigma_F=cvx.estimator.DataEstimator(
factor_sigma, use_last_available_time=True,
ignore_shape_check=True))
```
--------------------------------
### Configure Yahoo Finance Data Cleaning
Source: https://www.cvxportfolio.com/en/1.5.0/examples/data_cleaning.html
Setup script to analyze data cleaning heuristics for specific stock tickers using the Cvxportfolio library.
```python
from pathlib import Path
from tempfile import TemporaryDirectory
from time import sleep
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import cvxportfolio as cvx
# Here you can put any stocks for which you wish to analyze the cleaning;
# Some names with known issues:
TEST_UNIVERSE = ['SMT.L', 'NVR', 'HUBB', 'NWG.L', 'BA.L']
# Or, pick a larger universe
# from .universes import *
```
--------------------------------
### StockMarketSimulator Initialization
Source: https://www.cvxportfolio.com/en/1.5.0/simulator.html
Initializes the simulator for the stock market with default costs and parameters.
```APIDOC
## StockMarketSimulator
### Description
Initializes the StockMarketSimulator for the stock market with realistic default costs and parameters.
### Parameters
- **universe** (list) - Optional - List of Yahoo Finance stock names.
- **cash_key** (str) - Optional - Name of the cash account (e.g., 'USDOLLAR'). Default 'USDOLLAR'.
- **trading_frequency** (str or None) - Optional - Down-sampling frequency ('weekly', 'monthly', 'quarterly', 'annual').
- **base_location** (pathlib.Path) - Optional - Location of the storage.
- **costs** (list) - Optional - List of SimulatorCost classes or instances.
- **round_trades** (bool) - Optional - Round trades to integer number of shares. Default True.
- **max_fraction_liquidity** (float or None) - Optional - Cut trades to a maximum fraction of market liquidity. Default 0.05.
- **reject_trades_below** (float) - Optional - Minimum absolute size of a trade in cash units.
```
--------------------------------
### Include HoldingCost in Optimization Policy
Source: https://www.cvxportfolio.com/en/1.5.0/costs.html
Integrate HoldingCost into an optimization policy's objective function to penalize borrowing costs. This example shows a 10% annualized borrowing cost.
```python
policy = cvx.SinglePeriodOptimization(
objective = cvx.ReturnsForecast()
- 0.5 * cvx.FullCovariance()
- cvx.HoldingCost(short_fees=10),
constraints = [cvx.LeverageLimit(3)])
```
--------------------------------
### MarketNeutral Constraint Initialization
Source: https://www.cvxportfolio.com/en/1.5.0/constraints.html
Creates a market-neutral constraint using a specified benchmark policy. The benchmark can be a class or an instance, and parameters for covariance estimation can be provided.
```python
# (wtb)TΣt(wt+zt)=0
```
--------------------------------
### MarketSimulator and StockMarketSimulator Methods
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/simulator.rst.txt
Documentation for backtesting and optimization methods available in the simulator classes.
```APIDOC
## MarketSimulator and StockMarketSimulator Methods
### Description
These classes provide functionality to perform backtests on market data and optimize hyperparameters for portfolio strategies.
### Methods
- **backtest**: Executes a single backtest simulation.
- **run_backtest**: Alias for backtest.
- **backtest_many**: Executes multiple backtest simulations.
- **run_multiple_backtest**: Alias for backtest_many.
- **optimize_hyperparameters**: Performs optimization of hyperparameters for the simulator.
```
--------------------------------
### Define Single Period Optimization Policy
Source: https://www.cvxportfolio.com/en/1.5.0/returns.html
Defines a single period optimization policy using default historical means for returns and full covariance for risk. This is a common setup for basic portfolio optimization.
```python
>>> import cvxportfolio as cvx
>>> policy = cvx.SinglePeriodOptimization(cvx.ReturnsForecast() - \
0.5 * cvx.FullCovariance(), [cvx.LongOnly(), cvx.LeverageLimit(1)])
>>> cvx.MarketSimulator(['AAPL', 'MSFT', 'GOOG']).backtest(policy).plot()
```
--------------------------------
### Measure Solution Time in Cvxportfolio
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/paper_examples/solution_time.rst.txt
This script demonstrates the performance measurement of portfolio optimization tasks using the Cvxportfolio library.
```python
import cvxportfolio as cvx
import pandas as pd
import numpy as np
import time
# Define the universe and market data
# (Assuming market data is already loaded as 'market_data')
# Define the optimization policy
policy = cvx.SinglePeriodOpt(
cvx.ReturnsForecast() - 0.5 * cvx.FullCovariance(),
[cvx.LeverageLimit(3), cvx.LongOnly()]
)
# Run the backtest and measure time
start_time = time.time()
backtest = cvx.Backtest(policy, market_data)
result = backtest.run()
end_time = time.time()
print(f"Solution time: {end_time - start_time:.2f} seconds")
```
--------------------------------
### Download Market Data with yfinance and pandas_datareader
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/hello_world.html
Downloads historical adjusted closing prices for specified tickers using yfinance and US Treasury rates from FRED using pandas_datareader. Requires 'yfinance' and 'pandas_datareader' to be installed.
```python
"""This is a simple example of back-tests with Cvxportfolio.
This is a close translation of what was done in `this notebook
`_.
In fact, you can see that the results are identical.
The approach used here is not recommended; in particular we download
data externally (it is done better now by the automatic data download
and cleaning code we include in Cvxportfolio). The returns used here
are close-to-close total returns, while our interface computes correctly
the open-to-open total returns.
In this example returns and covariances are forecasted externally,
while today this can be done automatically using the default forecasters
used by :class:`cvxportfolio.ReturnsForecast` and
:class:`cvxportfolio.FullCovariance`.
Nevertheless, you can see by running this that we are still able to
reproduce exactly the behavior of the early development versions
of the library.
.. note::
To run this, you need to install ``yfinance`` and
``pandas_datareader``.
"""
import matplotlib.pyplot as plt
import pandas as pd
import pandas_datareader as pdr
import yfinance
import cvxportfolio as cvx
# Download market data
tickers = ['AMZN', 'GOOGL', 'TSLA', 'NKE']
returns = pd.DataFrame(dict([(ticker,
yfinance.download(ticker)['Adj Close'].pct_change())
for ticker in tickers]))
returns["USDOLLAR"] = pdr.get_data_fred(
'DFF', start="1900-01-01",
end=pd.Timestamp.today())['DFF']/(252*100)
returns = returns.fillna(method='ffill').iloc[1:]
print('Returns')
print(returns)
# Create market data server.
market_data = cvx.UserProvidedMarketData(
returns = returns,
cash_key = 'USDOLLAR')
# Today we'd do all the above by (no external packages needed):
# market_data = cvx.DownloadedMarketData(
# universe = ['AMZN', 'GOOGL', 'TSLA', 'NKE'],
# cash_key = 'USDOLLAR')
print('Historical returns:')
print(market_data.returns)
# Build forecasts of expected returns and covariances.
# Note that we shift so that each day we use ones built
# using past returns only. This is done automatically
# by the forecasters used by default in the stable versions
# of Cvxportfolio.
r_hat_with_cash = market_data.returns.rolling(
window=250).mean().shift(1).dropna()
Sigma_hat_without_cash = market_data.returns.iloc[:, :-1
].rolling(window=250).cov().shift(4).dropna()
r_hat = r_hat_with_cash.iloc[:, :-1]
r_hat_cash = r_hat_with_cash.iloc[:, -1]
print('Expected returns forecast:')
print(r_hat_with_cash)
# Define transaction and holding cost models.
# Half spread.
HALF_SPREAD = 10E-4
# In the 2016 development code borrow fees were expressed per-period.
# In the stable version we require annualized percent.
# This value corresponds to 1 basis point per period, which was in the
# original example.
BORROW_FEE = 2.552
tcost_model = cvx.TcostModel(a=HALF_SPREAD, b=None)
hcost_model = cvx.HcostModel(short_fees=BORROW_FEE)
# As risk model, we use the historical covariances computed above.
# Note that the stable version of Cvxportfolio requires the covariance
# matrix to not include cash (as it shouldn't). In the development versions
# it was there. It doesn't make any difference in numerical terms.
risk_model = cvx.FullSigma(Sigma_hat_without_cash)
# Constraint.
leverage_limit = cvx.LeverageLimit(3)
# Define a single-period optimization policy; its objective function is
# maximized.
gamma_risk, gamma_trade, gamma_hold = 5., 1., 1.
spo_policy = cvx.SinglePeriodOpt(
objective = cvx.ReturnsForecast(r_hat) + cvx.CashReturn(r_hat_cash)
- gamma_risk * risk_model
- gamma_trade * tcost_model
- gamma_hold * hcost_model,
constraints=[leverage_limit],
include_cash_return=False)
# Define the market simulator.
market_sim = cvx.MarketSimulator(
market_data = market_data,
costs = [
cvx.TcostModel(a=HALF_SPREAD, b=None),
cvx.HcostModel(short_fees=BORROW_FEE)])
# Initial portfolio, uniform on non-cash assets.
init_portfolio = pd.Series(
index=market_data.returns.columns, data=250000.)
init_portfolio.USDOLLAR = 0
```
--------------------------------
### Instantiate ReturnsForecast with HistoricalMeanReturn
Source: https://www.cvxportfolio.com/en/1.5.0/forecasts.html
Instantiate ReturnsForecast with HistoricalMeanReturn, applying exponential smoothing with a 1-year half-life and ignoring observations older than 5 years.
```python
import cvxportfolio as cvx
from cvxportfolio.forecast import HistoricalMeanReturn
import pandas as pd
returns_forecast = cvx.ReturnsForecast(
r_hat = HistoricalMeanReturn(
half_life=pd.Timedelta(days=365),
rolling=pd.Timedelta(days=365*5)))
```
--------------------------------
### User-Provided Forecaster Implementation
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/user_provided_forecasters.rst.txt
This Python script defines and utilizes custom forecasters for Cvxportfolio. It is designed to be executed as a standalone example. Note that custom forecasters may have slower execution times compared to optimized built-in forecasters.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
from cvxportfolio.forecast import Forecaster
class MyForecaster(Forecaster):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.data = pd.read_csv(
"../data/prices.csv", index_col=0, parse_dates=True
)
self.returns = self.data.pct_change().dropna()
def forecast(self, time_t, values, יודע_future_prices):
# we are given the current time, the current values of the assets, and the future prices
# we can use this information to compute the forecast
# in this example, we will just use the historical average return
# for the next period
return self.returns.loc[time_t:].mean().values
class MyForecaster2(Forecaster):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.data = pd.read_csv(
"../data/prices.csv", index_col=0, parse_dates=True
)
self.returns = self.data.pct_change().dropna()
def forecast(self, time_t, values, יודע_future_prices):
# we are given the current time, the current values of the assets, and the future prices
# we can use this information to compute the forecast
# in this example, we will just use the historical average return
# for the next period
return self.returns.loc[time_t:].mean().values
if __name__ == "__main__":
import matplotlib.pyplot as plt
# load the data
prices = pd.read_csv(
"../data/prices.csv", index_col=0, parse_dates=True
)
returns = prices.pct_change().dropna()
# define the universe of assets
universe = prices.columns.tolist()
# define the portfolio optimization problem
# we will use a simple mean-variance optimization
# with a risk aversion of 1
sigma = returns.cov().to_numpy()
mu = returns.mean().to_numpy()
risk_aversion = 1.0
# define the forecasters
forecaster1 = MyForecaster()
forecaster2 = MyForecaster2()
# define the policy
policy = cp.FixedPolicy(weights=pd.Series(1/len(universe), index=universe))
# define the simulator
simulator = cp.Simulator(
returns=returns,
initial_time=returns.index[0],
market_friction=cp.MarketUS(trading_costs=0.0001),
forecasters=forecaster1,
sigma=sigma,
risk_aversion=risk_aversion,
policy=policy,
cash_key="USDOLLAR",
costs=cp.Transaction(0.0001),
)
# run the backtest
result = simulator.run_backtest()
# print the results
print(result.summary())
```
--------------------------------
### Execute Backtests and Compare Strategies
Source: https://www.cvxportfolio.com/en/1.5.0/examples/paper_examples/rank_and_spo.html
Runs backtests for the RankAndLongShort policy and a SinglePeriodOpt policy, then prints the results.
```python
rank_and_long_short = PaperRankAndLongShort(
return_forecast=return_estimate, num_short=10,
num_long=10,
target_turnover=0.005) # in the orig. example TO was off by factor of 2
result_rank = simulator.run_backtest(
h=1e8 * w_b, start_time=start_t, end_time=end_t, policy=rank_and_long_short
)
print('RESULT RANK-AND-LONG-SHORT')
print(result_rank)
spo = cvx.SinglePeriodOpt(
cvx.ReturnsForecast(return_estimate) - 10 * risk_model
- 7. * optimization_tcost - 10. * optimization_hcost,
[cvx.LeverageLimit(3)])
result_spo = simulator.run_backtest(
h=1e8 * w_b, start_time=start_t, end_time=end_t, policy=spo
)
print('RESULT SPO')
print(result_spo)
```
--------------------------------
### Data Cleaning Script
Source: https://www.cvxportfolio.com/en/1.5.0/_sources/examples/data_cleaning.rst.txt
This Python script performs data cleaning on financial time series data. It handles common issues found in data from sources like Yahoo Finance. Ensure necessary libraries are installed before execution.
```python
import cvxportfolio as cp
import pandas as pd
import matplotlib.pyplot as plt
# load the data
prices = pd.read_csv("../data/prices.csv", index_col=0, parse_dates=True)
returns = pd.read_csv("../data/returns.csv", index_col=0, parse_dates=True)
# data cleaning
# we use this to save the plots
```