Add --analyze-per-epoch - moving populate_analysis to the epoch process

This commit is contained in:
Matthias 2022-08-19 15:19:43 +02:00
parent 09f8904545
commit bc359675a2
6 changed files with 48 additions and 12 deletions

View File

@ -40,7 +40,8 @@ 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]
[--recursive-strategy-search] [-i TIMEFRAME]
[--recursive-strategy-search] [--freqaimodel NAME]
[--freqaimodel-path PATH] [-i TIMEFRAME]
[--timerange TIMERANGE]
[--data-format-ohlcv {json,jsongz,hdf5}]
[--max-open-trades INT]
@ -53,7 +54,7 @@ usage: freqtrade hyperopt [-h] [-v] [--logfile FILE] [-V] [-c PATH] [-d PATH]
[--print-all] [--no-color] [--print-json] [-j JOBS]
[--random-state INT] [--min-trades INT]
[--hyperopt-loss NAME] [--disable-param-export]
[--ignore-missing-spaces]
[--ignore-missing-spaces] [--analyze-per-epoch]
optional arguments:
-h, --help show this help message and exit
@ -129,6 +130,7 @@ optional arguments:
--ignore-missing-spaces, --ignore-unparameterized-spaces
Suppress errors for any requested Hyperopt spaces that
do not contain any parameters.
--analyze-per-epoch Run populate_indicators once per epoch.
Common arguments:
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
@ -154,6 +156,10 @@ Strategy arguments:
--recursive-strategy-search
Recursively search for a strategy in the strategies
folder.
--freqaimodel NAME Specify a custom freqaimodels.
--freqaimodel-path PATH
Specify additional lookup path for freqaimodels.
```
### Hyperopt checklist

View File

@ -34,7 +34,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
"print_colorized", "print_json", "hyperopt_jobs",
"hyperopt_random_state", "hyperopt_min_trades",
"hyperopt_loss", "disableparamexport",
"hyperopt_ignore_missing_space"]
"hyperopt_ignore_missing_space", "analyze_per_epoch"]
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]

View File

@ -255,6 +255,13 @@ AVAILABLE_CLI_OPTIONS = {
nargs='+',
default='default',
),
"analyze_per_epoch": Arg(
'--analyze-per-epoch',
help='Run populate_indicators once per epoch.',
action='store_true',
default=False,
),
"print_all": Arg(
'--print-all',
help='Print all results, not only the best ones.',

View File

@ -302,6 +302,9 @@ class Configuration:
self._args_to_config(config, argname='spaces',
logstring='Parameter -s/--spaces detected: {}')
self._args_to_config(config, argname='analyze_per_epoch',
logstring='Parameter --analyze-per-epoch detected.')
self._args_to_config(config, argname='print_all',
logstring='Parameter --print-all detected ...')

View File

@ -24,13 +24,15 @@ from pandas import DataFrame
from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN
from freqtrade.data.converter import trim_dataframes
from freqtrade.data.history import get_timerange
from freqtrade.enums import HyperoptState
from freqtrade.exceptions import OperationalException
from freqtrade.misc import deep_merge_dicts, file_dump_json, plural
from freqtrade.optimize.backtesting import Backtesting
# Import IHyperOpt and IHyperOptLoss to allow unpickling classes from these modules
from freqtrade.optimize.hyperopt_auto import HyperOptAuto
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss
from freqtrade.optimize.hyperopt_tools import HyperoptTools, hyperopt_serializer
from freqtrade.optimize.hyperopt_tools import (HyperoptStateContainer, HyperoptTools,
hyperopt_serializer)
from freqtrade.optimize.optimize_reports import generate_strategy_stats
from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver
@ -74,10 +76,14 @@ class Hyperopt:
self.dimensions: List[Dimension] = []
self.config = config
self.min_date: datetime
self.max_date: datetime
self.backtesting = Backtesting(self.config)
self.pairlist = self.backtesting.pairlists.whitelist
self.custom_hyperopt: HyperOptAuto
self.analyze_per_epoch = self.config.get('analyze_per_epoch', False)
HyperoptStateContainer.set_state(HyperoptState.STARTUP)
if not self.config.get('hyperopt'):
self.custom_hyperopt = HyperOptAuto(self.config)
@ -290,6 +296,7 @@ class Hyperopt:
Called once per epoch to optimize whatever is configured.
Keep this function as optimized as possible!
"""
HyperoptStateContainer.set_state(HyperoptState.OPTIMIZE)
backtest_start_time = datetime.now(timezone.utc)
params_dict = self._get_params_dict(self.dimensions, raw_params)
@ -321,6 +328,10 @@ class Hyperopt:
with self.data_pickle_file.open('rb') as f:
processed = load(f, mmap_mode='r')
if self.analyze_per_epoch:
# Data is not yet analyzed, rerun populate_indicators.
processed = self.advise_and_trim(processed)
bt_results = self.backtesting.backtest(
processed=processed,
start_date=self.min_date,
@ -415,19 +426,24 @@ class Hyperopt:
return processed
def prepare_hyperopt_data(self) -> None:
data, timerange = self.backtesting.load_bt_data()
HyperoptStateContainer.set_state(HyperoptState.DATALOAD)
data, self.timerange = self.backtesting.load_bt_data()
self.backtesting.load_bt_data_detail()
logger.info("Dataload complete. Calculating indicators")
preprocessed = self.backtesting.strategy.advise_all_indicators(data)
if not self.analyze_per_epoch:
HyperoptStateContainer.set_state(HyperoptState.INDICATORS)
preprocessed = self.advise_and_trim(data)
preprocessed = self.advise_and_trim(data)
logger.info(f'Hyperopting with data from {self.min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {self.max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(self.max_date - self.min_date).days} days)..')
# Store non-trimmed data - will be trimmed after signal generation.
dump(preprocessed, self.data_pickle_file)
logger.info(f'Hyperopting with data from '
f'{self.min_date.strftime(DATETIME_PRINT_FORMAT)} '
f'up to {self.max_date.strftime(DATETIME_PRINT_FORMAT)} '
f'({(self.max_date - self.min_date).days} days)..')
# Store non-trimmed data - will be trimmed after signal generation.
dump(preprocessed, self.data_pickle_file)
else:
dump(data, self.data_pickle_file)
def get_asked_points(self, n_points: int) -> Tuple[List[List[Any]], List[bool]]:
"""

View File

@ -7,6 +7,9 @@ from abc import ABC, abstractmethod
from contextlib import suppress
from typing import Any, Optional, Sequence, Union
from freqtrade.enums.hyperoptstate import HyperoptState
from freqtrade.optimize.hyperopt_tools import HyperoptStateContainer
with suppress(ImportError):
from skopt.space import Integer, Real, Categorical
@ -61,6 +64,7 @@ class BaseParameter(ABC):
return (
self.in_space
and self.optimize
and HyperoptStateContainer.state != HyperoptState.OPTIMIZE
)