Merge branch 'develop' into isort_config
This commit is contained in:
commit
6977ffdbf9
@ -27,9 +27,9 @@ class MyAwesomeHyperOpt2(MyAwesomeHyperOpt):
|
|||||||
and then quickly switch between hyperopt classes, running optimization process with hyperopt class you need in each particular case:
|
and then quickly switch between hyperopt classes, running optimization process with hyperopt class you need in each particular case:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt ...
|
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt --strategy MyAwesomeStrategy ...
|
||||||
or
|
or
|
||||||
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 ...
|
$ freqtrade hyperopt --hyperopt MyAwesomeHyperOpt2 --strategy MyAwesomeStrategy ...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Creating and using a custom loss function
|
## Creating and using a custom loss function
|
||||||
|
@ -303,7 +303,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
|
|||||||
[--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]]
|
[--spaces {all,buy,sell,roi,stoploss,trailing,default} [{all,buy,sell,roi,stoploss,trailing,default} ...]]
|
||||||
[--dmmp] [--print-all] [--no-color] [--print-json]
|
[--dmmp] [--print-all] [--no-color] [--print-json]
|
||||||
[-j JOBS] [--random-state INT] [--min-trades INT]
|
[-j JOBS] [--random-state INT] [--min-trades INT]
|
||||||
[--continue] [--hyperopt-loss NAME]
|
[--hyperopt-loss NAME]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@ -349,9 +349,6 @@ optional arguments:
|
|||||||
reproducible hyperopt results.
|
reproducible hyperopt results.
|
||||||
--min-trades INT Set minimal desired number of trades for evaluations
|
--min-trades INT Set minimal desired number of trades for evaluations
|
||||||
in the hyperopt optimization path (default: 1).
|
in the hyperopt optimization path (default: 1).
|
||||||
--continue Continue hyperopt from previous runs. By default,
|
|
||||||
temporary files will be removed and hyperopt will
|
|
||||||
start from scratch.
|
|
||||||
--hyperopt-loss NAME Specify the class name of the hyperopt loss function
|
--hyperopt-loss NAME Specify the class name of the hyperopt loss function
|
||||||
class (IHyperOptLoss). Different functions can
|
class (IHyperOptLoss). Different functions can
|
||||||
generate completely different results, since the
|
generate completely different results, since the
|
||||||
|
@ -140,13 +140,7 @@ Since hyperopt uses Bayesian search, running for too many epochs may not produce
|
|||||||
It's therefore recommended to run between 500-1000 epochs over and over until you hit at least 10.000 epochs in total (or are satisfied with the result). You can best judge by looking at the results - if the bot keeps discovering better strategies, it's best to keep on going.
|
It's therefore recommended to run between 500-1000 epochs over and over until you hit at least 10.000 epochs in total (or are satisfied with the result). You can best judge by looking at the results - if the bot keeps discovering better strategies, it's best to keep on going.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade hyperopt -e 1000
|
freqtrade hyperopt --hyperop SampleHyperopt --strategy SampleStrategy -e 1000
|
||||||
```
|
|
||||||
|
|
||||||
or if you want intermediate result to see
|
|
||||||
|
|
||||||
```bash
|
|
||||||
for i in {1..100}; do freqtrade hyperopt -e 1000; done
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Why does it take a long time to run hyperopt?
|
### Why does it take a long time to run hyperopt?
|
||||||
|
@ -102,7 +102,7 @@ There you have two different types of indicators: 1. `guards` and 2. `triggers`.
|
|||||||
1. Guards are conditions like "never buy if ADX < 10", or never buy if current price is over EMA10.
|
1. Guards are conditions like "never buy if ADX < 10", or never buy if current price is over EMA10.
|
||||||
2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower Bollinger band".
|
2. Triggers are ones that actually trigger buy in specific moment, like "buy when EMA5 crosses over EMA10" or "buy when close price touches lower Bollinger band".
|
||||||
|
|
||||||
Hyperoptimization will, for each eval round, pick one trigger and possibly
|
Hyper-optimization will, for each epoch round, pick one trigger and possibly
|
||||||
multiple guards. The constructed strategy will be something like
|
multiple guards. The constructed strategy will be something like
|
||||||
"*buy exactly when close price touches lower Bollinger band, BUT only if
|
"*buy exactly when close price touches lower Bollinger band, BUT only if
|
||||||
ADX > 10*".
|
ADX > 10*".
|
||||||
@ -229,7 +229,7 @@ Because hyperopt tries a lot of combinations to find the best parameters it will
|
|||||||
We strongly recommend to use `screen` or `tmux` to prevent any connection loss.
|
We strongly recommend to use `screen` or `tmux` to prevent any connection loss.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade hyperopt --config config.json --hyperopt <hyperoptname> -e 500 --spaces all
|
freqtrade hyperopt --config config.json --hyperopt <hyperoptname> --strategy <strategyname> -e 500 --spaces all
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `<hyperoptname>` as the name of the custom hyperopt used.
|
Use `<hyperoptname>` as the name of the custom hyperopt used.
|
||||||
@ -240,10 +240,8 @@ running at least several thousand evaluations.
|
|||||||
The `--spaces all` option determines that all possible parameters should be optimized. Possibilities are listed below.
|
The `--spaces all` option determines that all possible parameters should be optimized. Possibilities are listed below.
|
||||||
|
|
||||||
!!! Note
|
!!! Note
|
||||||
By default, hyperopt will erase previous results and start from scratch. Continuation can be archived by using `--continue`.
|
Hyperopt will store hyperopt results with the timestamp of the hyperopt start time.
|
||||||
|
Reading commands (`hyperopt-list`, `hyperopt-show`) can use `--hyperopt-filename <filename>` to read and display older hyperopt results.
|
||||||
!!! Warning
|
|
||||||
When switching parameters or changing configuration options, make sure to not use the argument `--continue` so temporary results can be removed.
|
|
||||||
|
|
||||||
### Execute Hyperopt with different historical data source
|
### Execute Hyperopt with different historical data source
|
||||||
|
|
||||||
@ -253,11 +251,11 @@ uses data from directory `user_data/data`.
|
|||||||
|
|
||||||
### Running Hyperopt with Smaller Testset
|
### Running Hyperopt with Smaller Testset
|
||||||
|
|
||||||
Use the `--timerange` argument to change how much of the testset you want to use.
|
Use the `--timerange` argument to change how much of the test-set you want to use.
|
||||||
For example, to use one month of data, pass the following parameter to the hyperopt call:
|
For example, to use one month of data, pass the following parameter to the hyperopt call:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
freqtrade hyperopt --timerange 20180401-20180501
|
freqtrade hyperopt --hyperopt <hyperoptname> --strategy <strategyname> --timerange 20180401-20180501
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running Hyperopt using methods from a strategy
|
### Running Hyperopt using methods from a strategy
|
||||||
@ -318,7 +316,7 @@ The initial state for generation of these random values (random state) is contro
|
|||||||
|
|
||||||
If you have not set this value explicitly in the command line options, Hyperopt seeds the random state with some random value for you. The random state value for each Hyperopt run is shown in the log, so you can copy and paste it into the `--random-state` command line option to repeat the set of the initial random epochs used.
|
If you have not set this value explicitly in the command line options, Hyperopt seeds the random state with some random value for you. The random state value for each Hyperopt run is shown in the log, so you can copy and paste it into the `--random-state` command line option to repeat the set of the initial random epochs used.
|
||||||
|
|
||||||
If you have not changed anything in the command line options, configuration, timerange, Strategy and Hyperopt classes, historical data and the Loss Function -- you should obtain same hyperoptimization results with same random state value used.
|
If you have not changed anything in the command line options, configuration, timerange, Strategy and Hyperopt classes, historical data and the Loss Function -- you should obtain same hyper-optimization results with same random state value used.
|
||||||
|
|
||||||
## Understand the Hyperopt Result
|
## Understand the Hyperopt Result
|
||||||
|
|
||||||
@ -371,7 +369,7 @@ By default, hyperopt prints colorized results -- epochs with positive profit are
|
|||||||
You can use the `--print-all` command line option if you would like to see all results in the hyperopt output, not only the best ones. When `--print-all` is used, current best results are also colorized by default -- they are printed in bold (bright) style. This can also be switched off with the `--no-color` command line option.
|
You can use the `--print-all` command line option if you would like to see all results in the hyperopt output, not only the best ones. When `--print-all` is used, current best results are also colorized by default -- they are printed in bold (bright) style. This can also be switched off with the `--no-color` command line option.
|
||||||
|
|
||||||
!!! Note "Windows and color output"
|
!!! Note "Windows and color output"
|
||||||
Windows does not support color-output nativly, therefore it is automatically disabled. To have color-output for hyperopt running under windows, please consider using WSL.
|
Windows does not support color-output natively, therefore it is automatically disabled. To have color-output for hyperopt running under windows, please consider using WSL.
|
||||||
|
|
||||||
### Understand Hyperopt ROI results
|
### Understand Hyperopt ROI results
|
||||||
|
|
||||||
@ -494,7 +492,7 @@ Override the `trailing_space()` method and define the desired range in it if you
|
|||||||
|
|
||||||
## Show details of Hyperopt results
|
## Show details of Hyperopt results
|
||||||
|
|
||||||
After you run Hyperopt for the desired amount of epochs, you can later list all results for analysis, select only best or profitable once, and show the details for any of the epochs previously evaluated. This can be done with the `hyperopt-list` and `hyperopt-show` subcommands. The usage of these subcommands is described in the [Utils](utils.md#list-hyperopt-results) chapter.
|
After you run Hyperopt for the desired amount of epochs, you can later list all results for analysis, select only best or profitable once, and show the details for any of the epochs previously evaluated. This can be done with the `hyperopt-list` and `hyperopt-show` sub-commands. The usage of these sub-commands is described in the [Utils](utils.md#list-hyperopt-results) chapter.
|
||||||
|
|
||||||
## Validate backtesting results
|
## Validate backtesting results
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ freqtrade test-pairlist --config config.json --quote USDT BTC
|
|||||||
|
|
||||||
## List Hyperopt results
|
## List Hyperopt results
|
||||||
|
|
||||||
You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` subcommand.
|
You can list the hyperoptimization epochs the Hyperopt module evaluated previously with the `hyperopt-list` sub-command.
|
||||||
|
|
||||||
```
|
```
|
||||||
usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
|
usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
|
||||||
@ -432,10 +432,11 @@ usage: freqtrade hyperopt-list [-h] [-v] [--logfile FILE] [-V] [-c PATH]
|
|||||||
[--max-trades INT] [--min-avg-time FLOAT]
|
[--max-trades INT] [--min-avg-time FLOAT]
|
||||||
[--max-avg-time FLOAT] [--min-avg-profit FLOAT]
|
[--max-avg-time FLOAT] [--min-avg-profit FLOAT]
|
||||||
[--max-avg-profit FLOAT]
|
[--max-avg-profit FLOAT]
|
||||||
[--min-total-profit FLOAT] [--max-total-profit FLOAT]
|
[--min-total-profit FLOAT]
|
||||||
|
[--max-total-profit FLOAT]
|
||||||
[--min-objective FLOAT] [--max-objective FLOAT]
|
[--min-objective FLOAT] [--max-objective FLOAT]
|
||||||
[--no-color] [--print-json] [--no-details]
|
[--no-color] [--print-json] [--no-details]
|
||||||
[--export-csv FILE]
|
[--hyperopt-filename PATH] [--export-csv FILE]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@ -443,24 +444,27 @@ optional arguments:
|
|||||||
--profitable Select only profitable epochs.
|
--profitable Select only profitable epochs.
|
||||||
--min-trades INT Select epochs with more than INT trades.
|
--min-trades INT Select epochs with more than INT trades.
|
||||||
--max-trades INT Select epochs with less than INT trades.
|
--max-trades INT Select epochs with less than INT trades.
|
||||||
--min-avg-time FLOAT Select epochs on above average time.
|
--min-avg-time FLOAT Select epochs above average time.
|
||||||
--max-avg-time FLOAT Select epochs on under average time.
|
--max-avg-time FLOAT Select epochs below average time.
|
||||||
--min-avg-profit FLOAT
|
--min-avg-profit FLOAT
|
||||||
Select epochs on above average profit.
|
Select epochs above average profit.
|
||||||
--max-avg-profit FLOAT
|
--max-avg-profit FLOAT
|
||||||
Select epochs on below average profit.
|
Select epochs below average profit.
|
||||||
--min-total-profit FLOAT
|
--min-total-profit FLOAT
|
||||||
Select epochs on above total profit.
|
Select epochs above total profit.
|
||||||
--max-total-profit FLOAT
|
--max-total-profit FLOAT
|
||||||
Select epochs on below total profit.
|
Select epochs below total profit.
|
||||||
--min-objective FLOAT
|
--min-objective FLOAT
|
||||||
Select epochs on above objective (- is added by default).
|
Select epochs above objective.
|
||||||
--max-objective FLOAT
|
--max-objective FLOAT
|
||||||
Select epochs on below objective (- is added by default).
|
Select epochs below objective.
|
||||||
--no-color Disable colorization of hyperopt results. May be
|
--no-color Disable colorization of hyperopt results. May be
|
||||||
useful if you are redirecting output to a file.
|
useful if you are redirecting output to a file.
|
||||||
--print-json Print best result detailization in JSON format.
|
--print-json Print output in JSON format.
|
||||||
--no-details Do not print best epoch details.
|
--no-details Do not print best epoch details.
|
||||||
|
--hyperopt-filename FILENAME
|
||||||
|
Hyperopt result filename.Example: `--hyperopt-
|
||||||
|
filename=hyperopt_results_2020-09-27_16-20-48.pickle`
|
||||||
--export-csv FILE Export to CSV-File. This will disable table print.
|
--export-csv FILE Export to CSV-File. This will disable table print.
|
||||||
Example: --export-csv hyperopt.csv
|
Example: --export-csv hyperopt.csv
|
||||||
|
|
||||||
@ -480,7 +484,11 @@ Common arguments:
|
|||||||
--userdir PATH, --user-data-dir PATH
|
--userdir PATH, --user-data-dir PATH
|
||||||
Path to userdata directory.
|
Path to userdata directory.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
`hyperopt-list` will automatically use the latest available hyperopt results file.
|
||||||
|
You can override this using the `--hyperopt-filename` argument, and specify another, available filename (without path!).
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
List all results, print details of the best result at the end:
|
List all results, print details of the best result at the end:
|
||||||
@ -501,17 +509,41 @@ You can show the details of any hyperoptimization epoch previously evaluated by
|
|||||||
usage: freqtrade hyperopt-show [-h] [-v] [--logfile FILE] [-V] [-c PATH]
|
usage: freqtrade hyperopt-show [-h] [-v] [--logfile FILE] [-V] [-c PATH]
|
||||||
[-d PATH] [--userdir PATH] [--best]
|
[-d PATH] [--userdir PATH] [--best]
|
||||||
[--profitable] [-n INT] [--print-json]
|
[--profitable] [-n INT] [--print-json]
|
||||||
[--no-header]
|
[--hyperopt-filename PATH] [--no-header]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
--best Select only best epochs.
|
--best Select only best epochs.
|
||||||
--profitable Select only profitable epochs.
|
--profitable Select only profitable epochs.
|
||||||
-n INT, --index INT Specify the index of the epoch to print details for.
|
-n INT, --index INT Specify the index of the epoch to print details for.
|
||||||
--print-json Print best result detailization in JSON format.
|
--print-json Print output in JSON format.
|
||||||
|
--hyperopt-filename FILENAME
|
||||||
|
Hyperopt result filename.Example: `--hyperopt-
|
||||||
|
filename=hyperopt_results_2020-09-27_16-20-48.pickle`
|
||||||
--no-header Do not print epoch details header.
|
--no-header Do not print epoch details header.
|
||||||
|
|
||||||
|
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:
|
||||||
|
`userdir/config.json` or `config.json` whichever
|
||||||
|
exists). 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.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
!!! Note
|
||||||
|
`hyperopt-show` will automatically use the latest available hyperopt results file.
|
||||||
|
You can override this using the `--hyperopt-filename` argument, and specify another, available filename (without path!).
|
||||||
|
|
||||||
### Examples
|
### Examples
|
||||||
|
|
||||||
Print details for the epoch 168 (the number of the epoch is shown by the `hyperopt-list` subcommand or by Hyperopt itself during hyperoptimization run):
|
Print details for the epoch 168 (the number of the epoch is shown by the `hyperopt-list` subcommand or by Hyperopt itself during hyperoptimization run):
|
||||||
|
@ -27,7 +27,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
|
|||||||
"use_max_market_positions", "print_all",
|
"use_max_market_positions", "print_all",
|
||||||
"print_colorized", "print_json", "hyperopt_jobs",
|
"print_colorized", "print_json", "hyperopt_jobs",
|
||||||
"hyperopt_random_state", "hyperopt_min_trades",
|
"hyperopt_random_state", "hyperopt_min_trades",
|
||||||
"hyperopt_continue", "hyperopt_loss"]
|
"hyperopt_loss"]
|
||||||
|
|
||||||
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
|
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
|
||||||
|
|
||||||
@ -76,10 +76,10 @@ ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable",
|
|||||||
"hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit",
|
"hyperopt_list_min_total_profit", "hyperopt_list_max_total_profit",
|
||||||
"hyperopt_list_min_objective", "hyperopt_list_max_objective",
|
"hyperopt_list_min_objective", "hyperopt_list_max_objective",
|
||||||
"print_colorized", "print_json", "hyperopt_list_no_details",
|
"print_colorized", "print_json", "hyperopt_list_no_details",
|
||||||
"export_csv"]
|
"hyperoptexportfilename", "export_csv"]
|
||||||
|
|
||||||
ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index",
|
ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperopt_show_index",
|
||||||
"print_json", "hyperopt_show_no_header"]
|
"print_json", "hyperoptexportfilename", "hyperopt_show_no_header"]
|
||||||
|
|
||||||
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
|
NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes",
|
||||||
"list-markets", "list-pairs", "list-strategies", "list-data",
|
"list-markets", "list-pairs", "list-strategies", "list-data",
|
||||||
|
@ -252,13 +252,6 @@ AVAILABLE_CLI_OPTIONS = {
|
|||||||
metavar='INT',
|
metavar='INT',
|
||||||
default=1,
|
default=1,
|
||||||
),
|
),
|
||||||
"hyperopt_continue": Arg(
|
|
||||||
"--continue",
|
|
||||||
help="Continue hyperopt from previous runs. "
|
|
||||||
"By default, temporary files will be removed and hyperopt will start from scratch.",
|
|
||||||
default=False,
|
|
||||||
action='store_true',
|
|
||||||
),
|
|
||||||
"hyperopt_loss": Arg(
|
"hyperopt_loss": Arg(
|
||||||
'--hyperopt-loss',
|
'--hyperopt-loss',
|
||||||
help='Specify the class name of the hyperopt loss function class (IHyperOptLoss). '
|
help='Specify the class name of the hyperopt loss function class (IHyperOptLoss). '
|
||||||
@ -270,6 +263,12 @@ AVAILABLE_CLI_OPTIONS = {
|
|||||||
metavar='NAME',
|
metavar='NAME',
|
||||||
default=constants.DEFAULT_HYPEROPT_LOSS,
|
default=constants.DEFAULT_HYPEROPT_LOSS,
|
||||||
),
|
),
|
||||||
|
"hyperoptexportfilename": Arg(
|
||||||
|
'--hyperopt-filename',
|
||||||
|
help='Hyperopt result filename.'
|
||||||
|
'Example: `--hyperopt-filename=hyperopt_results_2020-09-27_16-20-48.pickle`',
|
||||||
|
metavar='FILENAME',
|
||||||
|
),
|
||||||
# List exchanges
|
# List exchanges
|
||||||
"print_one_column": Arg(
|
"print_one_column": Arg(
|
||||||
'-1', '--one-column',
|
'-1', '--one-column',
|
||||||
|
@ -5,6 +5,7 @@ from typing import Any, Dict, List
|
|||||||
from colorama import init as colorama_init
|
from colorama import init as colorama_init
|
||||||
|
|
||||||
from freqtrade.configuration import setup_utils_configuration
|
from freqtrade.configuration import setup_utils_configuration
|
||||||
|
from freqtrade.data.btanalysis import get_latest_hyperopt_file
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.state import RunMode
|
from freqtrade.state import RunMode
|
||||||
|
|
||||||
@ -41,8 +42,9 @@ def start_hyperopt_list(args: Dict[str, Any]) -> None:
|
|||||||
'filter_max_objective': config.get('hyperopt_list_max_objective', None),
|
'filter_max_objective': config.get('hyperopt_list_max_objective', None),
|
||||||
}
|
}
|
||||||
|
|
||||||
results_file = (config['user_data_dir'] /
|
results_file = get_latest_hyperopt_file(
|
||||||
'hyperopt_results' / 'hyperopt_results.pickle')
|
config['user_data_dir'] / 'hyperopt_results',
|
||||||
|
config.get('hyperoptexportfilename'))
|
||||||
|
|
||||||
# Previous evaluations
|
# Previous evaluations
|
||||||
epochs = Hyperopt.load_previous_results(results_file)
|
epochs = Hyperopt.load_previous_results(results_file)
|
||||||
@ -81,8 +83,10 @@ def start_hyperopt_show(args: Dict[str, Any]) -> None:
|
|||||||
|
|
||||||
print_json = config.get('print_json', False)
|
print_json = config.get('print_json', False)
|
||||||
no_header = config.get('hyperopt_show_no_header', False)
|
no_header = config.get('hyperopt_show_no_header', False)
|
||||||
results_file = (config['user_data_dir'] /
|
results_file = get_latest_hyperopt_file(
|
||||||
'hyperopt_results' / 'hyperopt_results.pickle')
|
config['user_data_dir'] / 'hyperopt_results',
|
||||||
|
config.get('hyperoptexportfilename'))
|
||||||
|
|
||||||
n = config.get('hyperopt_show_index', -1)
|
n = config.get('hyperopt_show_index', -1)
|
||||||
|
|
||||||
filteroptions = {
|
filteroptions = {
|
||||||
|
@ -263,6 +263,9 @@ class Configuration:
|
|||||||
self._args_to_config(config, argname='hyperopt_path',
|
self._args_to_config(config, argname='hyperopt_path',
|
||||||
logstring='Using additional Hyperopt lookup path: {}')
|
logstring='Using additional Hyperopt lookup path: {}')
|
||||||
|
|
||||||
|
self._args_to_config(config, argname='hyperoptexportfilename',
|
||||||
|
logstring='Using hyperopt file: {}')
|
||||||
|
|
||||||
self._args_to_config(config, argname='epochs',
|
self._args_to_config(config, argname='epochs',
|
||||||
logstring='Parameter --epochs detected ... '
|
logstring='Parameter --epochs detected ... '
|
||||||
'Will run Hyperopt with for {} epochs ...'
|
'Will run Hyperopt with for {} epochs ...'
|
||||||
@ -295,9 +298,6 @@ class Configuration:
|
|||||||
self._args_to_config(config, argname='hyperopt_min_trades',
|
self._args_to_config(config, argname='hyperopt_min_trades',
|
||||||
logstring='Parameter --min-trades detected: {}')
|
logstring='Parameter --min-trades detected: {}')
|
||||||
|
|
||||||
self._args_to_config(config, argname='hyperopt_continue',
|
|
||||||
logstring='Hyperopt continue: {}')
|
|
||||||
|
|
||||||
self._args_to_config(config, argname='hyperopt_loss',
|
self._args_to_config(config, argname='hyperopt_loss',
|
||||||
logstring='Using Hyperopt loss class name: {}')
|
logstring='Using Hyperopt loss class name: {}')
|
||||||
|
|
||||||
|
@ -22,10 +22,11 @@ BT_DATA_COLUMNS = ["pair", "profit_percent", "open_date", "close_date", "index",
|
|||||||
"open_rate", "close_rate", "open_at_end", "sell_reason"]
|
"open_rate", "close_rate", "open_at_end", "sell_reason"]
|
||||||
|
|
||||||
|
|
||||||
def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
|
def get_latest_optimize_filename(directory: Union[Path, str], variant: str) -> str:
|
||||||
"""
|
"""
|
||||||
Get latest backtest export based on '.last_result.json'.
|
Get latest backtest export based on '.last_result.json'.
|
||||||
:param directory: Directory to search for last result
|
:param directory: Directory to search for last result
|
||||||
|
:param variant: 'backtest' or 'hyperopt' - the method to return
|
||||||
:return: string containing the filename of the latest backtest result
|
:return: string containing the filename of the latest backtest result
|
||||||
:raises: ValueError in the following cases:
|
:raises: ValueError in the following cases:
|
||||||
* Directory does not exist
|
* Directory does not exist
|
||||||
@ -45,10 +46,57 @@ def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
|
|||||||
with filename.open() as file:
|
with filename.open() as file:
|
||||||
data = json_load(file)
|
data = json_load(file)
|
||||||
|
|
||||||
if 'latest_backtest' not in data:
|
if f'latest_{variant}' not in data:
|
||||||
raise ValueError(f"Invalid '{LAST_BT_RESULT_FN}' format.")
|
raise ValueError(f"Invalid '{LAST_BT_RESULT_FN}' format.")
|
||||||
|
|
||||||
return data['latest_backtest']
|
return data[f'latest_{variant}']
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_backtest_filename(directory: Union[Path, str]) -> str:
|
||||||
|
"""
|
||||||
|
Get latest backtest export based on '.last_result.json'.
|
||||||
|
:param directory: Directory to search for last result
|
||||||
|
:return: string containing the filename of the latest backtest result
|
||||||
|
:raises: ValueError in the following cases:
|
||||||
|
* Directory does not exist
|
||||||
|
* `directory/.last_result.json` does not exist
|
||||||
|
* `directory/.last_result.json` has the wrong content
|
||||||
|
"""
|
||||||
|
return get_latest_optimize_filename(directory, 'backtest')
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_hyperopt_filename(directory: Union[Path, str]) -> str:
|
||||||
|
"""
|
||||||
|
Get latest hyperopt export based on '.last_result.json'.
|
||||||
|
:param directory: Directory to search for last result
|
||||||
|
:return: string containing the filename of the latest hyperopt result
|
||||||
|
:raises: ValueError in the following cases:
|
||||||
|
* Directory does not exist
|
||||||
|
* `directory/.last_result.json` does not exist
|
||||||
|
* `directory/.last_result.json` has the wrong content
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return get_latest_optimize_filename(directory, 'hyperopt')
|
||||||
|
except ValueError:
|
||||||
|
# Return default (legacy) pickle filename
|
||||||
|
return 'hyperopt_results.pickle'
|
||||||
|
|
||||||
|
|
||||||
|
def get_latest_hyperopt_file(directory: Union[Path, str], predef_filename: str = None) -> Path:
|
||||||
|
"""
|
||||||
|
Get latest hyperopt export based on '.last_result.json'.
|
||||||
|
:param directory: Directory to search for last result
|
||||||
|
:return: string containing the filename of the latest hyperopt result
|
||||||
|
:raises: ValueError in the following cases:
|
||||||
|
* Directory does not exist
|
||||||
|
* `directory/.last_result.json` does not exist
|
||||||
|
* `directory/.last_result.json` has the wrong content
|
||||||
|
"""
|
||||||
|
if isinstance(directory, str):
|
||||||
|
directory = Path(directory)
|
||||||
|
if predef_filename:
|
||||||
|
return directory / predef_filename
|
||||||
|
return directory / get_latest_hyperopt_filename(directory)
|
||||||
|
|
||||||
|
|
||||||
def load_backtest_stats(filename: Union[Path, str]) -> Dict[str, Any]:
|
def load_backtest_stats(filename: Union[Path, str]) -> Dict[str, Any]:
|
||||||
|
@ -10,6 +10,7 @@ import logging
|
|||||||
import random
|
import random
|
||||||
import warnings
|
import warnings
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
from datetime import datetime
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
@ -24,11 +25,11 @@ from colorama import init as colorama_init
|
|||||||
from joblib import Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects
|
from joblib import Parallel, cpu_count, delayed, dump, load, wrap_non_picklable_objects
|
||||||
from pandas import DataFrame, isna, json_normalize
|
from pandas import DataFrame, isna, json_normalize
|
||||||
|
|
||||||
from freqtrade.constants import DATETIME_PRINT_FORMAT
|
from freqtrade.constants import DATETIME_PRINT_FORMAT, LAST_BT_RESULT_FN
|
||||||
from freqtrade.data.converter import trim_dataframe
|
from freqtrade.data.converter import trim_dataframe
|
||||||
from freqtrade.data.history import get_timerange
|
from freqtrade.data.history import get_timerange
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import plural, round_dict
|
from freqtrade.misc import file_dump_json, plural, round_dict
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
# Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules
|
# Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules
|
||||||
from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F401
|
from freqtrade.optimize.hyperopt_interface import IHyperOpt # noqa: F401
|
||||||
@ -75,19 +76,16 @@ class Hyperopt:
|
|||||||
|
|
||||||
self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config)
|
self.custom_hyperoptloss = HyperOptLossResolver.load_hyperoptloss(self.config)
|
||||||
self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function
|
self.calculate_loss = self.custom_hyperoptloss.hyperopt_loss_function
|
||||||
|
time_now = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
self.results_file = (self.config['user_data_dir'] /
|
self.results_file = (self.config['user_data_dir'] /
|
||||||
'hyperopt_results' / 'hyperopt_results.pickle')
|
'hyperopt_results' / f'hyperopt_results_{time_now}.pickle')
|
||||||
self.data_pickle_file = (self.config['user_data_dir'] /
|
self.data_pickle_file = (self.config['user_data_dir'] /
|
||||||
'hyperopt_results' / 'hyperopt_tickerdata.pkl')
|
'hyperopt_results' / 'hyperopt_tickerdata.pkl')
|
||||||
self.total_epochs = config.get('epochs', 0)
|
self.total_epochs = config.get('epochs', 0)
|
||||||
|
|
||||||
self.current_best_loss = 100
|
self.current_best_loss = 100
|
||||||
|
|
||||||
if not self.config.get('hyperopt_continue'):
|
self.clean_hyperopt()
|
||||||
self.clean_hyperopt()
|
|
||||||
else:
|
|
||||||
logger.info("Continuing on previous hyperopt results.")
|
|
||||||
|
|
||||||
self.num_epochs_saved = 0
|
self.num_epochs_saved = 0
|
||||||
|
|
||||||
@ -163,6 +161,9 @@ class Hyperopt:
|
|||||||
self.num_epochs_saved = num_epochs
|
self.num_epochs_saved = num_epochs
|
||||||
logger.debug(f"{self.num_epochs_saved} {plural(self.num_epochs_saved, 'epoch')} "
|
logger.debug(f"{self.num_epochs_saved} {plural(self.num_epochs_saved, 'epoch')} "
|
||||||
f"saved to '{self.results_file}'.")
|
f"saved to '{self.results_file}'.")
|
||||||
|
# Store hyperopt filename
|
||||||
|
latest_filename = Path.joinpath(self.results_file.parent, LAST_BT_RESULT_FN)
|
||||||
|
file_dump_json(latest_filename, {'latest_hyperopt': str(self.results_file.name)})
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _read_results(results_file: Path) -> List:
|
def _read_results(results_file: Path) -> List:
|
||||||
@ -655,8 +656,6 @@ class Hyperopt:
|
|||||||
self.backtesting.strategy.dp = None # type: ignore
|
self.backtesting.strategy.dp = None # type: ignore
|
||||||
IStrategy.dp = None # type: ignore
|
IStrategy.dp = None # type: ignore
|
||||||
|
|
||||||
self.epochs = self.load_previous_results(self.results_file)
|
|
||||||
|
|
||||||
cpus = cpu_count()
|
cpus = cpu_count()
|
||||||
logger.info(f"Found {cpus} CPU cores. Let's make them scream!")
|
logger.info(f"Found {cpus} CPU cores. Let's make them scream!")
|
||||||
config_jobs = self.config.get('hyperopt_jobs', -1)
|
config_jobs = self.config.get('hyperopt_jobs', -1)
|
||||||
|
@ -11,7 +11,8 @@ from freqtrade.data.btanalysis import (BT_DATA_COLUMNS, analyze_trade_parallelis
|
|||||||
calculate_market_change, calculate_max_drawdown,
|
calculate_market_change, calculate_max_drawdown,
|
||||||
combine_dataframes_with_mean, create_cum_profit,
|
combine_dataframes_with_mean, create_cum_profit,
|
||||||
extract_trades_of_period, get_latest_backtest_filename,
|
extract_trades_of_period, get_latest_backtest_filename,
|
||||||
load_backtest_data, load_trades, load_trades_from_db)
|
get_latest_hyperopt_file, load_backtest_data, load_trades,
|
||||||
|
load_trades_from_db)
|
||||||
from freqtrade.data.history import load_data, load_pair_history
|
from freqtrade.data.history import load_data, load_pair_history
|
||||||
from freqtrade.optimize.backtesting import BacktestResult
|
from freqtrade.optimize.backtesting import BacktestResult
|
||||||
from tests.conftest import create_mock_trades
|
from tests.conftest import create_mock_trades
|
||||||
@ -38,6 +39,17 @@ def test_get_latest_backtest_filename(testdatadir, mocker):
|
|||||||
get_latest_backtest_filename(testdatadir)
|
get_latest_backtest_filename(testdatadir)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_latest_hyperopt_file(testdatadir, mocker):
|
||||||
|
res = get_latest_hyperopt_file(testdatadir / 'does_not_exist', 'testfile.pickle')
|
||||||
|
assert res == testdatadir / 'does_not_exist/testfile.pickle'
|
||||||
|
|
||||||
|
res = get_latest_hyperopt_file(testdatadir.parent)
|
||||||
|
assert res == testdatadir.parent / "hyperopt_results.pickle"
|
||||||
|
|
||||||
|
res = get_latest_hyperopt_file(str(testdatadir.parent))
|
||||||
|
assert res == testdatadir.parent / "hyperopt_results.pickle"
|
||||||
|
|
||||||
|
|
||||||
def test_load_backtest_data_old_format(testdatadir):
|
def test_load_backtest_data_old_format(testdatadir):
|
||||||
|
|
||||||
filename = testdatadir / "backtest-result_test.json"
|
filename = testdatadir / "backtest-result_test.json"
|
||||||
|
@ -5,7 +5,7 @@ from copy import deepcopy
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict, List
|
from typing import Dict, List
|
||||||
from unittest.mock import MagicMock, PropertyMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pytest
|
import pytest
|
||||||
@ -79,13 +79,14 @@ def create_results(mocker, hyperopt, testdatadir) -> List[Dict]:
|
|||||||
|
|
||||||
mocker.patch.object(Path, "is_file", MagicMock(return_value=False))
|
mocker.patch.object(Path, "is_file", MagicMock(return_value=False))
|
||||||
stat_mock = MagicMock()
|
stat_mock = MagicMock()
|
||||||
stat_mock.st_size = PropertyMock(return_value=1)
|
stat_mock.st_size = 1
|
||||||
mocker.patch.object(Path, "stat", MagicMock(return_value=False))
|
mocker.patch.object(Path, "stat", MagicMock(return_value=stat_mock))
|
||||||
|
|
||||||
mocker.patch.object(Path, "unlink", MagicMock(return_value=True))
|
mocker.patch.object(Path, "unlink", MagicMock(return_value=True))
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.dump', return_value=None)
|
mocker.patch('freqtrade.optimize.hyperopt.dump', return_value=None)
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
|
|
||||||
return [{'loss': 1, 'result': 'foo', 'params': {}}]
|
return [{'loss': 1, 'result': 'foo', 'params': {}, 'is_best': True}]
|
||||||
|
|
||||||
|
|
||||||
def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
@ -495,6 +496,7 @@ def test_no_log_if_loss_does_not_improve(hyperopt, caplog) -> None:
|
|||||||
def test_save_results_saves_epochs(mocker, hyperopt, testdatadir, caplog) -> None:
|
def test_save_results_saves_epochs(mocker, hyperopt, testdatadir, caplog) -> None:
|
||||||
epochs = create_results(mocker, hyperopt, testdatadir)
|
epochs = create_results(mocker, hyperopt, testdatadir)
|
||||||
mock_dump = mocker.patch('freqtrade.optimize.hyperopt.dump', return_value=None)
|
mock_dump = mocker.patch('freqtrade.optimize.hyperopt.dump', return_value=None)
|
||||||
|
mock_dump_json = mocker.patch('freqtrade.optimize.hyperopt.file_dump_json', return_value=None)
|
||||||
results_file = testdatadir / 'optimize' / 'ut_results.pickle'
|
results_file = testdatadir / 'optimize' / 'ut_results.pickle'
|
||||||
|
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
@ -503,6 +505,7 @@ def test_save_results_saves_epochs(mocker, hyperopt, testdatadir, caplog) -> Non
|
|||||||
hyperopt._save_results()
|
hyperopt._save_results()
|
||||||
assert log_has(f"1 epoch saved to '{results_file}'.", caplog)
|
assert log_has(f"1 epoch saved to '{results_file}'.", caplog)
|
||||||
mock_dump.assert_called_once()
|
mock_dump.assert_called_once()
|
||||||
|
mock_dump_json.assert_called_once()
|
||||||
|
|
||||||
hyperopt.epochs = epochs + epochs
|
hyperopt.epochs = epochs + epochs
|
||||||
hyperopt._save_results()
|
hyperopt._save_results()
|
||||||
@ -519,6 +522,28 @@ def test_read_results_returns_epochs(mocker, hyperopt, testdatadir, caplog) -> N
|
|||||||
mock_load.assert_called_once()
|
mock_load.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
def test_load_previous_results(mocker, hyperopt, testdatadir, caplog) -> None:
|
||||||
|
epochs = create_results(mocker, hyperopt, testdatadir)
|
||||||
|
mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=epochs)
|
||||||
|
mocker.patch.object(Path, 'is_file', MagicMock(return_value=True))
|
||||||
|
statmock = MagicMock()
|
||||||
|
statmock.st_size = 5
|
||||||
|
# mocker.patch.object(Path, 'stat', MagicMock(return_value=statmock))
|
||||||
|
|
||||||
|
results_file = testdatadir / 'optimize' / 'ut_results.pickle'
|
||||||
|
|
||||||
|
hyperopt_epochs = hyperopt.load_previous_results(results_file)
|
||||||
|
|
||||||
|
assert hyperopt_epochs == epochs
|
||||||
|
mock_load.assert_called_once()
|
||||||
|
|
||||||
|
del epochs[0]['is_best']
|
||||||
|
mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=epochs)
|
||||||
|
|
||||||
|
with pytest.raises(OperationalException):
|
||||||
|
hyperopt.load_previous_results(results_file)
|
||||||
|
|
||||||
|
|
||||||
def test_roi_table_generation(hyperopt) -> None:
|
def test_roi_table_generation(hyperopt) -> None:
|
||||||
params = {
|
params = {
|
||||||
'roi_t1': 5,
|
'roi_t1': 5,
|
||||||
@ -534,6 +559,8 @@ def test_roi_table_generation(hyperopt) -> None:
|
|||||||
|
|
||||||
def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None:
|
def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
|
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -837,19 +864,10 @@ def test_clean_hyperopt(mocker, hyperopt_conf, caplog):
|
|||||||
assert log_has(f"Removing `{h.data_pickle_file}`.", caplog)
|
assert log_has(f"Removing `{h.data_pickle_file}`.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_continue_hyperopt(mocker, hyperopt_conf, caplog):
|
|
||||||
patch_exchange(mocker)
|
|
||||||
hyperopt_conf.update({'hyperopt_continue': True})
|
|
||||||
mocker.patch("freqtrade.optimize.hyperopt.Path.is_file", MagicMock(return_value=True))
|
|
||||||
unlinkmock = mocker.patch("freqtrade.optimize.hyperopt.Path.unlink", MagicMock())
|
|
||||||
Hyperopt(hyperopt_conf)
|
|
||||||
|
|
||||||
assert unlinkmock.call_count == 0
|
|
||||||
assert log_has("Continuing on previous hyperopt results.", caplog)
|
|
||||||
|
|
||||||
|
|
||||||
def test_print_json_spaces_all(mocker, hyperopt_conf, capsys) -> None:
|
def test_print_json_spaces_all(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
|
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -905,6 +923,7 @@ def test_print_json_spaces_all(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
|
|
||||||
def test_print_json_spaces_default(mocker, hyperopt_conf, capsys) -> None:
|
def test_print_json_spaces_default(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -952,6 +971,7 @@ def test_print_json_spaces_default(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
|
|
||||||
def test_print_json_spaces_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
def test_print_json_spaces_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -998,6 +1018,7 @@ def test_print_json_spaces_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
|
|
||||||
def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -1050,6 +1071,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non
|
|||||||
|
|
||||||
def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -1076,6 +1098,7 @@ def test_simplified_interface_all_failed(mocker, hyperopt_conf) -> None:
|
|||||||
|
|
||||||
def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -1128,6 +1151,7 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
|
|
||||||
def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
||||||
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
dumper = mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
@ -1186,6 +1210,7 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
])
|
])
|
||||||
def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> None:
|
def test_simplified_interface_failed(mocker, hyperopt_conf, method, space) -> None:
|
||||||
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
mocker.patch('freqtrade.optimize.hyperopt.dump', MagicMock())
|
||||||
|
mocker.patch('freqtrade.optimize.hyperopt.file_dump_json')
|
||||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
mocker.patch('freqtrade.optimize.backtesting.Backtesting.load_bt_data',
|
||||||
MagicMock(return_value=(MagicMock(), None)))
|
MagicMock(return_value=(MagicMock(), None)))
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
|
@ -1138,9 +1138,9 @@ def test_telegram_logs(default_conf, update, mocker) -> None:
|
|||||||
context = MagicMock()
|
context = MagicMock()
|
||||||
context.args = []
|
context.args = []
|
||||||
telegram._logs(update=update, context=context)
|
telegram._logs(update=update, context=context)
|
||||||
# Called at least 3 times. Exact times will change with unrelated changes to setup messages
|
# Called at least 2 times. Exact times will change with unrelated changes to setup messages
|
||||||
# Therefore we don't test for this explicitly.
|
# Therefore we don't test for this explicitly.
|
||||||
assert msg_mock.call_count > 3
|
assert msg_mock.call_count >= 2
|
||||||
|
|
||||||
|
|
||||||
def test_edge_disabled(default_conf, update, mocker) -> None:
|
def test_edge_disabled(default_conf, update, mocker) -> None:
|
||||||
|
Loading…
Reference in New Issue
Block a user