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, reject_trades_below=None, max_fraction_liquidity=None, 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 defaultscvxportfolio.DownloadedMarketDataandcvxportfolio.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, acvxportfolio.DownloadedMarketDatawill 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.UserProvidedMarketDatawill be initialized. If universe is specified it is ignored. You can also include cash returns as its last column, and setcash_keybelow 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.SymbolDataclass (not instance)) – The data source used, if providing a universe (forcvxportfolio.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), orcash, which sets the cash returns to 0. DefaultUSDOLLAR.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
nanbefore it is included in a back-test. Default one year.market_data (
cvxportfolio.data.MarketDatainstance or None) – An instance of acvxportfolio.data.MarketDataderived 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_datain your home folder.costs (list of
cvxportfolio.costs.SimulatorCostclasses 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.
reject_trades_below (float) – Minimum absolute size, in units of cash (e.g., USDOLLAR) of a trade. Trades (buys or sell) requested by the policy which are smaller than this threshold are ignored. Default None, equivalent to 0.
max_fraction_liquidity (float or None) – Optionally cap trades (in absolute value) up to a certain fraction of the realized volume in a given period for each asset, for example 0.05, meaning 5%. Requires volumes to be provided by the
cvxportfolio.data.MarketDataserver (otherwise it’s inactive). If used, this is applied before simulated costs are computed. Default None, which disables this filter.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
hargument.- 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
hit is assumed the initial portfolio is all cash; ifhis specified this is ignored. Default value one million.h (pandas.Series or None) – Initial portfolio
hexpressed in cash units. IfNonean initial portfolio ofinitial_valuein 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
hargument, or a list of those.- Parameters:
policies (list) – List of
cvxportfolio.policies.Policytrading 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
hit is assumed the initial portfolio is all cash; ifhis 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_valueis ignored, otherwise the same portfolio ofinitial_valueall 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.BacktestResultwhich 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
hit is assumed the initial portfolio is all cash; ifhis specified this is ignored. Default one million.h (pandas.Series or None) – Initial portfolio
hexpressed in cash units. IfNonean initial portfolio ofinitial_valuein cash is used.objective (str) – Attribute of
cvxportfolio.BacktestResultthat 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, max_fraction_liquidity=0.05, reject_trades_below=None, cash_key='USDOLLAR', base_location=PosixPath('/home/docs/cvxportfolio_data'), trading_frequency=None, **kwargs)View on GitHub#
This class simplifies
MarketSimulatorfor the stock market.It has simple and realistic (although conservative) default costs and other parameters.
- 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), orcash, which sets the cash returns to 0. DefaultUSDOLLAR.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_datain your home folder.costs (list of
cvxportfolio.costs.SimulatorCostclasses or instances) – List of costs that are applied at each time in a back-test. By default we addcvxportfolio.StocksTransactionCostandcvxportfolio.StocksHoldingCost.round_trades (bool) – Round trades to integer number of shares. By default, True.
max_fraction_liquidity (float or None) – Cut trades to a maximum fraction of available market liquidity. Default 5%.
reject_trades_below (float) – Minimum absolute size, in units of cash (e.g., USDOLLAR) of a trade. Trades (buys or sell) requested by the policy which are smaller than this threshold are ignored. Default None, equivalent to 0.
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
hargument.- 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
hit is assumed the initial portfolio is all cash; ifhis specified this is ignored. Default value one million.h (pandas.Series or None) – Initial portfolio
hexpressed in cash units. IfNonean initial portfolio ofinitial_valuein 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
hargument, or a list of those.- Parameters:
policies (list) – List of
cvxportfolio.policies.Policytrading 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
hit is assumed the initial portfolio is all cash; ifhis 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_valueis ignored, otherwise the same portfolio ofinitial_valueall 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.BacktestResultwhich 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
hit is assumed the initial portfolio is all cash; ifhis specified this is ignored. Default one million.h (pandas.Series or None) – Initial portfolio
hexpressed in cash units. IfNonean initial portfolio ofinitial_valuein cash is used.objective (str) – Attribute of
cvxportfolio.BacktestResultthat 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