Export backtesting results by default

closes #4977
This commit is contained in:
Matthias 2021-06-14 19:57:24 +02:00
parent 9c789856bd
commit cf7394d01c
7 changed files with 28 additions and 20 deletions

View File

@ -19,7 +19,7 @@ usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[--enable-protections] [--enable-protections]
[--dry-run-wallet DRY_RUN_WALLET] [--dry-run-wallet DRY_RUN_WALLET]
[--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]] [--strategy-list STRATEGY_LIST [STRATEGY_LIST ...]]
[--export EXPORT] [--export-filename PATH] [--export {none,trades}] [--export-filename PATH]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -63,8 +63,8 @@ optional arguments:
name is injected into the filename (so `backtest- name is injected into the filename (so `backtest-
data.json` becomes `backtest-data- data.json` becomes `backtest-data-
DefaultStrategy.json` DefaultStrategy.json`
--export EXPORT Export backtest results, argument are: trades. --export {none,trades}
Example: `--export=trades` Export backtest results (default: trades).
--export-filename PATH --export-filename PATH
Save backtest results to the file with this filename. Save backtest results to the file with this filename.
Requires `--export` to be set as well. Example: Requires `--export` to be set as well. Example:
@ -100,7 +100,7 @@ Strategy arguments:
Now you have good Buy and Sell strategies and some historic data, you want to test it against Now you have good Buy and Sell strategies and some historic data, you want to test it against
real data. This is what we call [backtesting](https://en.wikipedia.org/wiki/Backtesting). real data. This is what we call [backtesting](https://en.wikipedia.org/wiki/Backtesting).
Backtesting will use the crypto-currencies (pairs) from your config file and load historical candle (OHCLV) data from `user_data/data/<exchange>` by default. Backtesting will use the crypto-currencies (pairs) from your config file and load historical candle (OHLCV) data from `user_data/data/<exchange>` by default.
If no data is available for the exchange / pair / timeframe combination, backtesting will ask you to download them first using `freqtrade download-data`. If no data is available for the exchange / pair / timeframe combination, backtesting will ask you to download them first using `freqtrade download-data`.
For details on downloading, please refer to the [Data Downloading](data-download.md) section in the documentation. For details on downloading, please refer to the [Data Downloading](data-download.md) section in the documentation.
@ -110,11 +110,16 @@ All profit calculations include fees, and freqtrade will use the exchange's defa
!!! Warning "Using dynamic pairlists for backtesting" !!! Warning "Using dynamic pairlists for backtesting"
Using dynamic pairlists is possible, however it relies on the current market conditions - which will not reflect the historic status of the pairlist. Using dynamic pairlists is possible, however it relies on the current market conditions - which will not reflect the historic status of the pairlist.
Also, when using pairlists other than StaticPairlist, reproducability of backtesting-results cannot be guaranteed. Also, when using pairlists other than StaticPairlist, reproducibility of backtesting-results cannot be guaranteed.
Please read the [pairlists documentation](plugins.md#pairlists) for more information. Please read the [pairlists documentation](plugins.md#pairlists) for more information.
To achieve reproducible results, best generate a pairlist via the [`test-pairlist`](utils.md#test-pairlist) command and use that as static pairlist. To achieve reproducible results, best generate a pairlist via the [`test-pairlist`](utils.md#test-pairlist) command and use that as static pairlist.
!!! Note
By default, Freqtrade will export backtesting results to `user_data/backtest_results`.
The exported trades can be used for [further analysis](#further-backtest-result-analysis) or can be used by the [plotting sub-command](plotting.md#plot-price-and-indicators) (`freqtrade plot-dataframe`) in the scripts directory.
### Starting balance ### Starting balance
Backtesting will require a starting balance, which can be provided as `--dry-run-wallet <balance>` or `--starting-balance <balance>` command line argument, or via `dry_run_wallet` configuration setting. Backtesting will require a starting balance, which can be provided as `--dry-run-wallet <balance>` or `--starting-balance <balance>` command line argument, or via `dry_run_wallet` configuration setting.
@ -174,13 +179,13 @@ Where `SampleStrategy1` and `AwesomeStrategy` refer to class names of strategies
--- ---
Exporting trades to file Prevent exporting trades to file
```bash ```bash
freqtrade backtesting --strategy backtesting --export trades --config config.json freqtrade backtesting --strategy backtesting --export none --config config.json
``` ```
The exported trades can be used for [further analysis](#further-backtest-result-analysis), or can be used by the plotting script `plot_dataframe.py` in the scripts directory. Only use this if you're sure you'll not want to plot or analyze your results further.
--- ---

View File

@ -167,8 +167,9 @@ AVAILABLE_CLI_OPTIONS = {
), ),
"export": Arg( "export": Arg(
'--export', '--export',
help='Export backtest results, argument are: trades. ' help='Export backtest results (default: trades).',
'Example: `--export=trades`', choices=constants.EXPORT_OPTIONS,
), ),
"exportfilename": Arg( "exportfilename": Arg(
'--export-filename', '--export-filename',

View File

@ -12,6 +12,7 @@ PROCESS_THROTTLE_SECS = 5 # sec
HYPEROPT_EPOCH = 100 # epochs HYPEROPT_EPOCH = 100 # epochs
RETRY_TIMEOUT = 30 # sec RETRY_TIMEOUT = 30 # sec
TIMEOUT_UNITS = ['minutes', 'seconds'] TIMEOUT_UNITS = ['minutes', 'seconds']
EXPORT_OPTIONS = ['none', 'trades']
DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite' DEFAULT_DB_PROD_URL = 'sqlite:///tradesv3.sqlite'
DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite' DEFAULT_DB_DRYRUN_URL = 'sqlite:///tradesv3.dryrun.sqlite'
UNLIMITED_STAKE_AMOUNT = 'unlimited' UNLIMITED_STAKE_AMOUNT = 'unlimited'
@ -308,6 +309,7 @@ CONF_SCHEMA = {
'required': ['enabled', 'listen_ip_address', 'listen_port', 'username', 'password'] 'required': ['enabled', 'listen_ip_address', 'listen_port', 'username', 'password']
}, },
'db_url': {'type': 'string'}, 'db_url': {'type': 'string'},
'export': {'type': 'string', 'enum': EXPORT_OPTIONS, 'default': 'trades'},
'initial_state': {'type': 'string', 'enum': ['running', 'stopped']}, 'initial_state': {'type': 'string', 'enum': ['running', 'stopped']},
'forcebuy_enable': {'type': 'boolean'}, 'forcebuy_enable': {'type': 'boolean'},
'disable_dataframe_checks': {'type': 'boolean'}, 'disable_dataframe_checks': {'type': 'boolean'},

View File

@ -520,7 +520,7 @@ class Backtesting:
stats = generate_backtest_stats(data, self.all_results, stats = generate_backtest_stats(data, self.all_results,
min_date=min_date, max_date=max_date) min_date=min_date, max_date=max_date)
if self.config.get('export', False): if self.config.get('export', 'none') == 'trades':
store_backtest_stats(self.config['exportfilename'], stats) store_backtest_stats(self.config['exportfilename'], stats)
# Show backtest results # Show backtest results

View File

@ -326,6 +326,7 @@ def get_default_conf(testdatadir):
"strategy_path": str(Path(__file__).parent / "strategy" / "strats"), "strategy_path": str(Path(__file__).parent / "strategy" / "strats"),
"strategy": "DefaultStrategy", "strategy": "DefaultStrategy",
"internals": {}, "internals": {},
"export": "none",
} }
return configuration return configuration

View File

@ -155,6 +155,7 @@ def test_setup_optimize_configuration_without_arguments(mocker, default_conf, ca
'backtesting', 'backtesting',
'--config', 'config.json', '--config', 'config.json',
'--strategy', 'DefaultStrategy', '--strategy', 'DefaultStrategy',
'--export', 'none'
] ]
config = setup_optimize_configuration(get_args(args), RunMode.BACKTEST) config = setup_optimize_configuration(get_args(args), RunMode.BACKTEST)
@ -172,7 +173,8 @@ def test_setup_optimize_configuration_without_arguments(mocker, default_conf, ca
assert not log_has('Parameter --enable-position-stacking detected ...', caplog) assert not log_has('Parameter --enable-position-stacking detected ...', caplog)
assert 'timerange' not in config assert 'timerange' not in config
assert 'export' not in config assert 'export' in config
assert config['export'] == 'none'
assert 'runmode' in config assert 'runmode' in config
assert config['runmode'] == RunMode.BACKTEST assert config['runmode'] == RunMode.BACKTEST
@ -193,7 +195,6 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
'--enable-position-stacking', '--enable-position-stacking',
'--disable-max-market-positions', '--disable-max-market-positions',
'--timerange', ':100', '--timerange', ':100',
'--export', '/bar/foo',
'--export-filename', 'foo_bar.json', '--export-filename', 'foo_bar.json',
'--fee', '0', '--fee', '0',
] ]
@ -223,7 +224,6 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog) assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog)
assert 'export' in config assert 'export' in config
assert log_has('Parameter --export detected: {} ...'.format(config['export']), caplog)
assert 'exportfilename' in config assert 'exportfilename' in config
assert isinstance(config['exportfilename'], Path) assert isinstance(config['exportfilename'], Path)
assert log_has('Storing backtest results to {} ...'.format(config['exportfilename']), caplog) assert log_has('Storing backtest results to {} ...'.format(config['exportfilename']), caplog)
@ -395,7 +395,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
default_conf['timeframe'] = "1m" default_conf['timeframe'] = "1m"
default_conf['datadir'] = testdatadir default_conf['datadir'] = testdatadir
default_conf['export'] = None default_conf['export'] = 'none'
default_conf['timerange'] = '20180101-20180102' default_conf['timerange'] = '20180101-20180102'
backtesting = Backtesting(default_conf) backtesting = Backtesting(default_conf)
@ -416,7 +416,7 @@ def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) ->
default_conf['timeframe'] = "1m" default_conf['timeframe'] = "1m"
default_conf['datadir'] = testdatadir default_conf['datadir'] = testdatadir
default_conf['export'] = None default_conf['export'] = 'none'
default_conf['timerange'] = '20180101-20180102' default_conf['timerange'] = '20180101-20180102'
with pytest.raises(OperationalException, match='No pair in whitelist.'): with pytest.raises(OperationalException, match='No pair in whitelist.'):
@ -440,7 +440,7 @@ def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, ti
default_conf['ticker_interval'] = "1m" default_conf['ticker_interval'] = "1m"
default_conf['datadir'] = testdatadir default_conf['datadir'] = testdatadir
default_conf['export'] = None default_conf['export'] = 'none'
# Use stoploss from strategy # Use stoploss from strategy
del default_conf['stoploss'] del default_conf['stoploss']
default_conf['timerange'] = '20180101-20180102' default_conf['timerange'] = '20180101-20180102'

View File

@ -425,7 +425,6 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
assert not log_has('Parameter --enable-position-stacking detected ...', caplog) assert not log_has('Parameter --enable-position-stacking detected ...', caplog)
assert 'timerange' not in config assert 'timerange' not in config
assert 'export' not in config
def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None: def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> None:
@ -448,7 +447,7 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
'--enable-position-stacking', '--enable-position-stacking',
'--disable-max-market-positions', '--disable-max-market-positions',
'--timerange', ':100', '--timerange', ':100',
'--export', '/bar/foo', '--export', 'trades',
'--stake-amount', 'unlimited' '--stake-amount', 'unlimited'
] ]
@ -496,7 +495,7 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
'backtesting', 'backtesting',
'--config', 'config.json', '--config', 'config.json',
'--ticker-interval', '1m', '--ticker-interval', '1m',
'--export', '/bar/foo', '--export', 'trades',
'--strategy-list', '--strategy-list',
'DefaultStrategy', 'DefaultStrategy',
'TestStrategy' 'TestStrategy'