Add --analyze-per-epoch - moving populate_analysis to the epoch process
This commit is contained in:
parent
09f8904545
commit
bc359675a2
@ -40,7 +40,8 @@ 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]
|
||||||
[--recursive-strategy-search] [-i TIMEFRAME]
|
[--recursive-strategy-search] [--freqaimodel NAME]
|
||||||
|
[--freqaimodel-path PATH] [-i TIMEFRAME]
|
||||||
[--timerange TIMERANGE]
|
[--timerange TIMERANGE]
|
||||||
[--data-format-ohlcv {json,jsongz,hdf5}]
|
[--data-format-ohlcv {json,jsongz,hdf5}]
|
||||||
[--max-open-trades INT]
|
[--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]
|
[--print-all] [--no-color] [--print-json] [-j JOBS]
|
||||||
[--random-state INT] [--min-trades INT]
|
[--random-state INT] [--min-trades INT]
|
||||||
[--hyperopt-loss NAME] [--disable-param-export]
|
[--hyperopt-loss NAME] [--disable-param-export]
|
||||||
[--ignore-missing-spaces]
|
[--ignore-missing-spaces] [--analyze-per-epoch]
|
||||||
|
|
||||||
optional arguments:
|
optional arguments:
|
||||||
-h, --help show this help message and exit
|
-h, --help show this help message and exit
|
||||||
@ -129,6 +130,7 @@ optional arguments:
|
|||||||
--ignore-missing-spaces, --ignore-unparameterized-spaces
|
--ignore-missing-spaces, --ignore-unparameterized-spaces
|
||||||
Suppress errors for any requested Hyperopt spaces that
|
Suppress errors for any requested Hyperopt spaces that
|
||||||
do not contain any parameters.
|
do not contain any parameters.
|
||||||
|
--analyze-per-epoch Run populate_indicators once per epoch.
|
||||||
|
|
||||||
Common arguments:
|
Common arguments:
|
||||||
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
-v, --verbose Verbose mode (-vv for more, -vvv to get all messages).
|
||||||
@ -154,6 +156,10 @@ Strategy arguments:
|
|||||||
--recursive-strategy-search
|
--recursive-strategy-search
|
||||||
Recursively search for a strategy in the strategies
|
Recursively search for a strategy in the strategies
|
||||||
folder.
|
folder.
|
||||||
|
--freqaimodel NAME Specify a custom freqaimodels.
|
||||||
|
--freqaimodel-path PATH
|
||||||
|
Specify additional lookup path for freqaimodels.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Hyperopt checklist
|
### Hyperopt checklist
|
||||||
|
@ -34,7 +34,7 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "hyperopt_path",
|
|||||||
"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_loss", "disableparamexport",
|
"hyperopt_loss", "disableparamexport",
|
||||||
"hyperopt_ignore_missing_space"]
|
"hyperopt_ignore_missing_space", "analyze_per_epoch"]
|
||||||
|
|
||||||
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
|
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
|
||||||
|
|
||||||
|
@ -255,6 +255,13 @@ AVAILABLE_CLI_OPTIONS = {
|
|||||||
nargs='+',
|
nargs='+',
|
||||||
default='default',
|
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": Arg(
|
||||||
'--print-all',
|
'--print-all',
|
||||||
help='Print all results, not only the best ones.',
|
help='Print all results, not only the best ones.',
|
||||||
|
@ -302,6 +302,9 @@ class Configuration:
|
|||||||
self._args_to_config(config, argname='spaces',
|
self._args_to_config(config, argname='spaces',
|
||||||
logstring='Parameter -s/--spaces detected: {}')
|
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',
|
self._args_to_config(config, argname='print_all',
|
||||||
logstring='Parameter --print-all detected ...')
|
logstring='Parameter --print-all detected ...')
|
||||||
|
|
||||||
|
@ -24,13 +24,15 @@ from pandas import DataFrame
|
|||||||
from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN
|
from freqtrade.constants import DATETIME_PRINT_FORMAT, FTHYPT_FILEVERSION, LAST_BT_RESULT_FN
|
||||||
from freqtrade.data.converter import trim_dataframes
|
from freqtrade.data.converter import trim_dataframes
|
||||||
from freqtrade.data.history import get_timerange
|
from freqtrade.data.history import get_timerange
|
||||||
|
from freqtrade.enums import HyperoptState
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
from freqtrade.misc import deep_merge_dicts, file_dump_json, plural
|
from freqtrade.misc import deep_merge_dicts, file_dump_json, plural
|
||||||
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_auto import HyperOptAuto
|
from freqtrade.optimize.hyperopt_auto import HyperOptAuto
|
||||||
from freqtrade.optimize.hyperopt_loss_interface import IHyperOptLoss
|
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.optimize.optimize_reports import generate_strategy_stats
|
||||||
from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver
|
from freqtrade.resolvers.hyperopt_resolver import HyperOptLossResolver
|
||||||
|
|
||||||
@ -74,10 +76,14 @@ class Hyperopt:
|
|||||||
self.dimensions: List[Dimension] = []
|
self.dimensions: List[Dimension] = []
|
||||||
|
|
||||||
self.config = config
|
self.config = config
|
||||||
|
self.min_date: datetime
|
||||||
|
self.max_date: datetime
|
||||||
|
|
||||||
self.backtesting = Backtesting(self.config)
|
self.backtesting = Backtesting(self.config)
|
||||||
self.pairlist = self.backtesting.pairlists.whitelist
|
self.pairlist = self.backtesting.pairlists.whitelist
|
||||||
self.custom_hyperopt: HyperOptAuto
|
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'):
|
if not self.config.get('hyperopt'):
|
||||||
self.custom_hyperopt = HyperOptAuto(self.config)
|
self.custom_hyperopt = HyperOptAuto(self.config)
|
||||||
@ -290,6 +296,7 @@ class Hyperopt:
|
|||||||
Called once per epoch to optimize whatever is configured.
|
Called once per epoch to optimize whatever is configured.
|
||||||
Keep this function as optimized as possible!
|
Keep this function as optimized as possible!
|
||||||
"""
|
"""
|
||||||
|
HyperoptStateContainer.set_state(HyperoptState.OPTIMIZE)
|
||||||
backtest_start_time = datetime.now(timezone.utc)
|
backtest_start_time = datetime.now(timezone.utc)
|
||||||
params_dict = self._get_params_dict(self.dimensions, raw_params)
|
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:
|
with self.data_pickle_file.open('rb') as f:
|
||||||
processed = load(f, mmap_mode='r')
|
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(
|
bt_results = self.backtesting.backtest(
|
||||||
processed=processed,
|
processed=processed,
|
||||||
start_date=self.min_date,
|
start_date=self.min_date,
|
||||||
@ -415,19 +426,24 @@ class Hyperopt:
|
|||||||
return processed
|
return processed
|
||||||
|
|
||||||
def prepare_hyperopt_data(self) -> None:
|
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()
|
self.backtesting.load_bt_data_detail()
|
||||||
logger.info("Dataload complete. Calculating indicators")
|
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)} '
|
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'up to {self.max_date.strftime(DATETIME_PRINT_FORMAT)} '
|
||||||
f'({(self.max_date - self.min_date).days} days)..')
|
f'({(self.max_date - self.min_date).days} days)..')
|
||||||
# Store non-trimmed data - will be trimmed after signal generation.
|
# Store non-trimmed data - will be trimmed after signal generation.
|
||||||
dump(preprocessed, self.data_pickle_file)
|
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]]:
|
def get_asked_points(self, n_points: int) -> Tuple[List[List[Any]], List[bool]]:
|
||||||
"""
|
"""
|
||||||
|
@ -7,6 +7,9 @@ from abc import ABC, abstractmethod
|
|||||||
from contextlib import suppress
|
from contextlib import suppress
|
||||||
from typing import Any, Optional, Sequence, Union
|
from typing import Any, Optional, Sequence, Union
|
||||||
|
|
||||||
|
from freqtrade.enums.hyperoptstate import HyperoptState
|
||||||
|
from freqtrade.optimize.hyperopt_tools import HyperoptStateContainer
|
||||||
|
|
||||||
|
|
||||||
with suppress(ImportError):
|
with suppress(ImportError):
|
||||||
from skopt.space import Integer, Real, Categorical
|
from skopt.space import Integer, Real, Categorical
|
||||||
@ -61,6 +64,7 @@ class BaseParameter(ABC):
|
|||||||
return (
|
return (
|
||||||
self.in_space
|
self.in_space
|
||||||
and self.optimize
|
and self.optimize
|
||||||
|
and HyperoptStateContainer.state != HyperoptState.OPTIMIZE
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user