简体   繁体   中英

Python: Portfolio Optimization tool

I'm learning how to code and selected Python to do so. My first task is to optimize a portfolio along with Efficient Frontier. I found a great code wrote by @s666. As in general optimization case the constraints are as follow: 1) the sum of the weights = 1, and 2) no stock has a weight >1.

In the code displayed below, could you please educate me how can I add a third constraint where the 3 stocks considered have their individual weight boundaries in addition to the constraints mentioned above ie, 0.2>AAPL<0.7; 0.3<AMZN<0.8; 0.1<MSFT<0.6

Thanking you in advance....

import numpy as np
import pandas as pd
from pandas_datareader import data as d
import matplotlib.pyplot as plt
#list of stocks in portfolio
stocks = ['AAPL','AMZN','MSFT']#,'YHOO']
#download daily price data for each of the stocks in the portfolio
start = datetime.datetime(2010, 1, 1)
end = datetime.datetime(2018, 12, 31)
data = pd.DataFrame([d.DataReader(ticker, 'yahoo', start, end)['Adj Close'] for ticker in stocks]).T
data.columns = stocks

#convert daily stock prices into daily returns
returns = data.pct_change()
#calculate mean daily return and covariance of daily returns
mean_daily_returns = returns.mean()
cov_matrix = returns.cov()
#set number of runs of random portfolio weights
num_portfolios = 25000
#set up array to hold results
#We have increased the size of the array to hold the weight values for each stock
results = np.zeros((3+len(stocks),num_portfolios))
for i in range(num_portfolios):
    #select random weights for portfolio holdings
    weights = np.array(np.random.random(len(stocks)))
    #rebalance weights to sum to 1
    weights /= np.sum(weights)

    #calculate portfolio return and volatility
    portfolio_return = np.sum(mean_daily_returns * weights) * 252
    portfolio_std_dev = np.sqrt(np.dot(weights.T,np.dot(cov_matrix, weights))) * np.sqrt(252)

    #store results in results array
    results[0,i] = portfolio_return
    results[1,i] = portfolio_std_dev
    #store Sharpe Ratio (return / volatility) - risk free rate element excluded for simplicity
    results[2,i] = results[0,i] / results[1,i]
    #iterate through the weight vector and add data to results array
    for j in range(len(weights)):
        results[j+3,i] = weights[j]
#convert results array to Pandas DataFrame
results_frame = pd.DataFrame(results.T,columns=['ret','stdev','sharpe'] + [ticker for ticker in stocks])
#locate position of portfolio with highest Sharpe Ratio
max_sharpe_port = results_frame.iloc[results_frame['sharpe'].idxmax()]
#locate positon of portfolio with minimum standard deviation
min_vol_port = results_frame.iloc[results_frame['stdev'].idxmin()]
#create scatter plot coloured by Sharpe Ratio
plt.scatter(results_frame.stdev,results_frame.ret,c=results_frame.sharpe,cmap='RdYlBu')
plt.xlabel('Volatility')
plt.ylabel('Returns')
plt.colorbar()
#plot red star to highlight position of portfolio with highest Sharpe Ratio
plt.scatter(max_sharpe_port[1],max_sharpe_port[0],marker=(5,1,0),color='r',s=1000)
#plot green star to highlight position of minimum variance portfolio
plt.scatter(min_vol_port[1],min_vol_port[0],marker=(5,1,0),color='g',s=1000)

I developed a python package for portfolio optimization based on cvxpy and pandas called Riskfolio-Lib, with this library you can optimise CVaR, Max Drawdown, Omega Ratio, Sortino, RiskParity and other portfolio optimization models. You can check the documentation and examples in this link https://riskfolio-lib.readthedocs.io/en/latest/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM