pyPortfolioAnalysis package¶
Submodules¶
pyPortfolioAnalysis.pyPortfolioAnalysis module¶
pyPortfolioAnalysis: Methods to optimize portfolio¶
Documentation is available as docstring or as HTML on https://github.com/anuragagrawaal/pyPortfolioAnalysis
Fucntions and Classes
Optimization Methods¶
‘HHI’ ‘VaR’ ‘VaR_portfolio’ ‘add_constraint’ ‘add_objective’ ‘black_litterman’ ‘box_constraint’ ‘cVaR_portfolio’ ‘constrained_objective’ ‘diversification’ ‘diversification_constraint’ ‘equal_weight’ ‘extract_groups’ ‘extract_objective_measure’ ‘extract_weights’ ‘factor_exposure_constraint’ ‘fn_map’ ‘generate_sequence’ ‘get_constraints’ ‘group_constraint’ ‘group_fail’ ‘inverse_volatility_weights’ ‘leverage_exposure_constraint’ ‘leverage_fail’ ‘max_sum_fail’ ‘min_sum_fail’ ‘minmax_objective’ ‘normalize_weights’ ‘optimize_portfolio’ ‘performance_metrics_objective ‘port_mean’ ‘portfolio_risk_objective’ ‘portfolio_spec’ ‘pos_limit_fail’ ‘position_limit_constraint’ ‘return_constraint’ ‘return_objective’ ‘risk_budget_objective’ ‘rp_decrease’ ‘rp_decrease_leverage’ ‘rp_increase’ ‘rp_position_limit’ ‘rp_transform’ ‘transaction_cost_constraint’ ‘turnover’ ‘turnover_constraint’ ‘turnover_objective’ ‘var_portfolio’ ‘weight_concentration_objective’ ‘weight_sum_constraint’
Plots¶
‘chart_efficient_frontier’ ‘chart_group_weights’ ‘chart_weights’
References¶
Brian G. Peterson and Peter Carl (2018). PortfolioAnalytics: Portfolio Analysis, Including Numerical Methods for Optimization of Portfolios. R package version 1.1.0. https://CRAN.R-project.org/package=PortfolioAnalytics
Boudt, Kris and Lu, Wanbo and Peeters, Benedict, Higher Order Comoments of Multifactor Models and Asset Allocation (June 16, 2014). Available at SSRN: http://ssrn.com/abstract=2409603 or http://dx.doi.org/10.2139/ssrn.2409603
Chriss, Neil A and Almgren, Robert, Portfolios from Sorts (April 27, 2005). Available at SSRN: http://ssrn.com/abstract=720041 or http://dx.doi.org/10.2139/ssrn.720041
Meucci, Attilio, The Black-Litterman Approach: Original Model and Extensions (August 1, 2008). Shorter version in, THE ENCYCLOPEDIA OF QUANTITATIVE FINANCE, Wiley, 2010. Avail- able at SSRN: http://ssrn.com/abstract=1117574 or http://dx.doi.org/10.2139/ssrn.1117574
Meucci, Attilio, Fully Flexible Views: Theory and Practice (August 8, 2008). Fully Flexible Views: Theory and Practice, Risk, Vol. 21, No. 10, pp. 97-102, October 2008. Available at SSRN: http://ssrn.com/abstract=1213325
Scherer, Bernd and Martin, Doug, Modern Portfolio Optimization. Springer. 2005.
Shaw, William Thornton, Portfolio Optimization for VAR, CVaR, Omega and Utility with General Return Distributions: A Monte Carlo Approach for Long-Only and Bounded Short Portfolios with Optional Robustness and a Simplified Approach to Covariance Matching (June 1, 2011). Available at SSRN: http://ssrn.com/abstract=1856476 or http://dx.doi.org/10.2139/ssrn.1856476
-
pyPortfolioAnalysis.pyPortfolioAnalysis.HHI(weights, groups=None)¶ The Herfindahl Hirschman Index measures the concentration of weights using this function.
Concentration of weights
- weightsarray-like,
collection of weights of the portfolio.
- groupsdict,
dictionary of groups.
returns the weight concentration given the weights
port_mean var_portfolio VaR cVaR
>>> # calculate HHI >>> w = [0.2,0.3,-0.1,0.6,0.8] >>> HHI(w)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.VaR(R, p=0.05)¶ Calculate the value at risk (VaR)
This function calculates the value at risk (VaR) assuming gaussian distribution
- Rpd.DataFrame object,
returns dataframe
- pfloat, optional
quantile estimate
Calculates the VaR given returns
cVaR VaR_portfolio
>>> VaR(R,p = 0.01)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.VaR_portfolio(w, R, p=0.05, mean=True)¶ calculate the value at risk (VaR) of a portfolio
This function calculates the value at risk (VaR) assuming gaussian distribution
- warray-like,
list of weights of portfolio
- Rpd.DataFrame object,
returns dataframe
- pfloat, optional
quantile estimate
- meanbool, default = True
mean VaR of portfolio
Calculates the VaR given portfolio weights
cVaR VaR_portfolio VaR
>>> w = [0.2,0.3,0.5] >>> VaR_portfolio(w,R,p = 0.01)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.add_constraint(portfolio, kind, enabled=True, **kwargs)¶ Add a constraint in portfolio_spec object
Main function to add or update constraint in portfolio_spec object
- portfolioportfolio_spec,
an object of class portfolio_spec. see portfolio_spec
- kindstr,
currently supported constraint: ’weight_sum’ (also ’leverage’ or ’weight’), ’box’, ’group’,
- ’turnover’,’diversification’, ’position_limit’, ’return’, ’factor_exposure’,
or ’leverage_exposure’.
- enabledbool, default = True
bool to enable or disable constraints.
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
Adds constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
•weight_sum, weight, leverage Specify constraint on the sum of the weights, see weight_sum_constraint •full_investment Special case to set min_sum=1 and max_sum=1 of weight sum constraints •dollar_neutral, active Special case to set min_sum=0 and max_sum=0 of weight_sum constraints •box box constraint for the individual asset weights, see box_constraint •long_only Special case to set min=0 and max=1 of box constraint •group specify the sum of weights within groups and the number of assets with non-zero weights in groups,
see group_constraint
- •turnover Specify a constraint for target turnover. Turnover is calculated from a set of initial weights,
see turnover_constraint
•diversification target diversification of asset of weights, see diversification_constraint •position_limit Specify the number of non-zero,long, and/orshortpositions, see position_limit_constraint •return Specify the target mean return, see return_constraint •factor_exposure Specify risk factor exposures, see factor_exposure_constraint •leverage_exposure Specify a maximum leverage exposure, see leverage_exposure_constraint
>>> portfolio = portfolio_spec(assets = 4) >>> # adding weight_sum cinstraint >>> add_constraint(portfolio, kind = 'weight_sum', min_sum = 0.9, max_sum = .95) >>> # long_only is a special kind of box constraint where minimum and maximum is positive >>> # minimum and maximum can be list or scalars >>> add_constraint(portfolio, kind = 'box', minimum = [0.9, -0.5,-0.5, 0.1], maximum = 1) >>> add_constraint(portfolio, kind = 'long_only')
>>> # group constraint is used to specify min and max weights of certain asset_groups >>> # groups must be a dict and group_min and group_max can be scalar or list >>> add_constraint(portfolio, kind = 'group', group_min = [0.9, -0.5,-0.5, 0.1], group_max = 1, groups = {'eqity':[0,3], 'debt':[1,2]})
>>> # adding weight_sum constraint >>> add_constraint(portfolio, kind = 'weight_sum', min_sum = 0.9, max_sum = .95) >>> # special case of weight_sum is dollar_neutral/active or full_investment >>> add_constraint(portfolio, kind = 'dollar_neutral') >>> add_constraint(portfolio, kind = 'full_investment')
>>> #turnover constraint >>> add_constraint(portfolio, kind = 'turnover', turnover_target = 0.1)
>>> #diversification constraint for diversification target in a portfolio >>> add_constraint(portfolio, kind = 'diversification', div_target = 0.1)
>>> #position_limit is a constraint to restrict max position and also max long/short positions >>> add_constraint(portfolio, kind = 'position_limit', max_pos = 3, max_pos_long = 2, max_pos_short = 2)
>>> #return constraint to add a target mean historical return to the portfolio >>> add_constraint(portfolio, kind = 'return', return_target = 0.0018)
>>> #adds a tranaction cost constraint on portfolio >>> add_constraint(portfolio, kind = 'transaction_cost', ptc = 0.1)
>>> #constraint on the leverage of portfolio >>> add_constraint(portfolio, kind = 'leverage_exposure', leverage = 0.8)
>>> #Factor_exposure constraint is used to test portfolio with their impact on certaint factors >>> # factors can be single or multiple with lower and upper limit. >>> # B can be a N*K matrix for N assets and K factors. >>> # lower and upper arguments can be float for single factor and list for multiple factors >>> add_constraint(portfolio, kind = 'factor_exposure', B = np.matrix([[1.2,1.3], [2.3,1.4], [1.4,0.9], [3.4,1.2]]), lower = [0.8,1.4], upper = [2,2.4])
-
pyPortfolioAnalysis.pyPortfolioAnalysis.add_objective(portfolio, kind, name, arguments=None, constraints=None, enabled=True, message=True, **kwargs)¶ This function is the primary function of adding and updating business goals in a portfolio.spec type object. General interface, including risk, return, and risk budget, to add optimization goals.
- portfolioportfolio_spec,
an object of class portfolio_spec.
- kindstr,
the character form of the goal to be added or changed, currently ‘return’,’ risk’, ‘risk_budget’,’ quadratic_utility’, or ‘weight_concentration’.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances arguments : Default arguments to be transferred when executed on an objective function.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
Adds objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
In general, you will define your objective as one of the following types: ’return’, ’risk’, ’risk_budget’, or ’weight_concentration’.
These have special handling and intelligent defaults for dealing with the function most likely to be used as objectives, including mean, median, VaR, ES, etc. Objectives of type ’turnover’ and ’minmax’ are also supported.
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'return', name = 'mean', target = 0.0018) >>> add_objective(kind = 'portfolio_risk', name = 'std', target = 0.015) >>> add_objective(kind = 'risk_budget', name = 'risk_budget') >>> add_objective(kind = 'weight_conc', name = 'HHI', target = 0.11) >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
class
pyPortfolioAnalysis.pyPortfolioAnalysis.black_litterman(R, P)¶ Bases:
objectA class to call black_litterman object.
Black-litterman formula is popular to get posterior moments of the portfolio.
…
- Rpandas.DataFrame
dataframe of returns series.
- Pmatrix-like,
KXN link matrix where N is the number of assets and K are the views
- fit(Mu = None, S = None, Views = None, tau = 1):
returns a matrix of posterior returns based on Views and returns data.
-
fit(Mu=None, S=None, Views=None, tau=1)¶ fit method of black_litterman object
Main function to call in order to return the posterior mean of the portfolio given the views and return.
- Muarray-like, optional
prior mean of the returns. numpy.mean is called if Mu is None
- Smatrix-like, optional
NXN covariance matrix. numpy.cov is called if S is None
- Views: array-like, default = None
array of K views held by investor.
- Tau: float, default = 1
multiplying factor to be used.
- array:
returns an array of posterior moments of portfolio given the returns and weights
portfolio_spec optimize_portfolio
Black-litterman formula is very useful if an investor believes that a particular stock is going to rise compared to others although this information is not incorporated in the stock price. Essentially, it captures the views an investor holds for a particular asset.
>>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> P = np.matrix([[-1, 0, 1],[0,-1,1]]) >>> Views = np.matrix([[0.02], [0.05]]) >>> bl = black_litterman(R = port_ret, P = P) >>> bl.fit(Views = Views)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.box_constraint(assets, minimum, maximum, kind='box', enabled=True, message=True, **kwargs)¶ The box constraint defines the upper and lower limits of asset weights. add_constraint calls this function when type=”box” is defined.
- assetsint, or array-like,
number of assets, or optionally a named list of assets specifying initial weights.
- minimumfloat, or array-like,
numeric or named list defining the minimum constraints of the weight box.
- maximumfloat, or array-like,
numeric or named list defining the maximum constraints of the weight box.
- kindstr,
string of kind of constraint.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
Add box constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> add_constraint(portfolio, kind = 'box', minimum = [0.9, -0.5,-0.5, 0.1], maximum = 1)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.cVaR_portfolio(w, R, p=0.05, mean=True)¶ Calculate the conditional value at risk (cVaR) of a portfolio
This function calculates the conditional value at risk (cVaR) assuming gaussian distribution
- warray-like,
list of weights of portfolio
- Rpd.DataFrame object,
returns dataframe
- pfloat, optional
quantile estimate
- meanbool, default = True
mean VaR of portfolio
Calculates the VaR given portfolio weights
cVaR VaR_portfolio VaR
>>> w = [0.2,0.3,0.5] >>> cVaR_portfolio(w,R,p = 0.01)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.chart_efficient_frontier(portfolio, R, metric='Sharpe Ratio', arguments={'rf': 0.0}, cml=False, rand_pf=300, optimize_method='DEoptim', alpha=0.4, figsize=(10, 6), **kwargs)¶ Function to plot efficient frontier of portfolio.
- portfolioportfolio_spec,
an object of class portfolio_spec.
- Rpandas dataframe,
dataframe of the returns series
- metric: str, default = ‘Sharpe Ratio’
metric should be either of ‘Sharpe Ratio’ or ‘Treynor Ratio’
- argumentsdict, optional
additional arguments such as risk-free rate in the form of a dictionary.
- cmlbool, default = False
bool to enable or disable capital market line
- rand_pfint, optional
random portfolio to plot to show the efficient frontier
- optimize_methodstr, optional
optimize_method should be similar to those in optimize_portfolio. see optimize_portfolio
- alphafloat, optional
transparency
- figsizetuple, optional
figure size in the form of a tuple
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
matplotlib.scatter
chart_group_weights chart_weights chart_efficient_frontier
>>> # Rb is S&P500 benchmark for capital market line and beta for treynor ratio >>> chart_efficient_froniter(portfolio, R, metric = 'Treynor Ratio', arguments = {'rf': 0.0008, 'Rb':Rb}, cml = True, alpha = 0.1, rand_pf = 1000, optimize_method = 'pso')
-
pyPortfolioAnalysis.pyPortfolioAnalysis.chart_group_weights(portfolio)¶ Function to plot individual group weights of optimal weights.
- portfolioportfolio_spec,
an object of class portfolio_spec.
matplotlib.lines.Line2D
chart_group_weights chart_efficient_frontier
>>> chart_group_weights(portfolio) NOTE: chart_group_weights will only work after call optimize_portfolio on portfolio_spec
-
pyPortfolioAnalysis.pyPortfolioAnalysis.chart_weights(portfolio)¶ Function to plot weights of optimal weights.
- portfolioportfolio_spec,
an object of class portfolio_spec.
matplotlib.lines.Line2D
chart_group_weights chart_efficient_frontier
>>> chart_weights(portfolio) NOTE: chart_group_weights will only work after call optimize_portfolio on portfolio_spec
-
pyPortfolioAnalysis.pyPortfolioAnalysis.constrained_objective(w, R, portfolio, trace=False, normalize=False, storage=False, verbose=False, penalty=10000, *kwargs, **args)¶ Add a constraint in portfolio_spec object
Main function to add or update constraint in portfolio_spec object
- warray-like,
weights to test
- Rpd.DataFrame,
dataframe of returns of assets in portfolio
- tracebool, default = False
bool to enable or disable constraints.
- normalizebool, default = False
bool to specify if weights should be normalized first. see normalize_weights.
- verbosebool, default = False
bool to enable or disable verbose argument.
- penaltyint, optional
int value specifying he penalty if constraint or objective is breached.
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
- kwargsadditional arguments, optional
any additional argument to be passed.
returns a float of total penalty given a weight. if trace = True, additional objective measure will be returned in the form of dictionary.
rp_transform optimize_portfolio
constrained_objective is the main function that is called by optimize_weights to optimze the constraint and objectives provided by the portfolio.
Loosely speaking, constrained_objective is very similar to an information criteria.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.diversification(weights)¶ Diversification is stated as 1 minus the total of the squared weights
Diversification function to compute as a constraint
- weightsarray-like,
list of weights of assets.
returns diversification given the weights
turnover
>>> w = [0.2,0.3,0.5] >>> turnover(w)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.diversification_constraint(assets, div_target, kind='diversification', enabled=True, message=True)¶ Target diversification value is specified under the diversification constraint.
This function is called by add.constraint when type=”diversification” is mentioned.
- assetsInt, or array-like,
Number of assets or, as an alternative, a named asset list specifying initial weights.
- div_targetfloat,
diversification target value
- kindstr,
string of the kind of constraint.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds diversification constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #diversification constraint for diversification target in a portfolio >>> add_constraint(portfolio, kind = 'diversification', div_target = 0.1)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.equal_weight(R, portfoio, **kwargs)¶ Function to extract objective measures of equal weight portfolio.
- Rpd.DataFrame,
dataframe of returns of assets in portfolio
- portfolioportfolio_spec,
an object of class portfolio_spec.
- kwargsadditional arguments, optional
any additional argument to be passed.
dictionary of objective measures of equal weighted portfolio
inverse_volatility_weights
>>> equal_weight(R, portfolio)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.extract_groups(portfolio)¶ Function to extract groups from portfolio_spec object.
- portfolioportfolio_spec,
an object of class portfolio_spec.
dictionary of groups if group_constraint is specified.
extract_weights extract_objective_measure extract_groups
>>> extract_groups(portfolio) NOTE: extract_groups will only work after calling optimize_portfolio on portfolio_spec
-
pyPortfolioAnalysis.pyPortfolioAnalysis.extract_objective_measure(R, portfolio, **kwargs)¶ Function to extract objective measures of optimal weights.
- Rpd.DataFrame,
dataframe of returns of assets in portfolio
- portfolioportfolio_spec,
an object of class portfolio_spec.
- kwargsadditional arguments, optional
any additional argument to be passed.
dictionary of objective measures as specified in the portfolio_spec object
extract_weights extract_objective_measure extract_groups
>>> extract_objective_measure(R, portfolio) NOTE: extract_objective_measure will only work after calling optimize_portfolio on portfolio_spec
-
pyPortfolioAnalysis.pyPortfolioAnalysis.extract_weights(portfolio)¶ Function to extract optimal weights.
- portfolioportfolio_spec,
an object of class portfolio_spec.
array of optimal weights
extract_objective_measure extract_groups
>>> extract_weights(portfolio) NOTE: extract_weights will only work after calling optimize_portfolio on portfolio_spec
-
pyPortfolioAnalysis.pyPortfolioAnalysis.factor_exposure_constraint(assets, B, lower, upper, kind='factor_exposure', enabled=True, message=False)¶ Add a factor exposure constraint for “K” different factos in a portdolio and also their exposure to particular asset.
- assetsint, or array-like,
named list of assets specifying initial weights.
- Bmatrix-like,
matrix or list of risk factor exposures
- lowerint, or array-like
list of lower limits of risk factor exposure constraints.
- upperint, or array-like
list of upper limits of risk factor exposure constraints.
- kindstr,
string of kind of constraints.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = False
bool to enable or disable messages.
Adds factor_exposure constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #Factor_exposure constraint is used to test portfolio with their impact on certaint factors >>> # factors can be single or multiple with lower and upper limit. >>> # B can be a N*K matrix for N assets and K factors. >>> # lower and upper arguments can be float for single factor and list for multiple factors >>> add_constraint(portfolio, kind = 'factor_exposure', B = np.matrix([[1.2,1.3], [2.3,1.4], [1.4,0.9], [3.4,1.2]]), lower = [0.8,1.4], upper = [2,2.4])
-
pyPortfolioAnalysis.pyPortfolioAnalysis.fn_map(weights, portfolio, relax=False, verbose=False)¶ This function transforms list of weights that does not meet the portfolio constraints to an array that meets the constraints. relax argument (default = False) if True gives the function permission to transform weights if needed
- weightsarray-like,
list of initial weights.
- portfolioportfolio_spec,
an object of class portfolio_spec.
- relaxbool, default = False
bool to enable or disable constraints.
- verbosebool, default = False
bool to enable or disable messages.
returns the array of weights tranformed by the function and that does satisfy the constraints. called by optimize_portfolio if optimize_method = ‘DEoptim’ or ‘pso’
-
pyPortfolioAnalysis.pyPortfolioAnalysis.generate_sequence(minimum=0.01, maximum=1.01, by=0.01, rounding=3)¶ The sequence of min<->max weights for random.
Creating a series of potential weights for portfolios of random or brute force.
- minimumfloat,
sequence minimum value
- maximumfloat,
sequence maximum value
- byfloat, optional
number to increase the series by
- roundingint, optional
integer the number of decimals we can round to
returns a series of ranfom weights that satisfy the min-max weights constraint. Default weight_seq for rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.get_constraints(portfolio)¶ Helper functionality to get the constraints allowed out of the portfolio object
- portfolioportfolio_spec,
an object of class portfolio_spec.
returns dictionary of constraints extracted from the portfolio_spec object
>>> port = portfolio_spec(3) >>> add_constraint('dollar_neutral') >>> get_constraint(port)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.group_constraint(assets, groups, group_min, group_max, kind='group', enabled=True, message=False)¶ Group constraints determine the grouping of assets, group weights, and the number of positions of the groups (i.e. non-zero weights).
- assetsInt, or array-like,
Number of assets or, as an alternative, a named asset list specifying initial weights.
- groupsDict,
dictionary specifying the assets groups.
- group_minfloat, or array-like,
numeric or named list defining the minimum constraints of the weight group.
- group_maxfloat, or array-like,
numeric or named list defining the maximum constraints of the weight group.
- kindstr,
string of kind of constraint.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = False
bool to enable or disable messages.
Adds group constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> add_constraint(portfolio, kind = 'group', group_min = [0.9, -0.5,-0.5, 0.1], group_max =1, groups = {'eqity':[0,3], 'debt':[1,2]})
-
pyPortfolioAnalysis.pyPortfolioAnalysis.group_fail(weights, groups=None, cLO=None, cUP=None, group_pos=None)¶ The role loops through each group and checks if the cLO or cUP for the given group has been breached. This is a rp_transform helper feature. Test if group limits have been breached.
- weightsarray-like,
test the list of weights
- groupsdict,
A dictionary defining the asset classes. similar in group_constraint.
- cLOfloat, or array-like,
Specifying minimum weight group constraints by numeric or vector.
- cUPfloat, or array-like,
Specifying maximum weight group constraints by numeric or vector.
- group_posarray-like, optional
A list that defines the number of non-zero weights for each category.
Bool returning “True” if group weights are breached
-
pyPortfolioAnalysis.pyPortfolioAnalysis.inverse_volatility_weights(R, portfoio, **kwargs)¶ Function to calculate objective_measure of inverse volatility portfolio
- Rpd.DataFrame,
dataframe of returns of assets in portfolio
- portfolioportfolio_spec,
an object of class portfolio_spec.
- kwargsadditional arguments, optional
any additional argument to be passed.
dictionary of objective measures of inverse volatility portfolio
equal_weight inverse_volatility_weight
>>> inverse_volatility_weight(R, portfolio)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.leverage_exposure_constraint(assets, leverage, kind='leverage_exposure', enabled=True, message=True)¶ A maximum leverage where leverage is stated as the total of the absolute value of the weights is determined under the leverage_exposure constraint.
- assetsint, or array-like,
leverage : maximum leverage value
- kindstr,
string of kind of constraints
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds leverage_exposure constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #constraint on the leverage of portfolio >>> add_constraint(portfolio, kind = 'leverage_exposure', leverage = 0.8)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.leverage_fail(weights, leverage=None)¶ It is used by rp_transform as a helper function to test if leverage constraint is breached.
- weightsarray-like,
test the list of weights.
- leveragefloat,
specify the leverage the portfolio must satisfy
Returns “True” if the weights fail the leverage_exposure constraint. Called by rp_transform. see rp_transform.
- pos_limit_fail
import numpy as np
import pandas as pd
rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.max_sum_fail(weights, max_sum=None)¶ it is used by rp_transform as a helper function to test if max_sum constraint is breached.
- weightsarray-like,
test the list of weights
- max_sumfloat, optional
max_sum of the weights of portfolio
Returns “True” if the weights fail the max_sum constraint. Called by rp_transform. see rp_transform.
fn_map, rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.min_sum_fail(weights, min_sum=None)¶ it is used by rp_transform as a helper function to test if min_sum constraint is breached.
- weightsarray-like,
test the list of weights
- min_sumfloat, optional
max_sum of the weights of portfolio
Returns “True” if the weights fail the min_sum constraint. Called by rp_transform. see rp_transform.
fn_map, rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.minmax_objective(name, minimum, maximum, multiplier=1, arguments=None, target=None, enabled=True)¶ This target allows to determine min and max goals. Constructor for the tmp_minmax_objective.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances.
- minimumfloat,
minimum value
- maximumfloat,
maximum value
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- argumentsdict,
Default arguments to be transferred when executed on an objective function.
- targetfloat,
Univariate goal for the target.
- enabledbool, default = True
bool to enable or disable constraints.
Adds minmax_objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'risk', name = 'std', target = 0.015) NOTE: you can add other custom function in other kind of objective in similar methd. See add_objective
-
pyPortfolioAnalysis.pyPortfolioAnalysis.normalize_weights(weights)¶ Add a constraint in portfolio_spec object
Main function to add or update constraint in portfolio_spec object
- weightsarray-like,
list of weights to normalize based on constraints.
Returns array of normalized weights. Called be optimize_portfolio when optimize_method is: ‘pso’, ‘dual_annealing’, ‘shgo’, ‘basinhopping’, ‘brute’.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.optimize_portfolio(R, portfolio=None, constraints=None, objectives=None, optimize_method=['pso', 'DEoptim', 'dual_annealing', 'brute', 'shgo', 'basinhopping', 'best'], search_size=20000, trace=False, message=False, **kwargs)¶ This function is calls the portfolio to optimize the weights given the constrained and objectives of portfolio provided using add_constraint and add_objective functions.
Main function to optimize portfolio weights given the constraints and objectives
- Rpandas dataframe,
dataframe of the series of returns
- portfolioportfolio_spec,
an object of class portfolio_spec.
- constraintsdict, optional
constraints to be minimized/maximized given the assets. Although they are automatically called if portfolio_spec object has constraints specified
- objectivesdict, optional
objectives to be minimized/maximized given the assets. Although they are automatically called if portfolio_spec object has objectives specified
- optimize_methodfloat,
the method for optimizing portfolio. currently supported methods are: ‘pso’ ‘DEoptim’ ‘dual_annealing’ ‘brute’ ‘shgo’ ‘basinhopping’
User can also specify ‘best’ as optimize_method to use all optimizer and choose the best among them.
- search_size: int, optional
specify th iterations to do before calling the best portfolio
- tracebool, default = False
bool to enable or disable trace of portfolio.
- messagebool, default = False
bool to enable or disable messages.
- kwargsadditional key word arguments, optional
any additional constraint argument to be passed.
returns the optimal weights, objective measure, value of the best optimization (out). automatically adds weights to the portfolio_spec objects.
portfolio_spec add_constraint add_objective
- currently suuported optimization methods are:
‘pso’ ‘DEoptim’ ‘dual_annealing’ ‘brute’ ‘shgo’ ‘basinhopping’
The function calls constrained_objective to minimize the penalty (default = 10000) to come to a solution. the purpose of adding different optimization method is to give flexibility to user to choose optimizer based on specific problem.
Additional arguments can be specified such as maxiter, disp and other controls. the argument names are similar in scipy.optimize.[optimizer] or pyswarms. see scipy and pyswarm documentation.
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'return', name = 'mean', target = 0.0018) >>> add_objective(kind = 'portfolio_risk', name = 'std', target = 0.015) >>> add_objective(kind = 'risk_budget', name = 'risk_budget') >>> add_objective(kind = 'weight_conc', name = 'HHI', target = 0.11) >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
>>> optimize_portfolio(R, port, optimize_method = 'DEoptim', disp = False, search_size = 30000) NOTE: Yout can provide addional adguments based on solver. See the solver documentation for more information. >>> # we have used scipy.optimize for most of the solver and pyswarms for 'pso' method.
>>> optimize_portfolio(R, port, optimize_method = 'best', disp = False, maxiter = 1000) NOTE: 'best' optimize_method takes a while to give ouput because it uses all other optimizers.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.performance_metrics_objective(name, arguments, target=None, multiplier=1, enabled=True)¶ We’ll try minimizing the performance_metric if the target is null. Constructor for the portfolio_risk_objective class.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances
- targetfloat,
Univariate goal for the target.
- argumentsdict, optional
Default arguments to be transferred when executed on an objective function.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- enabledbool, default = True
bool to enable or disable constraints.
Adds portfolio risk objectives to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE
>>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.port_mean(weights, mu)¶ Add a constraint in portfolio_spec object Main function to add or update constraint in portfolio_spec object
- weightsarray-like,
weights of the portfolio.
- muarray-like,
mean return of assets
Adds port mean to object portfolio_spec of the specified input.
mu_{p} = w . mu_{r}
var_portfolio VaR cVaR
>>> #calculate the portfolio mean return >>> w = [0.2,0.3,-0.1,0.6,0.8] >>> port_mean(w,R)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.portfolio_risk_objective(name, target, arguments, multiplier=- 1, enabled=True)¶ We’ll try minimizing the risk metric if the target is null. Constructor for the portfolio_risk_objective class.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances
- targetfloat,
Univariate goal for the target.
- argumentsdict, optional
Default arguments to be transferred when executed on an objective function.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- enabledbool, default = True
bool to enable or disable constraints.
Adds portfolio risk objectives to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'portfolio_risk', name = 'std', target = 0.015) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
class
pyPortfolioAnalysis.pyPortfolioAnalysis.portfolio_spec(assets, category_labels=None, weights_seq=None, message=False)¶ Bases:
objectA class to call portfolio_spec object.
portfolio_spec object is the main class that contains all the constraints, objectives, optimal weights; it is called by many functions to get relevant attributes and store attributes.
…
- assetsint, or array-like,
add assets to portfolio either via name of assets in the form of an array or int of number of assets.
- category_label: dict, optional
dictionary of different categories assigned to different assets. similar to group_constraint. See group_constraint.
- weights_seqsequence, optional
sequence of random weights. These weights will be used to optimize weights. See generate_sequence
- messagebool, default = False
bool to enable or diable message
- port_summary():
returns a dictionary of the summary of constraints and objective added by add_consraint and add_objective funtions. See add_constraint, add_objective
- optimal_portfolio():
returns a dictionary of optimal weights, objective measure and minimum value calculated by the specified solver NOTE: optimal_portfolio will only return result if optimize_portfolio is called. See optimize_portfolio
-
optimal_portfolio()¶ summary of the portfolio
method to provide a summary of the optimal weights, objective and minimum output of portfolio.
- dict:
returns a dictionary of optimal weights, objective and minimum output of portfolio
portfolio_spec optimize_portfolio
>>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> p1 = portfolio_spec(assets = 3) >>> add_constraint(portfolio = p1, kind = 'factor_exposure', B = [0.2,0.2,0.4], lower = 1.0, upper = 0.9) >>> add_constraint(portfolio = p1, kind = 'group', groups = dict(zip(['equity','debt'],[[0,1], [2]])), group_min = 0.2, group_max = 0.5) >>> add_constraint(portfolio = p1, kind = 'transaction', ptc = 0.2) >>> add_objective(portfolio = p1, kind = 'return', target = 0.1, name = 'return_obj') >>> add_objective(portfolio = p1, kind = 'minmax', minimum = 0.2, maximum = 0.3,name = 'risk') >>> optimize_portfolio(R, p1, optimize_method = 'DEoptim') >>> p1.optimal_weights()
-
port_summary()¶ summary of the portfolio
method to provide a summary of the portfolio.
- dict:
returns a dictionary of all constraints and objective
portfolio_spec optimize_portfolio
>>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> p1 = portfolio_spec(assets = 3) >>> add_constraint(portfolio = p1, kind = 'factor_exposure', B = [0.2,0.2,0.4], lower = 1.0, upper = 0.9) >>> add_constraint(portfolio = p1, kind = 'group', groups = dict(zip(['equity','debt'],[[0,1], [2]])), group_min = 0.2, group_max = 0.5) >>> add_constraint(portfolio = p1, kind = 'transaction', ptc = 0.2) >>> add_objective(portfolio = p1, kind = 'return', target = 0.1, name = 'return_obj') >>> add_objective(portfolio = p1, kind = 'minmax', minimum = 0.2, maximum = 0.3,name = 'risk') >>> p1.port_summary()
-
pyPortfolioAnalysis.pyPortfolioAnalysis.pos_limit_fail(weights, max_pos=None, max_pos_long=None, max_pos_short=None)¶ This is used as a rp_transform helper function to search for position limit constraints being violated.
- weightsarray-like,
test list of weights.
- max_posint, optional
maximum number of non-zero-weighted assets
- max_pos_longint, optional
maximum number of long-position assets
- max_pos_shortint, optional
maximum number of short-position assets
Returns “True” if the weights fail the pos_limit constraint. called by rp_transform. see rp_transform.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.position_limit_constraint(assets, max_pos=None, kind='position', max_pos_long=None, max_pos_short=None, enabled=True, message=True)¶ When type=”position_limit” is mentioned, this function is called by add.constraint.
The maximum number of positions as well as the maximum number of long and short positions are determined by the user using this function.
- assetsint, or array-like,
named list of assets determining initial weights.
- max_posint,
maximum number of assets with non-zero weights.
- kindstr,
string of kind of constraint
- max_pos_longInt, optional
maximum number of assets with long positions.
- max_pos_shortInt, optional
maximum number of assets with short positions.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds position_limit constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #position_limit is a constraint to restrict max position and also max long/short positions >>> add_constraint(portfolio, kind = 'position_limit', max_pos = 3, max_pos_long = 2, max_pos_short = 2)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.return_constraint(assets, return_target, kind='return', enabled=True, message=False)¶ Target mean return value is determined by the return constraint. When type=”return” is mentioned, this function is called by add_constraint.
- assets :. int, or array-like,
named list of assets determining initial weights.
- kindstr,
string of kind of constraints.
- enabledbool, default = True
bool to enable or disable constraints.
- messagesbool, default = False
bool to enable or disable messages.
Adds return constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #return constraint to add a target mean historical return to the portfolio >>> add_constraint(portfolio, kind = 'return', return_target = 0.0018)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.return_objective(name, target, arguments, multiplier=- 1, enabled=True)¶ We’ll try minimizing the risk metric if the target is null. Constructor for the portfolio_risk_objective class.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances
- targetfloat,
Univariate goal for the target.
- argumentsdict, optional
Default arguments to be transferred when executed on an objective function.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- enabledbool, default = True
bool to enable or disable constraints.
Adds return_objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'return', name = 'mean', target = 0.0018) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.risk_budget_objective(assets, name, min_prisk=None, max_prisk=None, target=None, arguments=None, multiplier=1, enabled=True, min_concentration=False, min_difference=False)¶ Constructor for the risk_budget_objective.
- assetsint, or array-like,
The asset list to be used should come from object constraints.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances.
- min_priskfloat,
minimum percentage risk contribution
- max_priskfloat,
maximum percentage risk contribution
- argumentsdict, optional
Default arguments to be transferred when executed on an objective function.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
Adds risk budget objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
- Examples
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> add_objective(kind = 'risk_budget', name = 'risk_budget') >>> add_objective(kind = 'weight_conc', name = 'HHI', target = 0.11) >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.rp_decrease(weights, max_sum, min_box, weight_seq)¶ It is used by rp_transform as a helper function to reduce weights if max_sum or min_box constraint is breached.
- weightsarray-like,
test of list of weights
- max_sumfloat,
maximum sum of weights
- min_boxarray-like,
minimum of individual weights in a portfolio
- weight_seqseq,
sequence of random weights to choose from
returns an array of weights that satisfy the max_sum and min_box constraint. called by rp_transform.
rp_increase rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.rp_decrease_leverage(weights, max_box, min_box, leverage, weight_seq)¶ It is used by rp_transform as a helper function to redcrese leverage if leverage_exposure constraint is breached.
- weightsarray-like,
test of list of weights
- max_boxarray-like,
maximum of individual weights in a portfolio
- min_boxlike,
minimum of individual weights in a portfolio
- leverage: float,
leverage as specified in leverage_exposure constraints
- weight_seqseq,
sequence of random weights to choose from
returns an array of weights that satisfy the leverage constraint. called by rp_transform.
rp_increase rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.rp_increase(weights, min_sum, max_box, weight_seq)¶ It is used by rp_transform as a helper function to increase weights if min_sum or max_box constraint is breached.
- weightsarray-like,
test of list of weights
- max_sumfloat,
maximum sum of weights
- min_boxfloat,
minimum of individual weights in a portfolio
- weight_seqseq,
sequence of random weights to choose from
returns an array of weights that satisfy the max_sum and min_box constraint. called by rp_transform.
rp_increase rp_transform
-
pyPortfolioAnalysis.pyPortfolioAnalysis.rp_position_limit(weights, min_box, max_box, weight_seq, max_pos=None, max_pos_long=None, max_pos_short=None)¶ It is used by rp_transform as a helper function to increase weights if position_limit constraint is breached.
- weightsarray-like,
test of list of weights
- min_boxarray-like,
maximum of individual weights in a portfolio
- min_boxarray-like,
minimum of individual weights in a portfolio
- max_posint, optional
maximum position to hold in a portfolio
- max_pos_longint, optional
maximum long position to hold in a portfolio
- max_pos_shortint, optional
maximum short position to hold in a portfolio
- weight_seqseq,
sequence of random weights to choose from
returns an array of weights that satisfy the position limit constraint. called by rp_transform.
rp_increase rp_transform rp_decrease_leverage
-
pyPortfolioAnalysis.pyPortfolioAnalysis.rp_transform(w, min_sum, max_sum, min_box, max_box, groups=None, cLO=None, cUP=None, group_pos=None, max_pos=None, max_pos_long=None, max_pos_short=None, leverage=None, weight_seq=None, max_permutations=2000)¶ This function is mainly used to transform weights that dont satisfy the constraints such as: “box” “group” “max_pos” “leverage_exposure” See add_constraint for more deatils.
Transform a list of weights to fulfill constraints
- weightsarray-like,
list of weights to be transformed
- min_sumfloat,
minimum total of all weights of assets, default of 0.99
- max_sumfloat,
maximum total of all weights of assets, default of 1.01
- min_boxarray-like,
numeric or called list defining the minimum constraints of the weight box
- max_boxarray-like
numeric or called list defining the maximum constraints of the weight box
- groupsdict,
a dictionary defining the asset groups. similar to group_constraint. see group_constraint
- cLOflaot, or array-like,
float or list defining the minimum constraints of the weight group
- cUPfloat, or array-like
float or list defining the minimum constraints of the weight group
- group_posarray-like, optional
list that specifies the maximum number of non-zero-weight assets per group
- max_posint,
maximum non-zero-weight assets
- max_pos_longint
maximum number of long (i. e. buy) position assets
- max_pos_shortint,
maximum number of short (i. e. sell) position assets
- leveragefloat,
maximum exposure to leverage in which leverage is defined as sum(abs(weights))
- weight_seqseq, optional
list of seed sequence of weights. uses generate_sequence()
- max_permutationsint, optional
integer- maximum number of iterations to try for a portfolio which is valid, default 2000
weights array that satisfy the constraints on portfolio
rp_increase rp_decrease fn_map
-
pyPortfolioAnalysis.pyPortfolioAnalysis.transaction_cost_constraint(assets, ptc, kind='transaction', enabled=True, message=True)¶ A proportional cost value is determined under the transaction cost constraint. When type=”transaction_cost” is specified, this function is called by add.constraint.
- assetsint, or array-like,
number of assets, or optionally a named list of assets determining initial weights.
- ptcfloat,
proportional transaction cost value.
- kindstr,
string of kind of constraint
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds transaction _cost constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #adds a tranaction cost constraint on portfolio >>> add_constraint(portfolio, kind = 'transaction_cost', ptc = 0.1)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.turnover(weights, wgt_init=None)¶ Turnover estimation of two weight lists. This is used as an objective function and is named when the user adds with add.objective an objective of type turnover.
- weightsarray-like,
Weights list from optimization.
- wgt_initarray-like, optional
Initial weights list used for measuring turnover from.
returns the turnover of the portfolio given the weights
var_portfolio port_mean
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> w = [0.2,0.3,0.4,-.4,0.5] >>> turnover(w)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.turnover_constraint(assets, turnover_target, kind='turnover', enabled=True, message=True)¶ Target turnover value is determined under the turnover constraint. When type=”turnover” is stated, the function is called by add.constraint
- assetInt, or array-like,
Number of assets or, as an alternative, a named asset list specifying initial weights.
- kindstr,
character kind of the constraint.
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds turnover constraints to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> #turnover constraint >>> add_constraint(portfolio, kind = 'turnover', turnover_target = 0.1)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.turnover_objective(name, arguments, target=None, multiplier=1, enabled=True)¶ We’ll try minimizing the turnover metric if the goal is null. Constructor for the turnover_objective class.
- namestr,
The target name should correspond to a feature, although we will attempt to make allowances.
- argumentsdict,
Default arguments to be transferred when executed on an objective function.
- targetfloat,
Univariate goal for the target.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- enabledbool, default = True
bool to enable or disable constraints.
Adds turnover_objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> #adding objectives >>> >>> add_objective(kind = 'turnover', name = 'turnover', target = 0.2) >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE >>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.var_portfolio(R, weights)¶ When var is an object for mean variance or quadratic utility optimization, this function is used to measure the portfolio variance through a call to constrained_objective.
Main function to calculate portfolio variance
- Rpd.DataFrame,
return series
- weights: array-like,
list of weights of assets.
returns the variance of the portfolio given the following weights.
sigma_{p} = w Sigma_{p} w^{T}
port_mean VaR cVaR
>>> # calculate the variance of portfolio >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> w = [0.2,0.3,-0.1,0.6,0.8] >>> var_portfolio(w,R)
-
pyPortfolioAnalysis.pyPortfolioAnalysis.weight_concentration_objective(name, conc_aversion, conc_groups=None, multiplier=1, arguments=None, enabled=True)¶ Using the HHI as a concentration scale, this feature penalizes weight concentration Constructor for objective of weight concentration.
- namestr,
The name of the concentration measure is currently only supported by “HHI”.
- conc_aversionfloat,
concentration value(s) of aversion
- conc_groupsdict,
A dictionary defining the asset classes. Similar to ‘group constraint’ groups.
- multiplierint, optional
Multiplier to be added to the target, typically 1 or -1.
- argumentsdict, optional
Default arguments to be transferred when executed on an objective function.
- enabledbool, default = True
bool to enable or disable constraints.
Adds weight constraints objective to object portfolio_spec of the specified input.
add_objectives portfolio_risk_objectives risk_budget_objective turnover_objective minmax_objective weight_constraint_objective
>>> port = portfolio_spec(assets = 5) >>> import pandas_datareader as pdr >>> aapl = pdr.get_data_yahoo('AAPL') >>> msft = pdr.get_data_yahoo('MSFT') >>> tsla = pdr.get_data_yahoo('TSLA') >>> uber = pdr.get_data_yahoo('UBER') >>> amzn = pdr.get_data_yahoo('AMZN') >>> port = pd.DataFrame({'aapl': pd.DataFrame.reset_index(aapl).iloc[:,6], 'msft':pd.DataFrame.reset_index(msft).iloc[:,6], 'tsla': pd.DataFrame.reset_index(tsla).iloc[:,6], 'uber':pd.DataFrame.reset_index(uber).iloc[:,6], 'amzn': pd.DataFrame.reset_index(amzn).iloc[:,6]}) >>> port_ret = port.pct_change().dropna() >>> R = port_ret >>> add_constraint('long_only') >>> add_constraint('full_investment') >>> add_objective(kind = 'weight_conc', name = 'HHI', target = 0.11) >>> add_objective(kind = 'performance_metrics', name = 'sharpe', target = 0.13) >>> # add a custom objective by first defining it. >>> def sortino_ratio(w,R): #SOME CODE
>>> add_objective(kind = 'performance_metrics', name = {'sortino':sortino_ratio}, target = 0.35) NOTE: The output of sortino_ratio or other custom function in objective must be a float. NOTE: you can also add other custom function in other kind of objective in similar methd.
-
pyPortfolioAnalysis.pyPortfolioAnalysis.weight_sum_constraint(assets, kind='weight_sum', min_sum=0.99, max_sum=1.01, enabled=True, message=True)¶ The constraint determines the sum of the weights of the upper and lower limits. This function is called add.constraint when the type is defined as “weight sum”, “leverage”, “full investment”, “dollar neutral” or “active”
- assetsInt, or array-like,
Number of assets or, as an alternative, a named asset list specifying initial weights.
- kindstr,
character kind of the constraint.
- min_sumfloat,
Minimum sum of all weights of assets, default 0.99
- max_sumfloat,
Maximum sum of all weights of assets, default 1.01
- enabledbool, default = True
bool to enable or disable constraints.
- messagebool, default = True
bool to enable or disable messages.
Adds weight_sum constraint to object portfolio_spec of the specified input.
add_constraints box_constraints group_constraints weight_sum_constraint turnover_constraint diversification_constraint position_limit_constraint return_constraint factor_exposure_constraint transaction_cost_constraint leverage_exposure_constraint
>>> # adding weight_sum constraint >>> add_constraint(portfolio, kind = 'weight_sum', min_sum = 0.9, max_sum = .95) >>> # special case of weight_sum is dollar_neutral/active or full_investment >>> add_constraint(portfolio, kind = 'dollar_neutral') >>> add_constraint(portfolio, kind = 'full_investment')
Module contents¶
pyPortfolioAnalysis: Methods to optimize portfolio¶
Documentation is available as docstring or as HTML on https://github.com/anuragagrawaal/pyPortfolioAnalysis
Functions and Classes
Optimization Methods¶
‘HHI’ ‘VaR’ ‘VaR_portfolio’ ‘add_constraint’ ‘add_objective’ ‘black_litterman’ ‘box_constraint’ ‘cVaR_portfolio’ ‘constrained_objective’ ‘diversification’ ‘diversification_constraint’ ‘equal_weight’ ‘extract_groups’ ‘extract_objective_measure’ ‘extract_weights’ ‘factor_exposure_constraint’ ‘fn_map’ ‘generate_sequence’ ‘get_constraints’ ‘group_constraint’ ‘group_fail’ ‘inverse_volatility_weights’ ‘leverage_exposure_constraint’ ‘leverage_fail’ ‘max_sum_fail’ ‘min_sum_fail’ ‘minmax_objective’ ‘normalize_weights’ ‘optimize_portfolio’ ‘performance_metrics_objective ‘port_mean’ ‘portfolio_risk_objective’ ‘portfolio_spec’ ‘pos_limit_fail’ ‘position_limit_constraint’ ‘return_constraint’ ‘return_objective’ ‘risk_budget_objective’ ‘rp_decrease’ ‘rp_decrease_leverage’ ‘rp_increase’ ‘rp_position_limit’ ‘rp_transform’ ‘transaction_cost_constraint’ ‘turnover’ ‘turnover_constraint’ ‘turnover_objective’ ‘var_portfolio’ ‘weight_concentration_objective’ ‘weight_sum_constraint’
Plots¶
‘chart_efficient_frontier’ ‘chart_group_weights’ ‘chart_weights’
References¶
Brian G. Peterson and Peter Carl (2018). PortfolioAnalytics: Portfolio Analysis, Including Numerical Methods for Optimization of Portfolios. R package version 1.1.0. https://CRAN.R-project.org/package=PortfolioAnalytics
Boudt, Kris and Lu, Wanbo and Peeters, Benedict, Higher Order Comoments of Multifactor Models and Asset Allocation (June 16, 2014). Available at SSRN: http://ssrn.com/abstract=2409603 or http://dx.doi.org/10.2139/ssrn.2409603
Chriss, Neil A and Almgren, Robert, Portfolios from Sorts (April 27, 2005). Available at SSRN: http://ssrn.com/abstract=720041 or http://dx.doi.org/10.2139/ssrn.720041
Meucci, Attilio, The Black-Litterman Approach: Original Model and Extensions (August 1, 2008). Shorter version in, THE ENCYCLOPEDIA OF QUANTITATIVE FINANCE, Wiley, 2010. Avail- able at SSRN: http://ssrn.com/abstract=1117574 or http://dx.doi.org/10.2139/ssrn.1117574
Meucci, Attilio, Fully Flexible Views: Theory and Practice (August 8, 2008). Fully Flexible Views: Theory and Practice, Risk, Vol. 21, No. 10, pp. 97-102, October 2008. Available at SSRN: http://ssrn.com/abstract=1213325
Scherer, Bernd and Martin, Doug, Modern Portfolio Optimization. Springer. 2005.
Shaw, William Thornton, Portfolio Optimization for VAR, CVaR, Omega and Utility with General Return Distributions: A Monte Carlo Approach for Long-Only and Bounded Short Portfolios with Optional Robustness and a Simplified Approach to Covariance Matching (June 1, 2011). Available at SSRN: http://ssrn.com/abstract=1856476 or http://dx.doi.org/10.2139/ssrn.1856476