config - add argument 'strategy_params'

This commit is contained in:
Florian Merz 2021-02-14 14:37:48 +01:00
parent 10a11bda34
commit 32dee81195
12 changed files with 117 additions and 13 deletions

View File

@ -188,6 +188,7 @@
"disable_dataframe_checks": false, "disable_dataframe_checks": false,
"strategy": "DefaultStrategy", "strategy": "DefaultStrategy",
"strategy_path": "user_data/strategies/", "strategy_path": "user_data/strategies/",
"strategy_param": "{'param1': 5, 'param2': 'something'}",
"dataformat_ohlcv": "json", "dataformat_ohlcv": "json",
"dataformat_trades": "jsongz" "dataformat_trades": "jsongz"
} }

View File

@ -10,8 +10,8 @@ To learn how to get data for the pairs and exchange you're interested in, head o
``` ```
usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade backtesting [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME] [-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-i TIMEFRAME] [--strategy-path PATH] [--strategy-params JSON]
[--timerange TIMERANGE] [-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}] [--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT] [--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT] [--stake-amount STAKE_AMOUNT] [--fee FLOAT]
@ -85,6 +85,8 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON
Specify additional strategy parameters.
``` ```

View File

@ -54,7 +54,7 @@ optional arguments:
``` ```
usage: freqtrade trade [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] usage: freqtrade trade [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH] [--strategy-params JSON]
[--db-url PATH] [--sd-notify] [--dry-run] [--db-url PATH] [--sd-notify] [--dry-run]
optional arguments: optional arguments:
@ -88,6 +88,7 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON Specify additional strategy params.
``` ```
@ -189,6 +190,14 @@ checked before the default locations (The passed path must be a directory!):
freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory freqtrade trade --strategy AwesomeStrategy --strategy-path /some/directory
``` ```
### How to use **--strategy-params**?
This parameter allows you to add parameters of your strategy:
```bash
freqtrade trade --strategy AwesomeStrategy --strategy-params "{'param1': 5, 'param2': 'something'}"
```
#### How to install a strategy? #### How to install a strategy?
This is very simple. Copy paste your strategy file into the directory This is very simple. Copy paste your strategy file into the directory

View File

@ -117,6 +117,7 @@ Mandatory parameters are marked as **Required**, which means that they are requi
| `disable_dataframe_checks` | Disable checking the OHLCV dataframe returned from the strategy methods for correctness. Only use when intentionally changing the dataframe and understand what you are doing. [Strategy Override](#parameters-in-the-strategy).<br> *Defaults to `False`*. <br> **Datatype:** Boolean | `disable_dataframe_checks` | Disable checking the OHLCV dataframe returned from the strategy methods for correctness. Only use when intentionally changing the dataframe and understand what you are doing. [Strategy Override](#parameters-in-the-strategy).<br> *Defaults to `False`*. <br> **Datatype:** Boolean
| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`. <br> **Datatype:** ClassName | `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`. <br> **Datatype:** ClassName
| `strategy_path` | Adds an additional strategy lookup path (must be a directory). <br> **Datatype:** String | `strategy_path` | Adds an additional strategy lookup path (must be a directory). <br> **Datatype:** String
| `strategy_params` | Adds an additional strategy parameters. <br> **Datatype:** JSON
| `internals.process_throttle_secs` | Set the process throttle, or minimum loop duration for one bot iteration loop. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer | `internals.process_throttle_secs` | Set the process throttle, or minimum loop duration for one bot iteration loop. Value in second. <br>*Defaults to `5` seconds.* <br> **Datatype:** Positive Integer
| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages. <br>*Defaults to `60` seconds.* <br> **Datatype:** Positive Integer or 0 | `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages. <br>*Defaults to `60` seconds.* <br> **Datatype:** Positive Integer or 0
| `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. <br> **Datatype:** Boolean | `internals.sd_notify` | Enables use of the sd_notify protocol to tell systemd service manager about changes in the bot state and issue keep-alive pings. See [here](installation.md#7-optional-configure-freqtrade-as-a-systemd-service) for more details. <br> **Datatype:** Boolean

View File

@ -214,6 +214,7 @@ Let's say the stake currency is **ETH** and there is $10$ **ETH** on the wallet.
``` ```
usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] usage: freqtrade edge [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH]
[--strategy-params JSON]
[-i TIMEFRAME] [--timerange TIMERANGE] [-i TIMEFRAME] [--timerange TIMERANGE]
[--max-open-trades INT] [--stake-amount STAKE_AMOUNT] [--max-open-trades INT] [--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [--stoplosses STOPLOSS_RANGE] [--fee FLOAT] [--stoplosses STOPLOSS_RANGE]
@ -260,6 +261,8 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON
Specify additional strategy parameters.
``` ```

View File

@ -38,6 +38,7 @@ pip install -r requirements-hyperopt.txt
``` ```
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH] usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH] [--userdir PATH] [-s NAME] [--strategy-path PATH]
[--strategy-params JSON]
[-i TIMEFRAME] [--timerange TIMERANGE] [-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}] [--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT] [--max-open-trades INT]
@ -130,6 +131,8 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON
Specify additional strategy parameters.
``` ```

View File

@ -25,7 +25,8 @@ Possible arguments:
``` ```
usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME] [-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-p PAIRS [PAIRS ...]] [--strategy-path PATH] [--strategy-params JSON]
[-p PAIRS [PAIRS ...]]
[--indicators1 INDICATORS1 [INDICATORS1 ...]] [--indicators1 INDICATORS1 [INDICATORS1 ...]]
[--indicators2 INDICATORS2 [INDICATORS2 ...]] [--indicators2 INDICATORS2 [INDICATORS2 ...]]
[--plot-limit INT] [--db-url PATH] [--plot-limit INT] [--db-url PATH]
@ -91,6 +92,8 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON
Specify additional strategy parameters.
``` ```
Example: Example:
@ -237,7 +240,8 @@ Possible options for the `freqtrade plot-profit` subcommand:
``` ```
usage: freqtrade plot-profit [-h] [-v] [--logfile FILE] [-V] [-c PATH] usage: freqtrade plot-profit [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME] [-d PATH] [--userdir PATH] [-s NAME]
[--strategy-path PATH] [-p PAIRS [PAIRS ...]] [--strategy-path PATH] [--strategy-params JSON]
[-p PAIRS [PAIRS ...]]
[--timerange TIMERANGE] [--export EXPORT] [--timerange TIMERANGE] [--export EXPORT]
[--export-filename PATH] [--db-url PATH] [--export-filename PATH] [--db-url PATH]
[--trade-source {DB,file}] [-i TIMEFRAME] [--trade-source {DB,file}] [-i TIMEFRAME]
@ -288,6 +292,8 @@ Strategy arguments:
Specify strategy class name which will be used by the Specify strategy class name which will be used by the
bot. bot.
--strategy-path PATH Specify additional strategy lookup path. --strategy-path PATH Specify additional strategy lookup path.
--strategy-params JSON
Specify additional strategy parameters.
``` ```
The `-p/--pairs` argument, can be used to limit the pairs that are considered for this calculation. The `-p/--pairs` argument, can be used to limit the pairs that are considered for this calculation.

View File

@ -12,7 +12,7 @@ from freqtrade.constants import DEFAULT_CONFIG
ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"] ARGS_COMMON = ["verbosity", "logfile", "version", "config", "datadir", "user_data_dir"]
ARGS_STRATEGY = ["strategy", "strategy_path"] ARGS_STRATEGY = ["strategy", "strategy_path", "strategy_params"]
ARGS_TRADE = ["db_url", "sd_notify", "dry_run"] ARGS_TRADE = ["db_url", "sd_notify", "dry_run"]

View File

@ -93,6 +93,11 @@ AVAILABLE_CLI_OPTIONS = {
help='Specify additional strategy lookup path.', help='Specify additional strategy lookup path.',
metavar='PATH', metavar='PATH',
), ),
"strategy_params": Arg(
'--strategy-params',
help='Specify additional strategy parameters.',
metavar='JSON',
),
"db_url": Arg( "db_url": Arg(
'--db-url', '--db-url',
help=f'Override trades database URL, this is useful in custom deployments ' help=f'Override trades database URL, this is useful in custom deployments '

View File

@ -1,6 +1,7 @@
""" """
This module contains the configuration class This module contains the configuration class
""" """
import json
import logging import logging
import warnings import warnings
from copy import deepcopy from copy import deepcopy
@ -155,6 +156,9 @@ class Configuration:
self._args_to_config(config, argname='strategy_path', self._args_to_config(config, argname='strategy_path',
logstring='Using additional Strategy lookup path: {}') logstring='Using additional Strategy lookup path: {}')
self._args_to_config_from_json(config, argname='strategy_params',
logstring='Using additional Strategy params: {}')
if ('db_url' in self.args and self.args['db_url'] and if ('db_url' in self.args and self.args['db_url'] and
self.args['db_url'] != constants.DEFAULT_DB_PROD_URL): self.args['db_url'] != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args['db_url']}) config.update({'db_url': self.args['db_url']})
@ -403,7 +407,7 @@ class Configuration:
config.update({'runmode': self.runmode}) config.update({'runmode': self.runmode})
def _args_to_config(self, config: Dict[str, Any], argname: str, def _args_to_config_from_json(self, config: Dict[str, Any], argname: str,
logstring: str, logfun: Optional[Callable] = None, logstring: str, logfun: Optional[Callable] = None,
deprecated_msg: Optional[str] = None) -> None: deprecated_msg: Optional[str] = None) -> None:
""" """
@ -415,10 +419,36 @@ class Configuration:
sample: logfun=len (prints the length of the found sample: logfun=len (prints the length of the found
configuration instead of the content) configuration instead of the content)
""" """
def parsejson(argvalue):
return json.loads(argvalue.replace('\\\'', '\"'))
self._args_to_config(
config=config,
argname=argname,
logstring=logstring,
logfun=logfun,
deprecated_msg=deprecated_msg,
parsefun=parsejson
)
def _args_to_config(self, config: Dict[str, Any], argname: str,
logstring: str, logfun: Optional[Callable] = None,
deprecated_msg: Optional[str] = None,
parsefun: Callable = lambda x: x) -> None:
"""
:param config: Configuration dictionary
:param argname: Argumentname in self.args - will be copied to config dict.
:param logstring: Logging String
:param logfun: logfun is applied to the configuration entry before passing
that entry to the log string using .format().
sample: logfun=len (prints the length of the found
configuration instead of the content)
:param parsefun: parsefun is applied to the argvalue before updating the configuration
"""
if (argname in self.args and self.args[argname] is not None if (argname in self.args and self.args[argname] is not None
and self.args[argname] is not False): and self.args[argname] is not False):
config.update({argname: self.args[argname]}) config.update({argname: parsefun(self.args[argname])})
if logfun: if logfun:
logger.info(logstring.format(logfun(config[argname]))) logger.info(logstring.format(logfun(config[argname])))
else: else:

View File

@ -109,6 +109,18 @@ def test_parse_args_strategy_path_invalid() -> None:
Arguments(['--strategy-path']).get_parsed_arg() Arguments(['--strategy-path']).get_parsed_arg()
def test_parse_args_strategy_params() -> None:
args = Arguments([
'trade', '--strategy-params', '{"param1": 5, "param2": "something"}'
]).get_parsed_arg()
assert args['strategy_params'] == '{"param1": 5, "param2": "something"}'
def test_parse_args_strategy_params_invalid() -> None:
with pytest.raises(SystemExit, match=r'2'):
Arguments(['--strategy-params']).get_parsed_arg()
def test_parse_args_backtesting_invalid() -> None: def test_parse_args_backtesting_invalid() -> None:
with pytest.raises(SystemExit, match=r'2'): with pytest.raises(SystemExit, match=r'2'):
Arguments(['backtesting --ticker-interval']).get_parsed_arg() Arguments(['backtesting --ticker-interval']).get_parsed_arg()

View File

@ -117,6 +117,38 @@ def test__args_to_config(caplog):
assert config['strategy_path'] == "TestTest" assert config['strategy_path'] == "TestTest"
def test__args_to_config_from_json(caplog):
arg_list = ['trade', '--strategy-params', '{"param1": 5, "param2": "something"}']
args = Arguments(arg_list).get_parsed_arg()
configuration = Configuration(args)
config = {}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
# No warnings ...
configuration._args_to_config_from_json(config, argname="strategy_params",
logstring="DeadBeef")
assert len(w) == 0
assert log_has("DeadBeef", caplog)
assert config['strategy_params']['param1'] == 5
assert config['strategy_params']['param2'] == 'something'
configuration = Configuration(args)
config = {}
with warnings.catch_warnings(record=True) as w:
warnings.simplefilter("always")
# Deprecation warnings!
configuration._args_to_config_from_json(config, argname="strategy_params",
logstring="DeadBeef",
deprecated_msg="Going away soon!")
assert len(w) == 1
assert issubclass(w[-1].category, DeprecationWarning)
assert "DEPRECATED: Going away soon!" in str(w[-1].message)
assert log_has("DeadBeef", caplog)
assert config['strategy_params']['param1'] == 5
assert config['strategy_params']['param2'] == 'something'
def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None: def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
default_conf['max_open_trades'] = 0 default_conf['max_open_trades'] = 0
patched_configuration_load_config_file(mocker, default_conf) patched_configuration_load_config_file(mocker, default_conf)