freqtrade/optimize/hyperopt_epoch_filters.py
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