Simulator

This module implements cvxportfolio.MarketSimulator and derived classes.

These objects model the trading activity on a financial market. They simulate as accurately as possible what would have been the realized performance of a trading policy if it had been run in the market in the past. In financial jargon this is called back-testing.

class cvxportfolio.MarketSimulator(universe=(), returns=None, volumes=None, prices=None, market_data=None, costs=(), round_trades=False, datasource='YahooFinance', cash_key='USDOLLAR', base_location=PosixPath('/home/docs/cvxportfolio_data'), min_history=Timedelta('365 days 05:45:36'), trading_frequency=None, backtest_result_cls=<class 'cvxportfolio.result.BacktestResult'>)View on GitHub

This class is a generic financial market simulator.

It can either be initialized with an instance of a class derived from cvxportfolio.data.MarketData, like the two defaults cvxportfolio.DownloadedMarketData and cvxportfolio.UserProvidedMarketData, or with a selection of the arguments to the latter two.

Parameters:
  • universe (list) – List of names as understood by the data source used, e.g., ['AAPL', 'GOOG'] if using the default Yahoo Finance data source. If provided, a cvxportfolio.DownloadedMarketData will be initialized.

  • returns (pandas.DataFrame) – Historical open-to-open returns. The return at time \(t\) is \(r_t = p_{t+1}/p_t -1\) where \(p_t\) is the (open) price at time \(t\). Must have datetime index. If provided, a cvxportfolio.UserProvidedMarketData will be initialized. If universe is specified it is ignored. You can also include cash returns as its last column, and set cash_key below to the last column’s name.

  • volumes (pandas.DataFrame or None) – Historical market volumes, expressed in units of value (e.g., US dollars). If universe is specified it is ignored.

  • prices (pandas.DataFrame or None) – Historical open prices (e.g., used for rounding trades in the cvxportfolio.MarketSimulator). If universe is specified it is ignored.

  • datasource (str or cvxportfolio.data.SymbolData class (not instance)) – The data source used, if providing a universe (for cvxportfolio.DownloadedMarketData).

  • cash_key (str) – Name of the cash account. Its returns are the risk-free rate. If it is the name of the last column of the provided returns, that will be used. Otherwise, the last column of the returns’ will be added by downloading the risk-free returns. In that case you should make sure your provided dataframes have a time-zone aware datetime index. If not in the original dataframe, choice of USDOLLAR, EURO,``JPYEN``, GBPOUND (Cvxportfolio downloads the historical central bank rates from FRED), or cash, which sets the cash returns to 0. Default USDOLLAR.

  • trading_frequency (str or None) – Instead of using frequency implied by the index of the returns, down-sample all dataframes. We implement 'weekly', 'monthly', 'quarterly' and 'annual'. By default (None) don’t down-sample.

  • min_history (pandas.Timedelta) – Minimum amount of time for which an asset must have returns that are not nan before it is included in a back-test. Default one year.

  • market_data (cvxportfolio.data.MarketData instance or None) – An instance of a cvxportfolio.data.MarketData derived class. If provided, all previous arguments are ignored.

  • base_location (pathlib.Path) – The location of the storage. By default it’s a directory named cvxportfolio_data in your home folder.

  • costs (list of cvxportfolio.costs.SimulatorCost classes or instances) – List of costs that are applied at each time in a back-test.

  • round_trades (bool) – If market prices are available, round trades to integer number of shares.

  • backtest_result_cls (class) – Back-test result class (not instance) returned by the simulator. Use this if you wish to use a custom subclass of the default, cvxportfolio.result.BacktestResult.

backtest(policy, start_time=None, end_time=None, initial_value=1000000.0, h=None)View on GitHub

Back-test a trading policy.

The default initial portfolio is all cash, or you can pass any portfolio with the h argument.

Parameters:
  • policy (cvxportfolio.policies.Policy) – Trading policy, see the Trading policies documentation page.

  • start_time (str or pandas.Timestamp) – Start time of the back-test; if market is closed, the first trading day after it is selected.

  • end_time (str or pandas.Timestamp or None) – End time of the back-test, if market is closed the last trading day before it is selected.

  • initial_value (float) – Initial value in dollar of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default value one million.

  • h (pandas.Series or None) – Initial portfolio h expressed in cash units. If None an initial portfolio of initial_value in cash is used.

Returns:

Back-test result with all relevant data and metrics, logic to generate plots, ….

Return type:

cvxportfolio.BacktestResult

run_backtest()View on GitHub

Alias of backtest(), as it was defined originally in section 6.1 of the paper.

backtest_many(policies, start_time=None, end_time=None, initial_value=1000000.0, h=None, parallel=True)View on GitHub

Back-test many trading policies.

The default initial portfolio is all cash, or you can pass any portfolio with the h argument, or a list of those.

Parameters:
  • policies (list) – List of cvxportfolio.policies.Policy trading policies, see the Trading policies documentation page.

  • start_time (str or pandas.Timestamp) – Start time of the backtests. If market is closed the first trading day after it is selected. Currently it is not possible to specify different start times for different policies, so the same is used for all.

  • end_time (str or pandas.Timestamp or None) – End time of the backtests. If market is closed the last trading day before it is selected. Currently it is not possible to specify different end times for different policies, so the same is used for all.

  • initial_value (float) – Initial value in dollar of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default value one million.

  • h (list of pandas.Series or None) – Initial portfolio h expressed in dollar positions, or list of those. If passing a list it must have the same lenght as the policies. If this argument is specified, initial_value is ignored, otherwise the same portfolio of initial_value all in cash is used as starting point for all backtests.

  • parallel (bool) – Whether to run in parallel. If running in parallel you should must be careful at how you use this method. It is good practice to define the market simulator and execute this inside a if __name__ == '__main__:' clause, if in a script.

Raises:
  • SyntaxError – If the lenghts of objects passed don’t match, ….

  • ValueError – If there are no trading days between the provided times.

Returns:

List of cvxportfolio.BacktestResult which have all relevant backtest data and logic to compute metrics, generate plots, ….

Return type:

list

run_multiple_backtest()View on GitHub

Alias of backtest_many(), as it was defined originally in section 6.1 of the paper.

optimize_hyperparameters(policy, start_time=None, end_time=None, initial_value=1000000.0, h=None, objective='sharpe_ratio', parallel=True)View on GitHub

Optimize hyperparameters to maximize back-test objective.

Parameters:
  • policy (cvx.BaseTradingPolicy) – Trading policy with symbolic hyperparameters.

  • start_time (str or pandas.Timestamp) – Start time of the back-test on which we optimize; if market is closed, the first trading day after it is selected.

  • end_time (str or datetime or None) – End time of the back-test on which we optimize; if market is closed, the last trading day before it is selected.

  • initial_value (float) – Initial value in cash units of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default one million.

  • h (pandas.Series or None) – Initial portfolio h expressed in cash units. If None an initial portfolio of initial_value in cash is used.

  • objective (str) – Attribute of cvxportfolio.BacktestResult that is maximized. Default 'sharpe_ratio'.

  • parallel (bool) – Whether to run in parallel. If running in parallel you should must be careful at how you use this method. It is good practice to define the market simulator and execute this inside a if __name__ == '__main__:' clause, if in a script.

Returns:

The policy whose hyper-parameters now have optimal values. (The same object that was passed by the user.)

Return type:

cvxportfolio.Policy

class cvxportfolio.StockMarketSimulator(universe=(), costs=(<class 'cvxportfolio.costs.StocksTransactionCost'>, <class 'cvxportfolio.costs.StocksHoldingCost'>), round_trades=True, cash_key='USDOLLAR', base_location=PosixPath('/home/docs/cvxportfolio_data'), trading_frequency=None, **kwargs)View on GitHub

This class implements a simulator of the stock market. It simplifies the interface of MarketSimulator and has (realistic) default costs.

Parameters:
  • universe (list) – List of Yahoo Finance stock names.

  • cash_key (str) – Name of the cash account. Its returns are the risk-free rate. Choice of USDOLLAR, EURO,``JPYEN``, GBPOUND (Cvxportfolio downloads the historical central bank rates from FRED), or cash, which sets the cash returns to 0. Default USDOLLAR.

  • trading_frequency (str or None) – Instead of using frequency implied by the index of the returns, down-sample all dataframes. We implement 'weekly', 'monthly', 'quarterly' and 'annual'. By default (None) don’t down-sample.

  • base_location (pathlib.Path) – The location of the storage. By default it’s a directory named cvxportfolio_data in your home folder.

  • costs (list of cvxportfolio.costs.SimulatorCost classes or instances) – List of costs that are applied at each time in a back-test. By default we add cvxportfolio.StocksTransactionCost and cvxportfolio.StocksHoldingCost.

  • round_trades (bool) – Round trades to integer number of shares. By default, True.

  • kwargs (dict) – You can add any other argument to pass to MarketSimulator’s initializer.

backtest(policy, start_time=None, end_time=None, initial_value=1000000.0, h=None)View on GitHub

Back-test a trading policy.

The default initial portfolio is all cash, or you can pass any portfolio with the h argument.

Parameters:
  • policy (cvxportfolio.policies.Policy) – Trading policy, see the Trading policies documentation page.

  • start_time (str or pandas.Timestamp) – Start time of the back-test; if market is closed, the first trading day after it is selected.

  • end_time (str or pandas.Timestamp or None) – End time of the back-test, if market is closed the last trading day before it is selected.

  • initial_value (float) – Initial value in dollar of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default value one million.

  • h (pandas.Series or None) – Initial portfolio h expressed in cash units. If None an initial portfolio of initial_value in cash is used.

Returns:

Back-test result with all relevant data and metrics, logic to generate plots, ….

Return type:

cvxportfolio.BacktestResult

run_backtest()View on GitHub

Alias of backtest(), as it was defined originally in section 6.1 of the paper.

backtest_many(policies, start_time=None, end_time=None, initial_value=1000000.0, h=None, parallel=True)View on GitHub

Back-test many trading policies.

The default initial portfolio is all cash, or you can pass any portfolio with the h argument, or a list of those.

Parameters:
  • policies (list) – List of cvxportfolio.policies.Policy trading policies, see the Trading policies documentation page.

  • start_time (str or pandas.Timestamp) – Start time of the backtests. If market is closed the first trading day after it is selected. Currently it is not possible to specify different start times for different policies, so the same is used for all.

  • end_time (str or pandas.Timestamp or None) – End time of the backtests. If market is closed the last trading day before it is selected. Currently it is not possible to specify different end times for different policies, so the same is used for all.

  • initial_value (float) – Initial value in dollar of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default value one million.

  • h (list of pandas.Series or None) – Initial portfolio h expressed in dollar positions, or list of those. If passing a list it must have the same lenght as the policies. If this argument is specified, initial_value is ignored, otherwise the same portfolio of initial_value all in cash is used as starting point for all backtests.

  • parallel (bool) – Whether to run in parallel. If running in parallel you should must be careful at how you use this method. It is good practice to define the market simulator and execute this inside a if __name__ == '__main__:' clause, if in a script.

Raises:
  • SyntaxError – If the lenghts of objects passed don’t match, ….

  • ValueError – If there are no trading days between the provided times.

Returns:

List of cvxportfolio.BacktestResult which have all relevant backtest data and logic to compute metrics, generate plots, ….

Return type:

list

run_multiple_backtest()View on GitHub

Alias of backtest_many(), as it was defined originally in section 6.1 of the paper.

optimize_hyperparameters(policy, start_time=None, end_time=None, initial_value=1000000.0, h=None, objective='sharpe_ratio', parallel=True)View on GitHub

Optimize hyperparameters to maximize back-test objective.

Parameters:
  • policy (cvx.BaseTradingPolicy) – Trading policy with symbolic hyperparameters.

  • start_time (str or pandas.Timestamp) – Start time of the back-test on which we optimize; if market is closed, the first trading day after it is selected.

  • end_time (str or datetime or None) – End time of the back-test on which we optimize; if market is closed, the last trading day before it is selected.

  • initial_value (float) – Initial value in cash units of the portfolio, if not specifying h it is assumed the initial portfolio is all cash; if h is specified this is ignored. Default one million.

  • h (pandas.Series or None) – Initial portfolio h expressed in cash units. If None an initial portfolio of initial_value in cash is used.

  • objective (str) – Attribute of cvxportfolio.BacktestResult that is maximized. Default 'sharpe_ratio'.

  • parallel (bool) – Whether to run in parallel. If running in parallel you should must be careful at how you use this method. It is good practice to define the market simulator and execute this inside a if __name__ == '__main__:' clause, if in a script.

Returns:

The policy whose hyper-parameters now have optimal values. (The same object that was passed by the user.)

Return type:

cvxportfolio.Policy