Portfolio Management
As mentioned above, FinQuant is a program for financial portfolio management, among others.
The module finquant.portfolio
does exactly that.
Note
The impatient reader who simply wants to jump in and start using FinQuant is advised to jump to build_portfolio and have a look at and play around with the Examples.
This module is the core of FinQuant. It provides
a public class
Portfolio
that holds and calculates quantities of a financial portfolio, which is a collection ofStock
instances (theStock
class is provided infinquant.stock
and is a child class ofAsset
defined infinquant.asset
).a public function
build_portfolio()
that automatically constructs and returns an instance ofPortfolio
and instances ofStock
. The relevant stock data is either retrieved through quandl/yfinance or provided by the user as apandas.DataFrame
(after loading it manually from disk/reading from file). For an example on how to use it, please read the corresponding docstring, or have a look at the examples in the sub-directoryexample
.
The class Portfolio
is designed to easily manage your financial portfolio,
and makes the most common quantitative calculations, such as:
cumulative returns of the portfolio’s stocks
daily returns of the portfolio’s stocks (daily percentage change),
daily log returns of the portfolio’s stocks,
Expected (annualised) Return,
Volatility,
Downside Risk,
Value at Risk,
Sharpe Ratio,
Sortino Ratio,
Treynor Ratio (optional),
Beta parameter (optional),
R squared coefficient (optional),
skewness of the portfolio’s stocks,
Kurtosis of the portfolio’s stocks,
the portfolio’s covariance matrix.
Furthermore, the constructed portfolio can be optimised for
minimum Volatility,
maximum Sharpe Ratio
minimum Volatility for a given Expected Return
maximum Sharpe Ratio for a given target Volatility
by either performing a numerical computation to solve a minimisation problem, or by performing a Monte Carlo simulation of n trials. The former should be the preferred method for reasons of computational effort and accuracy. The latter is only included for the sake of completeness.
Finally, functions are implemented to generate the following plots:
Monte Carlo run to find optimal portfolio(s)
Efficient Frontier
Portfolio with the minimum Volatility based a numerical optimisation
Portfolio with the maximum Sharpe Ratio based on a numerical optimisation
Portfolio with the minimum Volatility for a given Expected Return based on a numerical optimisation
Portfolio with the maximum Sharpe Ratio for a given target Volatility based on a numerical optimisation
Individual stocks of the portfolio (Expected Return over Volatility)
Portfolio
- class finquant.portfolio.Portfolio
Object that contains information about an investment portfolio. To initialise the object, it does not require any input. To fill the portfolio with investment information, the function
add_stock(stock)
should be used, in whichstock
is an object ofStock
.- __init__()
Initiates
Portfolio
.
- add_stock(stock, defer_update=False)
Adds a stock of type
Stock
to the portfolio. Each timeadd_stock
is called, the following instance variables are updated:portfolio
:pandas.DataFrame
, adds a column with information fromstock
stocks
:dictionary
, adds an entry forstock
data
:pandas.DataFrame
, adds a column of stock prices fromstock
Also, if argument
defer_update
isTrue
, the following instance variables are (re-)computed:expected_return
: Expected Return of the portfoliovolatility
: Volatility of the portfoliodownside_risk
: Downside Riskvar
: Value at Risk of the portfoliosharpe
: Sharpe Ratio of the portfoliosortino
: Sortino Ratio of the portfolioskew
: Skewness of the portfolio’s stockskurtosis
: Kurtosis of the portfolio’s stocks
If argument
defer_update
isTrue
and__market_index
is notNone
, the following instance variables are (re-)computed as well:beta
: Beta parameter of the portfoliorsquared
: R squared coefficient of the portfoliotreynor
: Treynor Ratio of the portfolio
- Parameters:
stock (
Stock
) – An instance of the classStock
.defer_update (
bool
) – bool, if True instance variables are not (re-)computed at the end of this method.
- Return type:
None
- comp_beta()
Compute and return the Beta parameter of the portfolio.
- Return type:
Union
[floating
,float
,None
]- Returns:
Beta parameter of the portfolio
- comp_cov()
Compute and return a DataFrame of the covariance matrix of the portfolio.
- Return type:
DataFrame
- Returns:
Covariance matrix of the portfolio.
- comp_cumulative_returns()
Computes the cumulative returns of all stocks in the portfolio. See
finquant.returns.cumulative_returns
.- Return type:
DataFrame
- Returns:
Cumulative returns of given stock prices.
- comp_daily_log_returns()
Computes the daily log returns of all stocks in the portfolio. See
finquant.returns.daily_log_returns
.- Return type:
DataFrame
- Returns:
Daily log Returns of given stock prices.
- comp_daily_returns()
Computes the daily returns (percentage change) of all stocks in the portfolio. See
finquant.returns.daily_returns
.- Return type:
DataFrame
- Returns:
Daily percentage change of Returns of given stock prices.
- comp_downside_risk(freq=252)
Computes the downside risk of the portfolio.
- Parameters:
freq (
INT
) – Number of trading days in a year, default: 252- Return type:
Union
[floating
,float
]- Returns:
Downside risk of the portfolio.
- comp_expected_return(freq=252)
Computes the Expected Return of the portfolio.
- comp_mean_returns(freq=252)
Computes the mean returns based on historical stock price data. See
finquant.returns.historical_mean_return
.- Parameters:
freq (
INT
) – Number of trading days in a year, default: 252- Return type:
Series
- Returns:
Historical mean Returns.
- comp_rsquared()
Compute and return the R squared coefficient of the portfolio.
- Return type:
- Returns:
R squared coefficient of the portfolio
- comp_sharpe()
Compute and return the Sharpe Ratio of the portfolio.
- Return type:
Union
[floating
,float
]- Returns:
The Sharpe Ratio of the portfolio.
- comp_sortino()
Compute and return the Sortino Ratio of the portfolio
- Return type:
Union
[floating
,float
]- Returns:
The Sortino Ratio of the portfolio. May be
NaN
if the portoflio outperformed the risk free rate at every point
- comp_stock_volatility(freq=252)
Computes the Volatilities of all the stocks individually
- Parameters:
freq (
INT
) – Number of trading days in a year, default: 252- Return type:
Series
- Returns:
Individual volatilities of all stocks in the portfolio.
- comp_treynor()
Compute and return the Treynor Ratio of the portfolio.
- Return type:
- Returns:
The Treynor Ratio of the portfolio.
- comp_var()
Compute and return the Value at Risk of the portfolio.
- Return type:
Union
[floating
,float
]- Returns:
The Value at Risk (VaR) of the portfolio.
- comp_volatility(freq=252)
Computes the Volatility of the given portfolio.
- comp_weights()
Computes and returns a
pandas.Series
of the weights/allocation of the stocks of the portfolio.- Return type:
Series
- Returns:
A Series with weights/allocation of all stocks within the portfolio.
- ef_efficient_frontier(targets=None)
Interface to
finquant.efficient_frontier.EfficientFrontier.efficient_frontier
.Gets portfolios for a range of given target Returns. If no targets were provided, the algorithm will find the minimum and maximum Returns of the portfolio’s individual stocks, and set the target range according to those values. Results in the Efficient Frontier.
- Parameters:
targets (
Union
[ndarray
[Union
[floating
,float
],Any
],List
[Union
[floating
,float
]],None
]) – A list/array: range of target returns, default:None
- Return type:
ndarray
[float64
,Any
]- Returns:
Efficient Frontier as an array of (volatility, Return) values
- ef_efficient_return(target, verbose=False)
Interface to
finquant.efficient_frontier.EfficientFrontier.efficient_return
.Finds the portfolio with the minimum Volatility for a given target return.
- Parameters:
target (
NUMERIC
) – The target return of the optimised portfolio.verbose (
bool
) – Whether to print out properties or not, default: False
- Return type:
DataFrame
- Returns:
A DataFrame of weights/allocation of stocks within the optimised portfolio.
- ef_efficient_volatility(target, verbose=False)
Interface to
finquant.efficient_frontier.EfficientFrontier.efficient_volatility
.Finds the portfolio with the maximum Sharpe Ratio for a given target Volatility.
- Parameters:
target (
NUMERIC
) – The target return of the optimised portfolio.verbose (
bool
) – Whether to print out properties or not, default: False
- Return type:
DataFrame
- Returns:
A DataFrame of weights/allocation of stocks within the optimised portfolio.
- ef_maximum_sharpe_ratio(verbose=False)
Interface to
finquant.efficient_frontier.EfficientFrontier.maximum_sharpe_ratio
.Finds the portfolio with the maximum Sharpe Ratio, also called the tangency portfolio.
- Parameters:
verbose (
bool
) – Whether to print out properties or not, default: False- Return type:
DataFrame
- Returns:
A DataFrame of weights/allocation of stocks within the optimised portfolio.
- ef_minimum_volatility(verbose=False)
Interface to
finquant.efficient_frontier.EfficientFrontier.minimum_volatility
.Finds the portfolio with the minimum Volatility.
- Parameters:
verbose (
bool
) – Whether to print out properties or not, default: False- Return type:
DataFrame
- Returns:
A DataFrame of weights/allocation of stocks within the optimised portfolio.
- ef_plot_efrontier()
Interface to
finquant.efficient_frontier.EfficientFrontier.plot_efrontier
.Plots the Efficient Frontier.
- Return type:
None
- ef_plot_optimal_portfolios()
Interface to
finquant.efficient_frontier.EfficientFrontier.plot_optimal_portfolios
.Plots markers of the optimised portfolios for :rtype:
None
minimum Volatility, and
maximum Sharpe Ratio.
- get_stock(name)
Returns the instance of
Stock
with namename
.- Parameters:
name (
str
) – String of the name of the stock that is returned. Must match one of the labels in the dictionarypf.stocks
.- Return type:
- Returns:
Instance of
Stock
taken from the portfolio.
- mc_optimisation(num_trials=1000)
Interface to
finquant.monte_carlo.MonteCarloOpt.optimisation
.Optimisation of the portfolio by performing a Monte Carlo simulation.
- Parameters:
num_trials (
int
) – Number of portfolios to be computed, each with a random distribution of weights/allocation in each stock, default: 1000- Return type:
Tuple
[DataFrame
,DataFrame
]- Returns:
- opt_w:
DataFrame with optimised investment strategies for maximum Sharpe Ratio and minimum volatility.
- opt_res:
DataFrame with Expected Return, Volatility and Sharpe Ratio for portfolios with minimum Volatility and maximum Sharpe Ratio.
- mc_plot_results()
Plots the results of the Monte Carlo run, with all of the randomly generated weights/portfolios, as well as markers for the portfolios with the minimum Volatility, and maximum Sharpe Ratio.
- Return type:
None
- mc_properties()
Calculates and prints out Expected annualised Return, Volatility and Sharpe Ratio of optimised portfolio.
- Return type:
None
- plot_stocks(freq=252)
Plots the Expected annual Returns over annual Volatility of the stocks of the portfolio.
- Parameters:
freq (
INT
) – Number of trading days in a year, default: 252- Return type:
None
- properties()
Nicely prints out the properties of the portfolio:
Expected Return,
Volatility,
Downside Risk,
Value at Risk (VaR),
Confidence level of VaR,
Sharpe Ratio,
Sortino Ratio,
Treynor Ratio (optional),
Beta (optional),
R squared (optional),
skewness,
Kurtosis
as well as the allocation of the stocks across the portfolio.
- Return type:
None
build_portfolio
- portfolio.build_portfolio()
This function builds and returns an instance of
Portfolio
given a set of input arguments.- Parameters:
pf_allocation – (optional) A DataFrame with the required data column labels
Name
andAllocation
of the stocks. If not given, it is automatically generated with an equal weights for all stocks in the resulting portfolio.names – (optional) A List of strings, containing the names of the stocks, e.g. “GOOG” for Google.
start_date – (optional) string/datetime start date of stock data to be requested through quandl/yfinance (default:
None
).end_date – (optional) string/datetime end date of stock data to be requested through quandl/yfinance (default:
None
).data – (optional) A DataFrame which contains quantities of the stocks listed in
pf_allocation
.data_api –
(optional) A string (default:
quandl
) which determines how to obtain stock prices, if data is not provided by the user. Valid values:quandl
(Python package/API to Quandl)yfinance
(Python package formerly known asfix-yahoo-finance
)
market_index – (optional) A string (default:
None
) which determines the market index to be used for the computation of the Treynor ratio, beta parameter and the R squared coefficient of the portflio.
- Return type:
- Returns:
Instance of
Portfolio
which contains all the information requested by the user.
Note
Only the following combinations of inputs are allowed:
names
,pf_allocation
(optional),start_date
(optional),end_date
(optional),data_api
(optional),market_index
(optional)data
,pf_allocation
(optional)
The two different ways this function can be used are useful for:
building a portfolio by pulling data from quandl/yfinance,
building a portfolio by providing stock data which was obtained otherwise, e.g. from data files.
If used in an unsupported way, the function (or subsequently called function) raises appropriate Exceptions with useful information what went wrong.