Merge pull request #2839 from hroff-1902/list-hyperopts-2

Add list-hyperopts subcommand
This commit is contained in:
Matthias 2020-02-06 07:06:36 +01:00 committed by GitHub
commit 97e48080e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 131 additions and 22 deletions

View File

@ -108,9 +108,9 @@ With custom user directory
freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt freqtrade new-hyperopt --userdir ~/.freqtrade/ --hyperopt AwesomeHyperopt
``` ```
## List Strategies ## List Strategies and List Hyperopts
Use the `list-strategies` subcommand to see all strategies in one particular directory. Use the `list-strategies` subcommand to see all strategies in one particular directory and the `list-hyperopts` subcommand to list custom Hyperopts.
``` ```
freqtrade list-strategies --help freqtrade list-strategies --help
@ -133,22 +133,63 @@ Common arguments:
--userdir PATH, --user-data-dir PATH --userdir PATH, --user-data-dir PATH
Path to userdata directory. Path to userdata directory.
``` ```
```
freqtrade list-hyperopts --help
usage: freqtrade list-hyperopts [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH]
[--hyperopt-path PATH] [-1]
optional arguments:
-h, --help show this help message and exit
--hyperopt-path PATH Specify additional lookup path for Hyperopt and
Hyperopt Loss functions.
-1, --one-column Print output in one column.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
--logfile FILE Log to the file specified. Special values are:
'syslog', 'journald'. See the documentation for more
details.
-V, --version show program's version number and exit
-c PATH, --config PATH
Specify configuration file (default: `config.json`).
Multiple --config options may be used. Can be set to
`-` to read config from stdin.
-d PATH, --datadir PATH
Path to directory with historical backtesting data.
--userdir PATH, --user-data-dir PATH
Path to userdata directory.
```
!!! Warning !!! Warning
Using this command will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed. Using these commands will try to load all python files from a directory. This can be a security risk if untrusted files reside in this directory, since all module-level code is executed.
Example: search default strategy directory within userdir Example: Search default strategies and hyperopts directories (within the default userdir).
``` bash
freqtrade list-strategies
freqtrade list-hyperopts
```
Example: Search strategies and hyperopts directory within the userdir.
``` bash ``` bash
freqtrade list-strategies --userdir ~/.freqtrade/ freqtrade list-strategies --userdir ~/.freqtrade/
freqtrade list-hyperopts --userdir ~/.freqtrade/
``` ```
Example: search dedicated strategy path Example: Search dedicated strategy path.
``` bash ``` bash
freqtrade list-strategies --strategy-path ~/.freqtrade/strategies/ freqtrade list-strategies --strategy-path ~/.freqtrade/strategies/
``` ```
Example: Search dedicated hyperopt path.
``` bash
freqtrade list-hyperopt --hyperopt-path ~/.freqtrade/hyperopts/
```
## List Exchanges ## List Exchanges
Use the `list-exchanges` subcommand to see the exchanges available for the bot. Use the `list-exchanges` subcommand to see the exchanges available for the bot.

View File

@ -14,6 +14,7 @@ from freqtrade.commands.deploy_commands import (start_create_userdir,
from freqtrade.commands.hyperopt_commands import (start_hyperopt_list, from freqtrade.commands.hyperopt_commands import (start_hyperopt_list,
start_hyperopt_show) start_hyperopt_show)
from freqtrade.commands.list_commands import (start_list_exchanges, from freqtrade.commands.list_commands import (start_list_exchanges,
start_list_hyperopts,
start_list_markets, start_list_markets,
start_list_strategies, start_list_strategies,
start_list_timeframes) start_list_timeframes)

View File

@ -32,6 +32,8 @@ ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column"] ARGS_LIST_STRATEGIES = ["strategy_path", "print_one_column"]
ARGS_LIST_HYPEROPTS = ["hyperopt_path", "print_one_column"]
ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"] ARGS_LIST_EXCHANGES = ["print_one_column", "list_exchanges_all"]
ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"] ARGS_LIST_TIMEFRAMES = ["exchange", "print_one_column"]
@ -64,8 +66,8 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop
"print_json", "hyperopt_show_no_header"] "print_json", "hyperopt_show_no_header"]
NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs", NO_CONF_REQURIED = ["download-data", "list-timeframes", "list-markets", "list-pairs",
"list-strategies", "hyperopt-list", "hyperopt-show", "plot-dataframe", "list-strategies", "list-hyperopts", "hyperopt-list", "hyperopt-show",
"plot-profit"] "plot-dataframe", "plot-profit"]
NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"]
@ -132,9 +134,10 @@ class Arguments:
from freqtrade.commands import (start_create_userdir, start_download_data, from freqtrade.commands import (start_create_userdir, start_download_data,
start_hyperopt_list, start_hyperopt_show, start_hyperopt_list, start_hyperopt_show,
start_list_exchanges, start_list_markets, start_list_exchanges, start_list_hyperopts,
start_list_strategies, start_new_hyperopt, start_list_markets, start_list_strategies,
start_new_strategy, start_list_timeframes, start_list_timeframes,
start_new_hyperopt, start_new_strategy,
start_plot_dataframe, start_plot_profit, start_plot_dataframe, start_plot_profit,
start_backtesting, start_hyperopt, start_edge, start_backtesting, start_hyperopt, start_edge,
start_test_pairlist, start_trading) start_test_pairlist, start_trading)
@ -198,6 +201,15 @@ class Arguments:
list_strategies_cmd.set_defaults(func=start_list_strategies) list_strategies_cmd.set_defaults(func=start_list_strategies)
self._build_args(optionlist=ARGS_LIST_STRATEGIES, parser=list_strategies_cmd) self._build_args(optionlist=ARGS_LIST_STRATEGIES, parser=list_strategies_cmd)
# Add list-hyperopts subcommand
list_hyperopts_cmd = subparsers.add_parser(
'list-hyperopts',
help='Print available hyperopt classes.',
parents=[_common_parser],
)
list_hyperopts_cmd.set_defaults(func=start_list_hyperopts)
self._build_args(optionlist=ARGS_LIST_HYPEROPTS, parser=list_hyperopts_cmd)
# Add list-exchanges subcommand # Add list-exchanges subcommand
list_exchanges_cmd = subparsers.add_parser( list_exchanges_cmd = subparsers.add_parser(
'list-exchanges', 'list-exchanges',

View File

@ -6,7 +6,7 @@ from typing import Any, Dict
from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration import setup_utils_configuration
from freqtrade.configuration.directory_operations import (copy_sample_files, from freqtrade.configuration.directory_operations import (copy_sample_files,
create_userdata_dir) create_userdata_dir)
from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGY from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.misc import render_template from freqtrade.misc import render_template
from freqtrade.state import RunMode from freqtrade.state import RunMode
@ -57,7 +57,7 @@ def start_new_strategy(args: Dict[str, Any]) -> None:
if args["strategy"] == "DefaultStrategy": if args["strategy"] == "DefaultStrategy":
raise OperationalException("DefaultStrategy is not allowed as name.") raise OperationalException("DefaultStrategy is not allowed as name.")
new_path = config['user_data_dir'] / USERPATH_STRATEGY / (args["strategy"] + ".py") new_path = config['user_data_dir'] / USERPATH_STRATEGIES / (args["strategy"] + ".py")
if new_path.exists(): if new_path.exists():
raise OperationalException(f"`{new_path}` already exists. " raise OperationalException(f"`{new_path}` already exists. "

View File

@ -9,7 +9,7 @@ import rapidjson
from tabulate import tabulate from tabulate import tabulate
from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration import setup_utils_configuration
from freqtrade.constants import USERPATH_STRATEGY from freqtrade.constants import USERPATH_HYPEROPTS, USERPATH_STRATEGIES
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.exchange import (available_exchanges, ccxt_exchanges, from freqtrade.exchange import (available_exchanges, ccxt_exchanges,
market_is_active, symbol_is_pair) market_is_active, symbol_is_pair)
@ -38,11 +38,11 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
def start_list_strategies(args: Dict[str, Any]) -> None: def start_list_strategies(args: Dict[str, Any]) -> None:
""" """
Print Strategies available in a directory Print files with Strategy custom classes available in the directory
""" """
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGY)) directory = Path(config.get('strategy_path', config['user_data_dir'] / USERPATH_STRATEGIES))
strategies = StrategyResolver.search_all_objects(directory) strategies = StrategyResolver.search_all_objects(directory)
# Sort alphabetically # Sort alphabetically
strategies = sorted(strategies, key=lambda x: x['name']) strategies = sorted(strategies, key=lambda x: x['name'])
@ -54,6 +54,26 @@ def start_list_strategies(args: Dict[str, Any]) -> None:
print(tabulate(strats_to_print, headers='keys', tablefmt='pipe')) print(tabulate(strats_to_print, headers='keys', tablefmt='pipe'))
def start_list_hyperopts(args: Dict[str, Any]) -> None:
"""
Print files with HyperOpt custom classes available in the directory
"""
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE)
directory = Path(config.get('hyperopt_path', config['user_data_dir'] / USERPATH_HYPEROPTS))
hyperopts = HyperOptResolver.search_all_objects(directory)
# Sort alphabetically
hyperopts = sorted(hyperopts, key=lambda x: x['name'])
hyperopts_to_print = [{'name': s['name'], 'location': s['location'].name} for s in hyperopts]
if args['print_one_column']:
print('\n'.join([s['name'] for s in hyperopts]))
else:
print(tabulate(hyperopts_to_print, headers='keys', tablefmt='pipe'))
def start_list_timeframes(args: Dict[str, Any]) -> None: def start_list_timeframes(args: Dict[str, Any]) -> None:
""" """
Print ticker intervals (timeframes) available on Exchange Print ticker intervals (timeframes) available on Exchange

View File

@ -23,15 +23,16 @@ DRY_RUN_WALLET = 1000
MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons MATH_CLOSE_PREC = 1e-14 # Precision used for float comparisons
USERPATH_HYPEROPTS = 'hyperopts' USERPATH_HYPEROPTS = 'hyperopts'
USERPATH_STRATEGY = 'strategies' USERPATH_STRATEGIES = 'strategies'
USERPATH_NOTEBOOKS = 'notebooks'
# Soure files with destination directories within user-directory # Soure files with destination directories within user-directory
USER_DATA_FILES = { USER_DATA_FILES = {
'sample_strategy.py': USERPATH_STRATEGY, 'sample_strategy.py': USERPATH_STRATEGIES,
'sample_hyperopt_advanced.py': USERPATH_HYPEROPTS, 'sample_hyperopt_advanced.py': USERPATH_HYPEROPTS,
'sample_hyperopt_loss.py': USERPATH_HYPEROPTS, 'sample_hyperopt_loss.py': USERPATH_HYPEROPTS,
'sample_hyperopt.py': USERPATH_HYPEROPTS, 'sample_hyperopt.py': USERPATH_HYPEROPTS,
'strategy_analysis_example.ipynb': 'notebooks', 'strategy_analysis_example.ipynb': USERPATH_NOTEBOOKS,
} }
SUPPORTED_FIAT = [ SUPPORTED_FIAT = [

View File

@ -12,7 +12,7 @@ from pathlib import Path
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES, from freqtrade.constants import (REQUIRED_ORDERTIF, REQUIRED_ORDERTYPES,
USERPATH_STRATEGY) USERPATH_STRATEGIES)
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.resolvers import IResolver from freqtrade.resolvers import IResolver
from freqtrade.strategy.interface import IStrategy from freqtrade.strategy.interface import IStrategy
@ -26,7 +26,7 @@ class StrategyResolver(IResolver):
""" """
object_type = IStrategy object_type = IStrategy
object_type_str = "Strategy" object_type_str = "Strategy"
user_subdir = USERPATH_STRATEGY user_subdir = USERPATH_STRATEGIES
initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve() initial_search_path = Path(__file__).parent.parent.joinpath('strategy').resolve()
@staticmethod @staticmethod
@ -141,7 +141,7 @@ class StrategyResolver(IResolver):
""" """
abs_paths = StrategyResolver.build_search_paths(config, abs_paths = StrategyResolver.build_search_paths(config,
user_subdir=USERPATH_STRATEGY, user_subdir=USERPATH_STRATEGIES,
extra_dir=extra_dir) extra_dir=extra_dir)
if ":" in strategy_name: if ":" in strategy_name:

View File

@ -7,7 +7,8 @@ import pytest
from freqtrade.commands import (start_create_userdir, start_download_data, from freqtrade.commands import (start_create_userdir, start_download_data,
start_hyperopt_list, start_hyperopt_show, start_hyperopt_list, start_hyperopt_show,
start_list_exchanges, start_list_markets, start_list_exchanges, start_list_markets,
start_list_strategies, start_list_timeframes, start_list_hyperopts, start_list_strategies,
start_list_timeframes,
start_new_hyperopt, start_new_strategy, start_new_hyperopt, start_new_strategy,
start_test_pairlist, start_trading) start_test_pairlist, start_trading)
from freqtrade.configuration import setup_utils_configuration from freqtrade.configuration import setup_utils_configuration
@ -665,6 +666,39 @@ def test_start_list_strategies(mocker, caplog, capsys):
assert "DefaultStrategy" in captured.out assert "DefaultStrategy" in captured.out
def test_start_list_hyperopts(mocker, caplog, capsys):
args = [
"list-hyperopts",
"--hyperopt-path",
str(Path(__file__).parent.parent / "optimize"),
"-1"
]
pargs = get_args(args)
# pargs['config'] = None
start_list_hyperopts(pargs)
captured = capsys.readouterr()
assert "TestHyperoptLegacy" not in captured.out
assert "legacy_hyperopt.py" not in captured.out
assert "DefaultHyperOpt" in captured.out
assert "test_hyperopt.py" not in captured.out
# Test regular output
args = [
"list-hyperopts",
"--hyperopt-path",
str(Path(__file__).parent.parent / "optimize"),
]
pargs = get_args(args)
# pargs['config'] = None
start_list_hyperopts(pargs)
captured = capsys.readouterr()
assert "TestHyperoptLegacy" not in captured.out
assert "legacy_hyperopt.py" not in captured.out
assert "DefaultHyperOpt" in captured.out
assert "test_hyperopt.py" in captured.out
def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys): def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
patch_exchange(mocker, mock_markets=True) patch_exchange(mocker, mock_markets=True)
mocker.patch.multiple('freqtrade.exchange.Exchange', mocker.patch.multiple('freqtrade.exchange.Exchange',