freqtrade_origin/freqtrade/commands/optimize_commands.py

184 lines
6.4 KiB
Python
Raw Normal View History

import logging
from typing import Any, Dict
from freqtrade import constants
from freqtrade.configuration import setup_utils_configuration
2021-06-08 19:20:35 +00:00
from freqtrade.enums import RunMode
from freqtrade.exceptions import OperationalException
2021-02-26 18:48:06 +00:00
from freqtrade.misc import round_coin_value
from freqtrade.resolvers import StrategyResolver
2019-06-16 18:37:43 +00:00
2020-09-28 17:39:41 +00:00
logger = logging.getLogger(__name__)
def setup_optimize_configuration(args: Dict[str, Any], method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for the Hyperopt module
:param args: Cli args from Arguments()
2021-06-25 17:13:31 +00:00
:param method: Bot running mode
:return: Configuration
"""
2019-06-16 18:37:43 +00:00
config = setup_utils_configuration(args, method)
no_unlimited_runmodes = {
RunMode.BACKTEST: 'backtesting',
RunMode.HYPEROPT: 'hyperoptimization',
}
2021-02-26 18:48:06 +00:00
if method in no_unlimited_runmodes.keys():
wallet_size = config['dry_run_wallet'] * config['tradable_balance_ratio']
# tradable_balance_ratio
2021-02-26 18:48:06 +00:00
if (config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT
and config['stake_amount'] > wallet_size):
wallet = round_coin_value(wallet_size, config['stake_currency'])
2021-02-26 18:48:06 +00:00
stake = round_coin_value(config['stake_amount'], config['stake_currency'])
raise OperationalException(
f"Starting balance ({wallet}) is smaller than stake_amount {stake}. "
f"Wallet is calculated as `dry_run_wallet * tradable_balance_ratio`."
)
return config
def start_backtesting(args: Dict[str, Any]) -> None:
"""
Start Backtesting script
:param args: Cli args from Arguments()
:return: None
"""
# Import here to avoid loading backtesting module when it's not used
from freqtrade.optimize.backtesting import Backtesting
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.BACKTEST)
logger.info('Starting freqtrade in Backtesting mode')
# Initialize backtesting object
backtesting = Backtesting(config)
backtesting.start()
2021-10-31 08:55:19 +00:00
def start_backtesting_show(args: Dict[str, Any]) -> None:
"""
Show previous backtest result
"""
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
2021-10-30 15:05:12 +00:00
from freqtrade.data.btanalysis import load_backtest_stats
2021-10-31 08:55:19 +00:00
from freqtrade.optimize.optimize_reports import show_backtest_results, show_sorted_pairlist
2021-10-30 15:05:12 +00:00
results = load_backtest_stats(config['exportfilename'])
show_backtest_results(config, results)
2021-10-30 15:05:12 +00:00
show_sorted_pairlist(config, results)
def start_hyperopt(args: Dict[str, Any]) -> None:
"""
Start hyperopt script
:param args: Cli args from Arguments()
:return: None
"""
# Import here to avoid loading hyperopt module when it's not used
2019-09-24 12:39:28 +00:00
try:
from filelock import FileLock, Timeout
2020-09-28 17:39:41 +00:00
2019-09-24 12:39:28 +00:00
from freqtrade.optimize.hyperopt import Hyperopt
except ImportError as e:
raise OperationalException(
f"{e}. Please ensure that the hyperopt dependencies are installed.") from e
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.HYPEROPT)
logger.info('Starting freqtrade in Hyperopt mode')
2019-07-21 14:07:06 +00:00
lock = FileLock(Hyperopt.get_lock_filename(config))
try:
with lock.acquire(timeout=1):
# Remove noisy log messages
logging.getLogger('hyperopt.tpe').setLevel(logging.WARNING)
logging.getLogger('filelock').setLevel(logging.WARNING)
# Initialize backtesting object
hyperopt = Hyperopt(config)
hyperopt.start()
except Timeout:
logger.info("Another running instance of freqtrade Hyperopt detected.")
logger.info("Simultaneous execution of multiple Hyperopt commands is not supported. "
2019-11-13 08:38:06 +00:00
"Hyperopt module is resource hungry. Please run your Hyperopt sequentially "
"or on separate machines.")
logger.info("Quitting now.")
# TODO: return False here in order to help freqtrade to exit
# with non-zero exit code...
# Same in Edge and Backtesting start() functions.
2019-05-25 18:05:19 +00:00
def start_edge(args: Dict[str, Any]) -> None:
2019-05-25 18:05:19 +00:00
"""
Start Edge script
:param args: Cli args from Arguments()
:return: None
"""
from freqtrade.optimize.edge_cli import EdgeCli
2020-09-28 17:39:41 +00:00
2019-05-25 18:05:19 +00:00
# Initialize configuration
config = setup_optimize_configuration(args, RunMode.EDGE)
2019-05-25 18:05:19 +00:00
logger.info('Starting freqtrade in Edge mode')
# Initialize Edge object
edge_cli = EdgeCli(config)
edge_cli.start()
def start_lookahead_analysis(args: Dict[str, Any]) -> None:
"""
Start the backtest bias tester script
:param args: Cli args from Arguments()
:return: None
"""
2023-05-20 09:28:52 +00:00
from freqtrade.optimize.lookahead_analysis import LookaheadAnalysisSubFunctions
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
if config['targeted_trade_amount'] < config['minimum_trade_amount']:
# add logic that tells the user to check the configuration
# since this combo doesn't make any sense.
2023-05-20 09:28:52 +00:00
raise OperationalException(
"targeted trade amount can't be smaller than minimum trade amount."
)
strategy_objs = StrategyResolver.search_all_objects(
config, enum_failed=False, recursive=config.get('recursive_strategy_search', False))
lookaheadAnalysis_instances = []
# unify --strategy and --strategy_list to one list
if not (strategy_list := config.get('strategy_list', [])):
strategy_list = [config['strategy']]
# check if strategies can be properly loaded, only check them if they can be.
2023-05-20 09:30:51 +00:00
for strat in strategy_list:
for strategy_obj in strategy_objs:
if strategy_obj['name'] == strat and strategy_obj not in strategy_list:
lookaheadAnalysis_instances.append(
LookaheadAnalysisSubFunctions.initialize_single_lookahead_analysis(
strategy_obj, config))
break
# report the results
if lookaheadAnalysis_instances:
LookaheadAnalysisSubFunctions.text_table_lookahead_analysis_instances(
lookaheadAnalysis_instances)
if config.get('lookahead_analysis_exportfilename') is not None:
LookaheadAnalysisSubFunctions.export_to_csv(config, lookaheadAnalysis_instances)
else:
logger.error("There were no strategies specified neither through "
"--strategy nor through "
"--strategy_list "
"or timeframe was not specified.")