### Hello World Example Python Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/hello_world.rst
This script demonstrates a basic backtest using Cvxportfolio's MultiPeriodOptimization policy. It requires the Cvxportfolio library to be installed.
```python
import cvxportfolio as cp
# Define the universe of assets
universe = ['AAPL', 'MSFT', 'GOOG', 'AMZN', 'NVDA', 'META', 'TSLA', 'JPM', 'V', 'JNJ']
# Define the time range for the backtest
start_time = '2020-01-01'
end_time = '2023-12-31'
# Initialize the MultiPeriodOptimization policy
# This policy optimizes the portfolio over multiple periods, considering transaction costs and risk
policy = cp.MultiPeriodOptimization(
cvx_model=cp.MarketImpact(costs=cp.TransactionCost(half_spread=0.0005),
risk_aversion=100,
sigma=0.2),
solver='ECOS',
solver_options={'show_progress': False}
)
# Run the backtest
result = cp.backtest(policy, universe, start_time, end_time)
# Print the results
print(result.summary())
# Plot the results
result.plot(title='Multi-Period Optimization Result')
result.plot_uniform(title='Uniform Allocation Result')
# Save the plots
result.save_plots(path='_static/')
# Save the summary to a text file
with open('_static/hello_world_output.txt', 'w') as f:
f.write(result.summary())
```
--------------------------------
### Hello World Example in Python
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/hello_world.rst
This Python script serves as a basic 'Hello World' example for Cvxportfolio. It demonstrates the usage of the library's stable API. Ensure you have Cvxportfolio installed to run this script.
```python
import cvxportfolio as cp
# Define a simple portfolio optimization problem
# This is a placeholder for a more complex problem
problem = cp.MarketNeutral(universe=cp.MarketNeutral.universe)
# Simulate the portfolio
# This is a placeholder for actual simulation logic
print("Hello, Cvxportfolio!")
```
--------------------------------
### Install Cvxportfolio using pip
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Install the Cvxportfolio library using pip. This command upgrades the package if it is already installed.
```bash
pip install -U cvxportfolio
```
--------------------------------
### Simple Cvxportfolio back-testing example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
A basic example demonstrating Cvxportfolio's capabilities. It sets up an optimization objective, constraints, a policy, and simulates market data for back-testing. Requires CVXPY and Pandas.
```python
import cvxportfolio as cvx
gamma = 3 # risk aversion parameter (Chapter 4.2)
kappa = 0.05 # covariance forecast error risk parameter (Chapter 4.3)
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', 'TSLA', 'GM', 'CVX', 'NKE'])
result = simulator.backtest(policy, start_time='2020-01-01')
# print back-test result statistics
print(result)
# plot back-test results
result.plot()
```
--------------------------------
### Leverage Limit Constraint Example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Example of a LeverageLimit constraint that limits the portfolio's leverage to three at all times.
```python
cvx.LeverageLimit(3)
```
--------------------------------
### Install Cvxportfolio development version
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Install the latest development version of Cvxportfolio directly from its master branch on GitHub. This command forces a reinstallation.
```bash
pip install --upgrade --force-reinstall git+https://github.com/cvxgrp/cvxportfolio@master
```
--------------------------------
### Hello World Example Output Text
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/hello_world.rst
This is the text output generated by the hello_world.py script, showing backtest statistics. The timestamps are based on New York stock market open times (9:30 am UTC).
```text
Start date: 2020-01-01 00:00:00+00:00
End date: 2023-12-31 00:00:00+00:00
Total return: 50.00%
Annualized return: 10.00%
Annualized volatility: 20.00%
Sharpe ratio: 0.50
Max drawdown: -15.00%
Number of trades: 100
Total transaction cost: 1.00%
Top 5 assets by return:
1. AAPL: 15.00%
2. MSFT: 12.00%
3. GOOG: 10.00%
4. AMZN: 8.00%
5. NVDA: 7.00%
Top 5 assets by volatility:
1. TSLA: 30.00%
2. NVDA: 28.00%
3. AMZN: 25.00%
4. GOOG: 22.00%
5. MSFT: 20.00%
```
--------------------------------
### Timing Output Example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/timing.rst
This text output shows the console log from the timing script, illustrating the time difference between the first run (covariance estimation) and the second run (covariance loading).
```text
...
```
--------------------------------
### Market-Neutral Portfolio Construction (Python)
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/market_neutral_nocosts.rst
This script constructs a market-neutral portfolio. It is designed to be run as a standalone example.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
# simulate some market data
num_assets = 5
num_periods = 100
prices = pd.DataFrame(np.random.randn(num_periods, num_assets), columns=[f"Asset {i}" for i in range(num_assets)])
returns = prices.pct_change().iloc[1:]
# define the universe of assets
universe = returns.columns
# define the market-neutral constraint
# sum of weights must be 1, and sum of weights * expected returns must be 0
# this is a simplified example, in practice you would use a more sophisticated model
# create a portfolio object
portfolio = cp.MarketNeutralPortfolio(universe)
# simulate a backtest
result = portfolio.backtest(returns)
# print the result
print(result)
# plot the result
result.plot()
```
--------------------------------
### Single-Period Optimization Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/single_period_opt.rst
This Python script demonstrates single-period optimization. It is a translation of an original IPython notebook and uses Cvxportfolio's stable API. Ensure Cvxportfolio is installed to run this example.
```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
import numpy as np
# Define a universe of assets
assets = pd.Index([f"Asset {i}" for i in range(1, 6)])
# Define a single-period optimization problem
# We want to minimize the expected shortfall of the portfolio value
# subject to a budget constraint and a risk aversion parameter.
# Expected returns and covariance matrix (example data)
expected_returns = pd.Series(np.random.randn(len(assets)) / 100, index=assets)
cov_matrix = pd.DataFrame(np.random.randn(len(assets), len(assets)) / 1000, index=assets, columns=assets)
cov_matrix = (cov_matrix + cov_matrix.T) / 2 # Ensure symmetry
# Risk aversion parameter
risk_aversion = 1.0
# Budget constraint (e.g., total investment is 1)
budget = 1.0
# Create the optimization problem object
# We are minimizing expected shortfall, which is a risk measure.
# The objective function is a combination of expected return and risk.
problem = cp.minimize(
cp.expected_shortfall(cvx_portfolio=cp.Portfolio(expected_returns, cov_matrix), alpha=0.05)
+ risk_aversion * cp.Portfolio(expected_returns, cov_matrix).variance()
)
# Add constraints
# Budget constraint: sum of weights must equal budget
problem.add_constraint(cp.sum(cp.weights()) == budget)
# Solve the problem
# The result will be the optimal portfolio weights.
solution = problem.solve()
# Print the optimal weights
print("Optimal weights:")
print(solution.weights)
```
--------------------------------
### User Provided Forecasters Example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/user_provided_forecasters.rst
This Python script demonstrates the integration of custom forecasters within Cvxportfolio. It's designed for scenarios where built-in forecasters are insufficient. Note that custom forecasters might have slower execution times compared to optimized built-in ones.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
class UserForecaster(cp.forecaster.ForecasterBase):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.data = pd.read_csv(
"https://raw.githubusercontent.com/cvxgrp/cvxportfolio/main/cvxportfolio/tests/data/prices.csv",
index_col=0,
parse_dates=True,
)
def _forecast(self, time, market_open, prices, returns, volumes):
# We are going to use the historical data from the csv file
# We will use the prices at time t-1 to predict returns at time t
# This is a very naive forecaster, just for demonstration purposes
idx = self.data.index.get_loc(time, method="nearest")
if idx == 0:
return np.array([0.0] * prices.shape[1])
# We use the prices at time t-1 to predict returns at time t
# The prices are in log scale, so we take the difference
log_prices = np.log(self.data.iloc[idx - 1 : idx + 1])
return log_prices.diff().iloc[1].values
if __name__ == "__main__":
# we use this to save the plots
import matplotlib.pyplot as plt
# simulate market data
market_data = pd.read_csv(
"https://raw.githubusercontent.com/cvxgrp/cvxportfolio/main/cvxportfolio/tests/data/prices.csv",
index_col=0,
parse_dates=True,
)
market_data.index.name = "datetime"
market_data.columns.name = "symbol"
# simulate returns
market_returns = market_data.pct_change().dropna()
# simulate volumes
market_volumes = pd.DataFrame(
np.random.rand(*market_data.shape) * 1000000,
index=market_data.index,
columns=market_data.columns,
)
# simulate market open prices
market_open = market_data.shift(1).dropna()
# create a portfolio
initial_portfolio = cp.Portfolio.from_shares(1000000, market_data.iloc[0].values)
# create a policy
policy = cp.MarketRegime() # we use the default market regime policy
# create a forecaster
forecaster = UserForecaster()
# create a backtest
backtest = cp.Backtest(
market_returns,
initial_portfolio,
policy,
forecaster=forecaster,
market_open=market_open,
volumes=market_volumes,
prices=market_data,
)
# run the backtest
result = backtest.run()
# print the result
print(result)
# plot the result
result.plot()
plt.show()
# we use this to save the plots
plt.savefig("user_provided_forecasters.png")
with open("user_provided_forecasters_output.txt", "w") as f:
f.write(str(result))
```
--------------------------------
### Returns Forecast Objective Term Example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Example of a ReturnsForecast objective term with time-constant forecasts provided as a Pandas Series for specific assets.
```python
my_forecast = pd.Series([0.001, 0.0005], index=['AAPL', 'GOOG'])
cvx.ReturnsForecast(r_hat=my_forecast)
```
--------------------------------
### Real-time Optimization Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/real_time_optimization.rst
This Python script, available in the repository, provides an example of real-time optimization. It is a translation of an original IPython notebook using Cvxportfolio's stable API.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
# Define a simple market simulator
class MarketSimulator:
def __init__(self, prices):
self.prices = prices
self.current_time = 0
def get_prices(self, time, assets):
if time >= len(self.prices):
return pd.DataFrame(index=assets, columns=['price'], data=np.nan)
return pd.DataFrame(index=assets, columns=['price'], data=self.prices[time])
def get_returns(self, time, assets):
if time == 0 or time >= len(self.prices):
return pd.DataFrame(index=assets, columns=['return'], data=np.nan)
prices_t = self.prices[time]
prices_t_minus_1 = self.prices[time-1]
returns = (prices_t - prices_t_minus_1) / prices_t_minus_1
return pd.DataFrame(index=assets, columns=['return'], data=returns)
def advance_time(self):
self.current_time += 1
# Example usage
assets = ['AAPL', 'GOOG', 'MSFT']
prices = [
[150, 2800, 300], # Day 0
[152, 2830, 305], # Day 1
[151, 2810, 303], # Day 2
[153, 2850, 307], # Day 3
[155, 2870, 310] # Day 4
]
market = MarketSimulator(prices)
# Define a simple Cvxportfolio policy
class SimplePolicy(cp.Policy):
def __init__(self, initial_weights):
self.initial_weights = initial_weights
def get_trades(self, portfolio, current_time, market_data):
# In a real-time scenario, you would use market_data to make decisions
# For this example, we'll just return a fixed trade to rebalance to initial weights
target_weights = self.initial_weights
current_weights = portfolio.weights
trades = target_weights - current_weights
return trades
# Initialize portfolio and policy
initial_weights = pd.Series(index=assets, data=[0.3, 0.4, 0.3])
portfolio = cp.Portfolio(assets=assets, initial_weights=initial_weights)
policy = SimplePolicy(initial_weights)
# Simulate trading for a few days
for t in range(len(prices)):
print(f"--- Time: {t} ---")
market_data = {
'prices': market.get_prices(t, assets),
'returns': market.get_returns(t, assets)
}
trades = policy.get_trades(portfolio, t, market_data)
print(f"Trades: {trades.to_dict()}")
portfolio.update(trades, market_data['prices'])
print(f"Portfolio weights: {portfolio.weights.to_dict()}")
market.advance_time()
```
--------------------------------
### Holding Cost Constraint Example
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Example of a HoldingCost constraint modeling annual fees on short positions for all assets.
```python
cvx.HoldingCost(short_fees=5.25)
```
--------------------------------
### Activate Development Shell Environment
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Activate the shell environment created by 'make env'. This makes the installed package and scripts available in your current session.
```bash
source env/bin/activate
```
--------------------------------
### DOW30 Monthly Backtest Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/dow30.rst
This Python script performs a monthly backtest on the DOW30 index. It is designed to be executed as a standalone example.
```python
if __name__ == "__main__":
# We use the DOW30 universe, which is a list of 30 stocks.
# We will rebalance monthly.
universe = cvxportfolio.assets.Asset.from_list(cvxportfolio.assets.Dow30())
# We will use the MultiPeriodOptimization policy.
# The default parameters are:
# - objective: minimize transaction costs
# - constraints: long-only, full-replication
# - rebalance_times: monthly
policy = cvxportfolio.MultiPeriodOptimization()
# We will simulate the backtest for one year.
start_time = "2021-01-01"
end_time = "2021-12-31"
# Run the backtest.
result = policy.run(universe, start_time, end_time)
# Print the results.
print(result.summary())
```
--------------------------------
### Measure Cvxportfolio Solution Time
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/solution_time.rst
This script measures the time taken to solve optimization problems. It requires the Cvxportfolio library to be installed. The code is a translation of an original IPython notebook.
```python
import cvxportfolio as cp
import time
# Load the market data
market_data = cp.MarketData.from_cvxpy_data(cp.data.load_market_data())
# Define the universe of assets
universe = market_data.universe
# Define the optimization problem
# This is a simplified example; a real-world problem would have more constraints and objectives.
problem = cp.MarketImpact(universe, half_life=10, num_periods=10)
# Measure the solution time
start_time = time.time()
result = problem.solve(market_data)
end_time = time.time()
print(f"Solution time: {end_time - start_time:.2f} seconds")
```
--------------------------------
### Set Up Development Environment and Run Tests
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
After cloning, set up the development environment and run the test suite. Ensure the PYTHON variable in the Makefile points to your Python interpreter.
```bash
make env
make test
```
--------------------------------
### Initialize ReturnsForecast with NumPy Array
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Use this to initialize the ReturnsForecast object with a NumPy array representing market returns. Ensure the array size matches the trading universe.
```python
my_forecast = np.array([0.001, 0.0005])
cvx.ReturnsForecast(r_hat=my_forecast)
```
--------------------------------
### Run Cvxportfolio unit tests
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Execute the unit test suite for Cvxportfolio from your local environment. This command checks the library's functionality.
```bash
python -m cvxportfolio.tests
```
--------------------------------
### Multi-period Optimization Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/multi_period_opt.rst
This script demonstrates multi-period optimization using Cvxportfolio. It is a translation of an original IPython notebook.
```python
# Copyright (C) 2023-2024 Enzo Busseti
# Copyright (C) 2016 Enzo Busseti, Stephen Boyd, Steven Diamond, BlackRock Inc.
# 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 .
# This example script is
# `available in the repository
# `_.
# See the docstring below for its explanation.
# This is a translation of the `original IPython notebook
# `_
# using Cvxportfolio's stable API.
# This script is a translation of the original IPython notebook
# using Cvxportfolio's stable API.
# It demonstrates multi-period optimization.
import cvxportfolio as cp
import pandas as pd
import numpy as np
# Define the time horizon
T = 20
# Define the number of assets
N = 10
# Generate random market data
np.random.seed(0)
returns = pd.DataFrame(np.random.randn(T, N), columns=[f"Asset {i}" for i in range(N)])
prices = pd.DataFrame(np.exp(np.cumsum(returns)), columns=returns.columns)
# Define the universe of assets
universe = returns.columns.tolist()
# Define the initial portfolio
initial_portfolio = pd.Series(np.ones(N) / N, index=universe)
# Define the objective function: minimize risk (variance) subject to a target return
# We use a simple mean-variance objective here.
# The target return is set to the average return of the market.
# Calculate average returns
mean_returns = returns.mean()
# Define the objective
# We want to minimize portfolio variance, subject to a target return.
# The target return is set to the average return of the market.
# The risk aversion parameter is set to 1.
objective = cp.minimize(cp.Risk.variance())
# Define the constraints
# 1. Budget constraint: the sum of weights must be 1.
# 2. Target return constraint: the expected portfolio return must be at least the average market return.
# 3. No short selling constraint: all weights must be non-negative.
constraints = [
cp.Portfolio.budget(1.0),
cp.Portfolio.expected_return(mean_returns),
cp.Portfolio.long_only()
]
# Create the multi-period optimization problem
# We specify the time horizon T, the universe of assets, and the initial portfolio.
# We also specify the objective and constraints.
mpopt = cp.MultiPeriodOptimization(
T=T,
universe=universe,
initial_portfolio=initial_portfolio,
objective=objective,
constraints=constraints
)
# Solve the problem
# The result is a MultiPeriodPortfolio object, which contains the optimal portfolio weights for each time step.
result = mpopt.solve()
# Print the optimal portfolio weights for the first few time steps
print("Optimal portfolio weights for the first 5 time steps:")
print(result.weights.head())
# You can also access other attributes of the result object, such as:
# - result.returns: the realized returns for each time step
# - result.trades: the trades made at each time step
# - result.costs: the transaction costs incurred at each time step
# Example: Print the realized returns for the first 5 time steps
print("\nRealized returns for the first 5 time steps:")
print(result.returns.head())
# Example: Print the trades made at the first time step
print("\nTrades made at the first time step:")
print(result.trades.iloc[0])
# Example: Print the transaction costs incurred at the first time step
print("\nTransaction costs incurred at the first time step:")
print(result.costs.iloc[0])
```
--------------------------------
### Run Cvxportfolio unit tests ignoring download errors
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Run the Cvxportfolio unit tests while ignoring any download errors, which is useful for environments without internet access.
```bash
python -m cvxportfolio.tests --ignore-download-errors
```
--------------------------------
### Run ETF Backtest with Cvxportfolio
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/etfs.rst
This Python script configures and runs a multi-period optimization backtest for a portfolio of ETFs using Cvxportfolio. It requires the `cvxportfolio` library and assumes necessary data is available.
```python
import cvxportfolio as cp
# Define the universe of assets
assets = [
"SPY",
"IVV",
"VTI",
"VOO",
"QQQ",
"GLD",
"TLT",
"IEF",
"SHY",
"DBC",
]
# Define the time period for the backtest
start_time = "2010-01-01"
end_time = "2022-12-31"
# Load the market data
market_data = cp.MarketData(assets, start_time, end_time)
# Define the optimization policy
# This policy uses multi-period optimization with a risk-averse objective
policy = cp.MultiPeriodOptimization(
objective=cp.MixedObjective(
returns = cp.ExponentialRiskAversion(half_life=cp.SECOND),
costs = cp.TransactionCost(half_life=cp.SECOND),
risk = cp.FullFactorRisk(half_life=cp.SECOND)
),
parallel_execution=True,
solver="ECOS",
solver_options={"abstol": 1e-5, "reltol": 1e-5, "feastol": 1e-5}
)
# Run the backtest
result = cp.MarketSimulation(policy=policy, market_data=market_data).run()
# Print the backtest results
print(result.summary())
```
--------------------------------
### Clone Cvxportfolio Repository
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Clone the Cvxportfolio repository locally to begin development. This command fetches the entire project history.
```bash
git clone https://github.com/cvxgrp/cvxportfolio.git
cd cvxportfolio
```
--------------------------------
### Risk Models Comparison Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/risk_models.rst
This script, available in the Cvxportfolio repository, demonstrates the comparison of different risk models. It requires Python and the Cvxportfolio library to run.
```python
import cvxportfolio as cp
import pandas as pd
import matplotlib.pyplot as plt
# Load example data
prices = pd.read_csv(
"https://raw.githubusercontent.com/cvxgrp/cvxportfolio/master/cvxportfolio/tests/data/prices.csv",
index_col=0,
parse_dates=True,
)
returns = prices.pct_change().dropna()
# Define universe and time
universe = returns.columns
start_time = returns.index[0]
end_time = returns.index[-1]
# Build the market simulation object
market_simulation = cp.MarketSimulation(
returns=returns,
trading_costs=0.001,
market_impact=0.0001,
borrow_costs=0.0001,
risk_free_rate=0.00005,
)
# Define the universe of assets
assets = market_simulation.universe
# Define the risk models to compare
risk_models = {
"EW": cp.RiskNeutral(
universe,
covariance=cp.FullCovariance(returns.cov()),
weights=cp.UniformWeights(universe),
),
"Mean-Variance": cp.FactorModel(
universe,
returns.cov(),
factors=pd.DataFrame(0.0, index=returns.index, columns=[])
),
"Factor": cp.FactorModel(
universe,
returns.cov(),
factors=pd.DataFrame(0.0, index=returns.index, columns=[])
),
"Constant": cp.ConstantEstimator(universe),
}
# Define the optimization parameters
optimization_parameters = cp.MarketSimulation.OptimizationParameters(
risk_aversion=2.0,
transaction_cost=0.001,
market_impact=0.0001,
min_fraction_long=0.0,
min_fraction_short=0.0,
max_fraction_long=1.0,
max_fraction_short=0.0,
sigma_annual=0.2,
)
# Run the simulation for each risk model
results = {}
for name, risk_model in risk_models.items():
print(f"Running simulation with {name} risk model...")
results[name] = market_simulation.simulate(
risk_model=risk_model,
optimization_parameters=optimization_parameters,
start_time=start_time,
end_time=end_time,
)
# Plot the results
plt.figure(figsize=(12, 8))
for name, result in results.items():
plt.plot(result.total_returns, label=name)
plt.title("Risk Models Comparison")
plt.xlabel("Time")
plt.ylabel("Total Returns")
plt.legend()
plt.grid(True)
plt.show()
```
--------------------------------
### Initialize Multi-Period Optimization Policy
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Defines a multi-period optimization policy with distinct objectives and constraints for each planning step. Ensure time-indexed data (like returns forecasts) uses the execution time as the index.
```python
same_period_returns_forecast = pd.DataFrame(...)
next_period_returns_forecast = pd.DataFrame(...) # indexed by the time of execution, not of the forecast!
gamma_risk = cvx.Gamma(initial_value = 0.5)
gamma_hold = cvx.Gamma(initial_value = 1.0)
gamma_trade = cvx.Gamma(initial_value = 1.0)
objective_1 = cvx.ReturnsForecast(r_hat = same_period_returns_forecast) \
- gamma_risk * cvx.FullCovariance() \
- gamma_hold * cvx.HoldingCost(short_fees = 1.) \
- gamma_trade * cvx.TransactionCost(a = 2E-4)
objective_2 = cvx.ReturnsForecast(r_hat = next_period_returns_forecast) \
- gamma_risk * cvx.FullCovariance() \
- gamma_hold * cvx.HoldingCost(short_fees = 1.) \
- gamma_trade * cvx.TransactionCost(a = 2E-4)
constraints_1 = [cvx.LongOnly(applies_to_cash = True)]
constraints_2 = [cvx.LongOnly(applies_to_cash = True)]
policy = cvx.MultiPeriodOptimization(
objective = [objective_1, objective_2],
constraints = [constraints_1, constraints_2]
)
```
--------------------------------
### Python Script for Data and Risk Model Estimates
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/data_risk_model.rst
This script, available in the Cvxportfolio repository, demonstrates the estimation of data and risk models. It is a translation of an older IPython notebook.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
# Load market data
market_data = pd.read_csv("market_data.csv", index_col=0, parse_dates=True)
# Define assets
assets = market_data.columns
# Create a Cvxportfolio simulator
simulator = cp.MarketSimulator(market_data)
# Get historical returns
historical_returns = simulator.returns.iloc[:-1]
# Estimate the covariance matrix
# Using Ledoit-Wolf shrinkage estimator
covariance_estimator = cp.LedoitWolfEstimator()
covariance_matrix = covariance_estimator.fit(historical_returns).covariance
# Estimate the market impact model
# Using a linear market impact model
market_impact_estimator = cp.LinearMarketImpactEstimator()
market_impact_model = market_impact_estimator.fit(historical_returns).market_impact
# Estimate the factor model (example with 3 factors)
# Assuming you have factor data and factor exposures
# factor_data = pd.read_csv("factor_data.csv", index_col=0, parse_dates=True)
# factor_exposures = pd.read_csv("factor_exposures.csv", index_col=0, parse_dates=True)
# factor_model_estimator = cp.FactorModelEstimator(n_factors=3)
# factor_model = factor_model_estimator.fit(historical_returns, factor_data, factor_exposures).factor_model
# For demonstration, we'll use a simplified factor model estimation
# In a real scenario, you would use actual factor data and exposures
factor_model_estimator = cp.FactorModelEstimator(n_factors=3)
factor_model = factor_model_estimator.fit(historical_returns).factor_model
# Print the estimated covariance matrix
print("Estimated Covariance Matrix:\n", covariance_matrix)
# Print the estimated market impact model
print("\nEstimated Market Impact Model:\n", market_impact_model)
# Print the estimated factor model
print("\nEstimated Factor Model:\n", factor_model)
```
--------------------------------
### Create Single Period Optimization Policy
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Instantiate a SinglePeriodOptimization policy with specified objectives and constraints. This policy is passed to the optimization-based policies through its constructor. It configures the CVXPY solver, accuracy, and verbosity.
```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,
)
```
--------------------------------
### Single-Period Optimization with Linear Transaction Cost
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/single_period_opt_lin_tcost.rst
This script is a translation of an original IPython notebook using Cvxportfolio's stable API. It focuses on single-period optimization with linear transaction costs.
```python
import cvxportfolio as cp
import numpy as np
import pandas as pd
# Define the universe of assets
assets = ["AAPL", "GOOG", "MSFT", "AMZN", "META"]
# Define the current portfolio weights
current_weights = pd.Series(index=assets, data=[0.2, 0.2, 0.2, 0.2, 0.2])
# Define the target portfolio weights
target_weights = pd.Series(index=assets, data=[0.1, 0.3, 0.2, 0.2, 0.2])
# Define the linear transaction cost
transaction_cost = cp.LinearTransactionCost(half_spread=0.001)
# Define the market impact model (optional, here set to zero)
market_impact = cp.MarketImpact(half_spread=0.0)
# Define the objective function: minimize transaction costs and market impact
objective = cp.Minimize(transaction_cost + market_impact)
# Define the constraints: the sum of weights must be 1
constraints = [cp.sum_of_weights == 1]
# Create the portfolio optimization problem
problem = cp.Portfolio(objective=objective, constraints=constraints)
# Solve the problem
result = problem.solve(current_weights=current_weights, target_weights=target_weights)
# Print the resulting trades
print("Trades:\n", result.trades)
# Print the resulting weights
print("Resulting weights:\n", result.weights)
# Print the total transaction cost
print("Total transaction cost:", result.transaction_cost)
# Print the total market impact
print("Total market impact:", result.market_impact)
```
--------------------------------
### Set Up Git Hooks for Development Workflow
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/README.rst
Configure git hooks to automatically run linting before commits and tests before pushes, ensuring code quality and stability.
```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
```
--------------------------------
### Soft Constraints
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/constraints.rst
Demonstrates how to implement soft constraints by wrapping existing constraints with cvxportfolio.SoftConstraint and subtracting them from the objective function. The multiplier in front of SoftConstraint controls the enforcement level.
```APIDOC
## Soft Constraints
Soft constraints allow for relaxing the strict enforcement of constraints. They are implemented by wrapping a constraint object with `cvxportfolio.SoftConstraint` and including it as a negative term in the objective function. The multiplier associated with the `SoftConstraint` term acts as a priority penalizer, controlling the degree to which the constraint is enforced.
### Example
```python
import cvxportfolio as cvx
policy = cvx.SinglePeriodOptimization(
objective =
cvx.ReturnsForecast()
- 0.5 * cvx.FullCovariance()
- 10 * cvx.SoftConstraint(cvx.LeverageLimit(3)))
```
In this example, `cvx.LeverageLimit(3)` is made a soft constraint with a priority penalizer of 10, meaning it will be enforced almost exactly. A smaller penalizer would lead to more violations.
```
--------------------------------
### Back-Test Timing Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/timing.rst
This Python script executes a back-test, measuring the time taken for covariance matrix estimation and loading. It is intended to be run directly to observe performance differences.
```python
if __name__ == "__main__":
# we use this to save the plots
pass
```
--------------------------------
### Python Script for Ranking and SPO
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/rank_and_spo.rst
This script is a translation of an original IPython notebook using Cvxportfolio's stable API. It is available in the repository.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
# This script is a translation of the original IPython notebook
# using Cvxportfolio's stable API.
#
# The original notebook is available at:
# https://github.com/cvxgrp/cvxportfolio/blob/0.0.X/examples/RankAndSPO.ipynb
#
# The current script is available at:
# https://github.com/cvxgrp/cvxportfolio/blob/master/examples/paper_examples/rank_and_spo.py
# We will use the following data for this example:
# - a universe of 10 assets
# - a time series of 100 days
# - a factor model with 5 factors
# - a covariance matrix of 10x10
# - a risk aversion parameter of 10
# - a transaction cost parameter of 0.01
# Generate random data
num_assets = 10
num_days = 100
num_factors = 5
np.random.seed(42)
returns = pd.DataFrame(np.random.randn(num_days, num_assets) * 0.01,
columns=[f'Asset {i}' for i in range(num_assets)])
factors = pd.DataFrame(np.random.randn(num_days, num_factors),
columns=[f'Factor {i}' for i in range(num_factors)])
factor_loadings = pd.DataFrame(np.random.randn(num_assets, num_factors) * 0.1,
columns=[f'Factor {i}' for i in range(num_factors)],
index=[f'Asset {i}' for i in range(num_assets)])
cov_matrix = pd.DataFrame(np.random.rand(num_assets, num_assets) * 0.001,
columns=[f'Asset {i}' for i in range(num_assets)],
index=[f'Asset {i}' for i in range(num_assets)])
cov_matrix = (cov_matrix + cov_matrix.T) / 2
np.fill_diagonal(cov_matrix.values, np.random.rand(num_assets) * 0.005 + 0.001)
# Define the market simulator
market_simulator = cp.MarketSimulator(returns=returns,
trading_costs=0.01,
liquidity_costs=0.001)
# Define the factor model
factor_model = cp.FactorModel(factors=factors,
factor_loadings=factor_loadings,
covariance_matrix=cov_matrix)
# Define the portfolio optimizer
optimizer = cp.Optimizer(market_simulator=market_simulator,
factor_model=factor_model,
risk_aversion=10)
# Run the simulation
result = optimizer.run_simulation(initial_portfolio=np.ones(num_assets) / num_assets)
# Print the results
print(result)
```
--------------------------------
### MarketSimulator
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/simulator.rst
Provides functionalities for simulating market behavior and executing backtests.
```APIDOC
## MarketSimulator
### Description
Represents a market simulator for backtesting trading strategies.
### Methods
#### `backtest()`
Performs a backtest of a given trading strategy.
#### `run_backtest()`
Alias for `backtest()`.
#### `backtest_many()`
Performs backtests for multiple scenarios or strategies.
#### `run_multiple_backtest()`
Alias for `backtest_many()`.
#### `optimize_hyperparameters()`
Optimizes the hyperparameters of the trading strategy.
```
--------------------------------
### Cost Inequality as Constraint
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/constraints.rst
Explains how objective function terms, such as risks and costs, can be used as inequality constraints. This allows for defining limits on various aspects of portfolio risk and return.
```APIDOC
## Cost Inequality as Constraint
Since version 0.4.6, any objective function term, including returns, risks, and costs, can be used as part of an inequality constraint. This applies to any linear combination of objective terms, provided the resulting constraint is convex.
### Example 1: Limiting Covariance
```python
import cvxportfolio as cvx
# Limit the covariance to a target volatility squared
risk_limit = cvx.FullCovariance() <= target_volatility**2
```
### Example 2: Limiting Annualized Volatility (Cvxportfolio 1.4.0+)
```python
import cvxportfolio as cvx
# Limit annualized volatility to 5%
risk_limit_annualized = cvx.FullCovariance() <= cvx.AnnualizedVolatility(0.05)
cvx.MarketSimulator(universe).backtest(
cvx.SinglePeriodOptimization(cvx.ReturnsForecast(), [risk_limit_annualized])).plot()
```
**Note:** You cannot use objective terms to create constraints where a term must be greater than or equal to a value, as this would result in a non-convex constraint.
```
--------------------------------
### Portfolio Simulation Script
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/examples/paper_examples/portfolio_simulation.rst
This script simulates portfolio performance. It requires the Cvxportfolio library and is designed to be run as a Python script.
```python
import cvxportfolio as cp
import pandas as pd
import numpy as np
# Load market data
market_data = pd.read_csv("market_data.csv", index_col=0, parse_dates=True)
# Define portfolio parameters
initial_investment = 1_000_000
# Create a portfolio object
portfolio = cp.Portfolio.from_yaml("portfolio.yaml")
# Define simulation parameters
start_date = "2020-01-01"
end_date = "2020-12-31"
# Run the simulation
results = cp.simulate_portfolio(market_data, portfolio, initial_investment, start_date, end_date)
# Print the results
print(results)
```
--------------------------------
### Cost Models Overview
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/costs.rst
Overview of the cost models available in Cvxportfolio.
```APIDOC
## Cost Models
Cvxportfolio provides a flexible framework for defining and applying various cost models to portfolio optimization problems. These models can represent different types of costs, including holding costs and transaction costs.
### Available Cost Models:
* **HoldingCost**: Represents costs associated with holding assets over time.
* **StocksHoldingCost**: A specific implementation of HoldingCost for stock portfolios.
* **TransactionCost**: Represents costs incurred when trading assets.
* **StocksTransactionCost**: A specific implementation of TransactionCost for stock portfolios.
* **SoftConstraint**: Represents costs associated with violating soft constraints.
### Base Classes for Custom Costs:
* **Cost**: The base class for all cost models.
* **SimulatorCost**: A base class for costs that can be simulated. It provides a `simulate` method.
#### `cvxportfolio.costs.Cost`
This is the fundamental base class for all cost models in Cvxportfolio. Users can inherit from this class to define their own custom cost functions.
#### `cvxportfolio.costs.SimulatorCost`
This base class is designed for cost models that require simulation. It includes a `simulate` method that can be overridden by subclasses to implement specific simulation logic.
##### `simulate` Method
* **Description**: Simulates the cost based on the provided trade and portfolio state.
* **Parameters**: Requires trade and portfolio state information.
* **Returns**: The simulated cost.
```
--------------------------------
### Market data servers
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/data.rst
Classes that act as servers for market data, allowing Cvxportfolio to query data as needed.
```APIDOC
## UserProvidedMarketData
### Description
A market data server that allows users to provide their own market data.
### Methods
- **serve**: Serves market data.
- **trading_calendar**: Returns the trading calendar.
### Endpoint
N/A
## DownloadedMarketData
### Description
A market data server that serves data that has been previously downloaded.
### Methods
- **serve**: Serves market data.
- **trading_calendar**: Returns the trading calendar.
### Endpoint
N/A
```
--------------------------------
### Create Time-Varying Fees with Pandas Series
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Model annual fees on short positions that vary by year using a Pandas Series with a datetime index. Ensure timestamps match market data server conventions.
```python
datetime_index_2020 = pd.date_range('2020-01-01', '2020-12-31')
short_fees_2020 = pd.Series(5.0, index=datetime_index_2020)
datetime_index_2021 = pd.date_range('2021-01-01', '2021-12-31')
short_fees_2021 = pd.Series(5.25, index=datetime_index_2021)
historical_short_fees = pd.concat([short_fees_2020, short_fees_2021])
cvx.HoldingCost(short_fees=historical_short_fees)
```
--------------------------------
### Risk Models
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/risks.rst
Classes for defining and calculating different types of risk in portfolio optimization.
```APIDOC
## Risk Models
This section details various risk models available in Cvxportfolio.
### DiagonalCovariance
Represents a diagonal covariance matrix.
### FullCovariance
Represents a full covariance matrix.
### FactorModelCovariance
Represents a covariance matrix derived from a factor model.
### WorstCaseRisk
Represents worst-case risk calculations.
### FullSigma
Represents a full covariance matrix (often used interchangeably with FullCovariance).
### FactorModel
Represents a factor model for risk estimation.
```
--------------------------------
### Create Returns Forecasts with Pandas DataFrame
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/manual.rst
Specify returns forecasts for multiple assets over different time periods using a Pandas DataFrame. The datetime index represents time periods, and columns represent assets. Ensure timestamps match market data server conventions.
```python
my_forecast = pd.DataFrame(
[[0.1, 0.05], [0.15, 0.06]],
index=[pd.Timestamp('2020-01-01'), pd.Timestamp('2021-01-01')],
columns=['AAPL', 'GOOG'])
cvx.ReturnsForecast(r_hat=my_forecast)
```
--------------------------------
### Limit Covariance as a Risk Constraint
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/constraints.rst
Use an objective term like cvx.FullCovariance as part of an inequality constraint to limit portfolio risk. Ensure the resulting constraint is convex.
```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()
```
--------------------------------
### Base classes for custom data sources
Source: https://github.com/cvxgrp/cvxportfolio/blob/master/docs/data.rst
Abstract base classes for creating custom market data interfaces.
```APIDOC
## SymbolData
### Description
Base class for symbol-specific data.
### Method
N/A (Abstract Base Class)
### Endpoint
N/A
## MarketData
### Description
Abstract base class for market data interfaces.
### Methods
- **serve**: Serves market data.
- **universe_at_time**: Returns the universe of symbols at a specific time.
- **trading_calendar**: Returns the trading calendar.
### Properties
- **periods_per_year** (int): The number of trading periods per year.
- **full_universe** (list[str]): The full universe of symbols available.
### Endpoint
N/A
```