039d6384ed
Avoiding memory-exhaustion on huge hyperopt results closes #5305 closes #5149
129 lines
4.4 KiB
Python
129 lines
4.4 KiB
Python
import logging
|
|
from typing import List
|
|
|
|
from freqtrade.exceptions import OperationalException
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def hyperopt_filter_epochs(epochs: List, filteroptions: dict, log: bool = True) -> List:
|
|
"""
|
|
Filter our items from the list of hyperopt results
|
|
"""
|
|
if filteroptions['only_best']:
|
|
epochs = [x for x in epochs if x['is_best']]
|
|
if filteroptions['only_profitable']:
|
|
epochs = [x for x in epochs
|
|
if x['results_metrics'].get('profit_total', 0) > 0]
|
|
|
|
epochs = _hyperopt_filter_epochs_trade_count(epochs, filteroptions)
|
|
|
|
epochs = _hyperopt_filter_epochs_duration(epochs, filteroptions)
|
|
|
|
epochs = _hyperopt_filter_epochs_profit(epochs, filteroptions)
|
|
|
|
epochs = _hyperopt_filter_epochs_objective(epochs, filteroptions)
|
|
if log:
|
|
logger.info(f"{len(epochs)} " +
|
|
("best " if filteroptions['only_best'] else "") +
|
|
("profitable " if filteroptions['only_profitable'] else "") +
|
|
"epochs found.")
|
|
return epochs
|
|
|
|
|
|
def _hyperopt_filter_epochs_trade(epochs: List, trade_count: int):
|
|
"""
|
|
Filter epochs with trade-counts > trades
|
|
"""
|
|
return [
|
|
x for x in epochs if x['results_metrics'].get('total_trades', 0) > trade_count
|
|
]
|
|
|
|
|
|
def _hyperopt_filter_epochs_trade_count(epochs: List, filteroptions: dict) -> List:
|
|
|
|
if filteroptions['filter_min_trades'] > 0:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, filteroptions['filter_min_trades'])
|
|
|
|
if filteroptions['filter_max_trades'] > 0:
|
|
epochs = [
|
|
x for x in epochs
|
|
if x['results_metrics'].get('total_trades') < filteroptions['filter_max_trades']
|
|
]
|
|
return epochs
|
|
|
|
|
|
def _hyperopt_filter_epochs_duration(epochs: List, filteroptions: dict) -> List:
|
|
|
|
def get_duration_value(x):
|
|
# Duration in minutes ...
|
|
if 'holding_avg_s' in x['results_metrics']:
|
|
avg = x['results_metrics']['holding_avg_s']
|
|
return avg // 60
|
|
raise OperationalException(
|
|
"Holding-average not available. Please omit the filter on average time, "
|
|
"or rerun hyperopt with this version")
|
|
|
|
if filteroptions['filter_min_avg_time'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if get_duration_value(x) > filteroptions['filter_min_avg_time']
|
|
]
|
|
if filteroptions['filter_max_avg_time'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if get_duration_value(x) < filteroptions['filter_max_avg_time']
|
|
]
|
|
|
|
return epochs
|
|
|
|
|
|
def _hyperopt_filter_epochs_profit(epochs: List, filteroptions: dict) -> List:
|
|
|
|
if filteroptions['filter_min_avg_profit'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if x['results_metrics'].get('profit_mean', 0) * 100
|
|
> filteroptions['filter_min_avg_profit']
|
|
]
|
|
if filteroptions['filter_max_avg_profit'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if x['results_metrics'].get('profit_mean', 0) * 100
|
|
< filteroptions['filter_max_avg_profit']
|
|
]
|
|
if filteroptions['filter_min_total_profit'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if x['results_metrics'].get('profit_total_abs', 0)
|
|
> filteroptions['filter_min_total_profit']
|
|
]
|
|
if filteroptions['filter_max_total_profit'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
epochs = [
|
|
x for x in epochs
|
|
if x['results_metrics'].get('profit_total_abs', 0)
|
|
< filteroptions['filter_max_total_profit']
|
|
]
|
|
return epochs
|
|
|
|
|
|
def _hyperopt_filter_epochs_objective(epochs: List, filteroptions: dict) -> List:
|
|
|
|
if filteroptions['filter_min_objective'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
|
|
epochs = [x for x in epochs if x['loss'] < filteroptions['filter_min_objective']]
|
|
if filteroptions['filter_max_objective'] is not None:
|
|
epochs = _hyperopt_filter_epochs_trade(epochs, 0)
|
|
|
|
epochs = [x for x in epochs if x['loss'] > filteroptions['filter_max_objective']]
|
|
|
|
return epochs
|