### 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 ```