diff --git a/config_full.json.example b/config_full.json.example
index 6593750b4..17d1abbe3 100644
--- a/config_full.json.example
+++ b/config_full.json.example
@@ -188,6 +188,7 @@
"disable_dataframe_checks": false,
"strategy": "DefaultStrategy",
"strategy_path": "user_data/strategies/",
+ "strategy_param": "{'param1': 5, 'param2': 'something'}",
"dataformat_ohlcv": "json",
"dataformat_trades": "jsongz"
}
diff --git a/docs/backtesting.md b/docs/backtesting.md
index a14c8f2e4..d6e3fc49a 100644
--- a/docs/backtesting.md
+++ b/docs/backtesting.md
@@ -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]
[-d PATH] [--userdir PATH] [-s NAME]
- [--strategy-path PATH] [-i TIMEFRAME]
- [--timerange TIMERANGE]
+ [--strategy-path PATH] [--strategy-params JSON]
+ [-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT]
[--stake-amount STAKE_AMOUNT] [--fee FLOAT]
@@ -85,6 +85,8 @@ Strategy arguments:
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
+ --strategy-params JSON
+ Specify additional strategy parameters.
```
diff --git a/docs/bot-usage.md b/docs/bot-usage.md
index c7fe8634d..fdff76e9e 100644
--- a/docs/bot-usage.md
+++ b/docs/bot-usage.md
@@ -54,7 +54,7 @@ optional arguments:
```
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]
optional arguments:
@@ -85,9 +85,10 @@ Common arguments:
Strategy arguments:
-s NAME, --strategy NAME
- Specify strategy class name which will be used by the
- bot.
- --strategy-path PATH Specify additional strategy lookup path.
+ Specify strategy class name which will be used by the
+ bot.
+ --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
```
+### 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?
This is very simple. Copy paste your strategy file into the directory
diff --git a/docs/configuration.md b/docs/configuration.md
index 00d2830e4..97bbe9c55 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -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).
*Defaults to `False`*.
**Datatype:** Boolean
| `strategy` | **Required** Defines Strategy class to use. Recommended to be set via `--strategy NAME`.
**Datatype:** ClassName
| `strategy_path` | Adds an additional strategy lookup path (must be a directory).
**Datatype:** String
+| `strategy_params` | Adds an additional strategy parameters.
**Datatype:** JSON
| `internals.process_throttle_secs` | Set the process throttle, or minimum loop duration for one bot iteration loop. Value in second.
*Defaults to `5` seconds.*
**Datatype:** Positive Integer
| `internals.heartbeat_interval` | Print heartbeat message every N seconds. Set to 0 to disable heartbeat messages.
*Defaults to `60` seconds.*
**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.
**Datatype:** Boolean
diff --git a/docs/edge.md b/docs/edge.md
index 5565ca2f9..56c65e55f 100644
--- a/docs/edge.md
+++ b/docs/edge.md
@@ -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]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
+ [--strategy-params JSON]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--max-open-trades INT] [--stake-amount STAKE_AMOUNT]
[--fee FLOAT] [--stoplosses STOPLOSS_RANGE]
@@ -260,6 +261,8 @@ Strategy arguments:
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
+ --strategy-params JSON
+ Specify additional strategy parameters.
```
diff --git a/docs/hyperopt.md b/docs/hyperopt.md
index ec155062f..edc3b3ff1 100644
--- a/docs/hyperopt.md
+++ b/docs/hyperopt.md
@@ -38,6 +38,7 @@ pip install -r requirements-hyperopt.txt
```
usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--userdir PATH] [-s NAME] [--strategy-path PATH]
+ [--strategy-params JSON]
[-i TIMEFRAME] [--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT]
@@ -130,6 +131,8 @@ Strategy arguments:
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
+ --strategy-params JSON
+ Specify additional strategy parameters.
```
diff --git a/docs/plotting.md b/docs/plotting.md
index 19ddb4f57..870baa894 100644
--- a/docs/plotting.md
+++ b/docs/plotting.md
@@ -25,7 +25,8 @@ Possible arguments:
```
usage: freqtrade plot-dataframe [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-d PATH] [--userdir PATH] [-s NAME]
- [--strategy-path PATH] [-p PAIRS [PAIRS ...]]
+ [--strategy-path PATH] [--strategy-params JSON]
+ [-p PAIRS [PAIRS ...]]
[--indicators1 INDICATORS1 [INDICATORS1 ...]]
[--indicators2 INDICATORS2 [INDICATORS2 ...]]
[--plot-limit INT] [--db-url PATH]
@@ -91,6 +92,8 @@ Strategy arguments:
Specify strategy class name which will be used by the
bot.
--strategy-path PATH Specify additional strategy lookup path.
+ --strategy-params JSON
+ Specify additional strategy parameters.
```
Example:
@@ -237,7 +240,8 @@ Possible options for the `freqtrade plot-profit` subcommand:
```
usage: freqtrade plot-profit [-h] [-v] [--logfile FILE] [-V] [-c PATH]
[-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]
[--export-filename PATH] [--db-url PATH]
[--trade-source {DB,file}] [-i TIMEFRAME]
@@ -288,6 +292,8 @@ Strategy arguments:
Specify strategy class name which will be used by the
bot.
--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.
diff --git a/freqtrade/commands/arguments.py b/freqtrade/commands/arguments.py
index c64c11a18..d9ce72140 100644
--- a/freqtrade/commands/arguments.py
+++ b/freqtrade/commands/arguments.py
@@ -12,7 +12,7 @@ from freqtrade.constants import DEFAULT_CONFIG
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"]
diff --git a/freqtrade/commands/cli_options.py b/freqtrade/commands/cli_options.py
index 7dc85377d..89ddc5d23 100644
--- a/freqtrade/commands/cli_options.py
+++ b/freqtrade/commands/cli_options.py
@@ -93,6 +93,11 @@ AVAILABLE_CLI_OPTIONS = {
help='Specify additional strategy lookup path.',
metavar='PATH',
),
+ "strategy_params": Arg(
+ '--strategy-params',
+ help='Specify additional strategy parameters.',
+ metavar='JSON',
+ ),
"db_url": Arg(
'--db-url',
help=f'Override trades database URL, this is useful in custom deployments '
diff --git a/freqtrade/configuration/configuration.py b/freqtrade/configuration/configuration.py
index 7bf3e6bf2..e4b65e772 100644
--- a/freqtrade/configuration/configuration.py
+++ b/freqtrade/configuration/configuration.py
@@ -1,6 +1,7 @@
"""
This module contains the configuration class
"""
+import json
import logging
import warnings
from copy import deepcopy
@@ -155,6 +156,9 @@ class Configuration:
self._args_to_config(config, argname='strategy_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
self.args['db_url'] != constants.DEFAULT_DB_PROD_URL):
config.update({'db_url': self.args['db_url']})
@@ -403,9 +407,9 @@ class Configuration:
config.update({'runmode': self.runmode})
- def _args_to_config(self, config: Dict[str, Any], argname: str,
- logstring: str, logfun: Optional[Callable] = None,
- deprecated_msg: Optional[str] = None) -> None:
+ def _args_to_config_from_json(self, config: Dict[str, Any], argname: str,
+ logstring: str, logfun: Optional[Callable] = None,
+ deprecated_msg: Optional[str] = None) -> None:
"""
:param config: Configuration dictionary
:param argname: Argumentname in self.args - will be copied to config dict.
@@ -415,10 +419,36 @@ class Configuration:
sample: logfun=len (prints the length of the found
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
and self.args[argname] is not False):
- config.update({argname: self.args[argname]})
+ config.update({argname: parsefun(self.args[argname])})
if logfun:
logger.info(logstring.format(logfun(config[argname])))
else:
diff --git a/tests/test_arguments.py b/tests/test_arguments.py
index 60c2cfbac..2aea7baa4 100644
--- a/tests/test_arguments.py
+++ b/tests/test_arguments.py
@@ -109,6 +109,18 @@ def test_parse_args_strategy_path_invalid() -> None:
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:
with pytest.raises(SystemExit, match=r'2'):
Arguments(['backtesting --ticker-interval']).get_parsed_arg()
diff --git a/tests/test_configuration.py b/tests/test_configuration.py
index 94c3e24f6..015ce4443 100644
--- a/tests/test_configuration.py
+++ b/tests/test_configuration.py
@@ -117,6 +117,38 @@ def test__args_to_config(caplog):
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:
default_conf['max_open_trades'] = 0
patched_configuration_load_config_file(mocker, default_conf)