Improve handling of backtesting params

This commit is contained in:
Matthias 2021-02-26 19:48:06 +01:00
parent 86f9409fd2
commit 98f3142b30
6 changed files with 39 additions and 16 deletions

View File

@ -111,7 +111,7 @@ AVAILABLE_CLI_OPTIONS = {
action='store_true', action='store_true',
), ),
"dry_run_wallet": Arg( "dry_run_wallet": Arg(
'--dry-run-wallet', '--dry-run-wallet', '--starting-balance',
help='Starting balance, used for backtesting / hyperopt and dry-runs.', help='Starting balance, used for backtesting / hyperopt and dry-runs.',
type=float, type=float,
), ),

View File

@ -4,6 +4,7 @@ from typing import Any, Dict
from freqtrade import constants from freqtrade import constants
from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration import setup_utils_configuration
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import round_coin_value
from freqtrade.state import RunMode from freqtrade.state import RunMode
@ -22,9 +23,13 @@ def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[
RunMode.BACKTEST: 'backtesting', RunMode.BACKTEST: 'backtesting',
RunMode.HYPEROPT: 'hyperoptimization', RunMode.HYPEROPT: 'hyperoptimization',
} }
if (method in no_unlimited_runmodes.keys() and if method in no_unlimited_runmodes.keys():
config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT and if (config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT
config['max_open_trades'] != float('inf')): and config['stake_amount'] > config['dry_run_wallet']):
wallet = round_coin_value(config['dry_run_wallet'], config['stake_currency'])
stake = round_coin_value(config['stake_amount'], config['stake_currency'])
raise OperationalException(f"Starting balance ({wallet}) "
f"is smaller than stake_amount {stake}.")
pass pass
# config['dry_run_wallet'] = config['stake_amount'] * \ # config['dry_run_wallet'] = config['stake_amount'] * \
# config['max_open_trades'] * (2 - config['tradable_balance_ratio']) # config['max_open_trades'] * (2 - config['tradable_balance_ratio'])

View File

@ -214,9 +214,6 @@ class Configuration:
self._args_to_config( self._args_to_config(
config, argname='enable_protections', config, argname='enable_protections',
logstring='Parameter --enable-protections detected, enabling Protections. ...') logstring='Parameter --enable-protections detected, enabling Protections. ...')
# Setting max_open_trades to infinite if -1
if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf')
if 'use_max_market_positions' in self.args and not self.args["use_max_market_positions"]: if 'use_max_market_positions' in self.args and not self.args["use_max_market_positions"]:
config.update({'use_max_market_positions': False}) config.update({'use_max_market_positions': False})
@ -228,6 +225,9 @@ class Configuration:
'overriding max_open_trades to: %s ...', config.get('max_open_trades')) 'overriding max_open_trades to: %s ...', config.get('max_open_trades'))
elif config['runmode'] in NON_UTIL_MODES: elif config['runmode'] in NON_UTIL_MODES:
logger.info('Using max_open_trades: %s ...', config.get('max_open_trades')) logger.info('Using max_open_trades: %s ...', config.get('max_open_trades'))
# Setting max_open_trades to infinite if -1
if config.get('max_open_trades') == -1:
config['max_open_trades'] = float('inf')
if self.args.get('stake_amount', None): if self.args.get('stake_amount', None):
# Convert explicitly to float to support CLI argument for both unlimited and value # Convert explicitly to float to support CLI argument for both unlimited and value

View File

@ -128,7 +128,7 @@ class Backtesting:
PairLocks.use_db = True PairLocks.use_db = True
Trade.use_db = True Trade.use_db = True
def _set_strategy(self, strategy): def _set_strategy(self, strategy: IStrategy):
""" """
Load strategy into backtesting Load strategy into backtesting
""" """

View File

@ -9,7 +9,6 @@ import pandas as pd
import pytest import pytest
from arrow import Arrow from arrow import Arrow
from freqtrade import constants
from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_backtesting from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_backtesting
from freqtrade.configuration import TimeRange from freqtrade.configuration import TimeRange
from freqtrade.data import history from freqtrade.data import history
@ -232,8 +231,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
assert log_has('Parameter --fee detected, setting fee to: {} ...'.format(config['fee']), caplog) assert log_has('Parameter --fee detected, setting fee to: {} ...'.format(config['fee']), caplog)
def test_setup_optimize_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None: def test_setup_optimize_configuration_stake_amount(mocker, default_conf, caplog) -> None:
default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
patched_configuration_load_config_file(mocker, default_conf) patched_configuration_load_config_file(mocker, default_conf)
@ -241,12 +239,23 @@ def test_setup_optimize_configuration_unlimited_stake_amount(mocker, default_con
'backtesting', 'backtesting',
'--config', 'config.json', '--config', 'config.json',
'--strategy', 'DefaultStrategy', '--strategy', 'DefaultStrategy',
'--stake-amount', '1',
'--starting-balance', '2'
] ]
# TODO: does this test still make sense?
conf = setup_optimize_configuration(get_args(args), RunMode.BACKTEST) conf = setup_optimize_configuration(get_args(args), RunMode.BACKTEST)
assert isinstance(conf, dict) assert isinstance(conf, dict)
args = [
'backtesting',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--stake-amount', '1',
'--starting-balance', '0.5'
]
with pytest.raises(OperationalException, match=r"Starting balance .* smaller .*"):
setup_optimize_configuration(get_args(args), RunMode.BACKTEST)
def test_start(mocker, fee, default_conf, caplog) -> None: def test_start(mocker, fee, default_conf, caplog) -> None:
start_mock = MagicMock() start_mock = MagicMock()

View File

@ -12,7 +12,6 @@ import pytest
from arrow import Arrow from arrow import Arrow
from filelock import Timeout from filelock import Timeout
from freqtrade import constants
from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_hyperopt from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_hyperopt
from freqtrade.data.history import load_data from freqtrade.data.history import load_data
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
@ -130,8 +129,7 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo
assert log_has('Parameter --print-all detected ...', caplog) assert log_has('Parameter --print-all detected ...', caplog)
def test_setup_hyperopt_configuration_unlimited_stake_amount(mocker, default_conf) -> None: def test_setup_hyperopt_configuration_stake_amount(mocker, default_conf) -> None:
default_conf['stake_amount'] = constants.UNLIMITED_STAKE_AMOUNT
patched_configuration_load_config_file(mocker, default_conf) patched_configuration_load_config_file(mocker, default_conf)
@ -139,11 +137,22 @@ def test_setup_hyperopt_configuration_unlimited_stake_amount(mocker, default_con
'hyperopt', 'hyperopt',
'--config', 'config.json', '--config', 'config.json',
'--hyperopt', 'DefaultHyperOpt', '--hyperopt', 'DefaultHyperOpt',
'--stake-amount', '1',
'--starting-balance', '2'
] ]
# TODO: does this test still make sense?
conf = setup_optimize_configuration(get_args(args), RunMode.HYPEROPT) conf = setup_optimize_configuration(get_args(args), RunMode.HYPEROPT)
assert isinstance(conf, dict) assert isinstance(conf, dict)
args = [
'hyperopt',
'--config', 'config.json',
'--strategy', 'DefaultStrategy',
'--stake-amount', '1',
'--starting-balance', '0.5'
]
with pytest.raises(OperationalException, match=r"Starting balance .* smaller .*"):
setup_optimize_configuration(get_args(args), RunMode.HYPEROPT)
def test_hyperoptresolver(mocker, default_conf, caplog) -> None: def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
patched_configuration_load_config_file(mocker, default_conf) patched_configuration_load_config_file(mocker, default_conf)