Improve handling of backtesting params
This commit is contained in:
parent
86f9409fd2
commit
98f3142b30
@ -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,
|
||||||
),
|
),
|
||||||
|
@ -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'])
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
"""
|
"""
|
||||||
|
@ -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()
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user