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 of Stock instances (the Stock class is provided in finquant.stock and is a child class of Asset defined in finquant.asset).

  • a public function build_portfolio() that automatically constructs and returns an instance of Portfolio and instances of Stock. The relevant stock data is either retrieved through quandl/yfinance or provided by the user as a pandas.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-directory example.

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 which stock is an object of Stock.

__init__()

Initiates Portfolio.

add_stock(stock, defer_update=False)

Adds a stock of type Stock to the portfolio. Each time add_stock is called, the following instance variables are updated:

  • portfolio: pandas.DataFrame, adds a column with information from stock

  • stocks: dictionary, adds an entry for stock

  • data: pandas.DataFrame, adds a column of stock prices from stock

Also, if argument defer_update is True, the following instance variables are (re-)computed:

  • expected_return: Expected Return of the portfolio

  • volatility: Volatility of the portfolio

  • downside_risk: Downside Risk

  • var: Value at Risk of the portfolio

  • sharpe: Sharpe Ratio of the portfolio

  • sortino: Sortino Ratio of the portfolio

  • skew: Skewness of the portfolio’s stocks

  • kurtosis: Kurtosis of the portfolio’s stocks

If argument defer_update is True and __market_index is not None, the following instance variables are (re-)computed as well:

  • beta: Beta parameter of the portfolio

  • rsquared: R squared coefficient of the portfolio

  • treynor: Treynor Ratio of the portfolio

Parameters:
  • stock (Stock) – An instance of the class Stock.

  • 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.

Parameters:

freq (INT) – Number of trading days in a year, default: 252

Return type:

FLOAT

Returns:

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:

FLOAT

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:

FLOAT

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.

Parameters:

freq (INT) – Number of trading days in a year, default: 252

Return type:

FLOAT

Returns:

The volatility of the 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 name name.

Parameters:

name (str) – String of the name of the stock that is returned. Must match one of the labels in the dictionary pf.stocks.

Return type:

Stock

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 and Allocation 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 as fix-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:

Portfolio

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:

  1. building a portfolio by pulling data from quandl/yfinance,

  2. 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.