From 9a3ada65f55c53dc068786a383a1a1000c205e10 Mon Sep 17 00:00:00 2001 From: mrpabloyeah Date: Tue, 8 Apr 2025 23:12:51 +0200 Subject: [PATCH] Complete the integration on freqtrade --- docs/commands/hyperopt.md | 1 + docs/hyperopt.md | 1 + tests/optimize/test_hyperoptloss.py | 52 +++++++++++++++++++++++++++-- 3 files changed, 51 insertions(+), 3 deletions(-) diff --git a/docs/commands/hyperopt.md b/docs/commands/hyperopt.md index 2fc522d0f..28ad45dd2 100644 --- a/docs/commands/hyperopt.md +++ b/docs/commands/hyperopt.md @@ -79,6 +79,7 @@ options: SortinoHyperOptLoss, SortinoHyperOptLossDaily, CalmarHyperOptLoss, MaxDrawDownHyperOptLoss, MaxDrawDownRelativeHyperOptLoss, + MaxDrawDownPerPairHyperOptLoss, ProfitDrawDownHyperOptLoss, MultiMetricHyperOptLoss --disable-param-export Disable automatic hyperopt parameter export. diff --git a/docs/hyperopt.md b/docs/hyperopt.md index 51a6a5187..89708486d 100644 --- a/docs/hyperopt.md +++ b/docs/hyperopt.md @@ -471,6 +471,7 @@ Currently, the following loss functions are builtin: * `SortinoHyperOptLossDaily` - optimizes Sortino Ratio calculated on **daily** trade returns relative to **downside** standard deviation. * `MaxDrawDownHyperOptLoss` - Optimizes Maximum absolute drawdown. * `MaxDrawDownRelativeHyperOptLoss` - Optimizes both maximum absolute drawdown while also adjusting for maximum relative drawdown. +* `MaxDrawDownPerPairHyperOptLoss` - Optimizes the profit/drawdown ratio calculated individually for each pair in the pairlist. * `CalmarHyperOptLoss` - Optimizes Calmar Ratio calculated on trade returns relative to max drawdown. * `ProfitDrawDownHyperOptLoss` - Optimizes by max Profit & min Drawdown objective. `DRAWDOWN_MULT` variable within the hyperoptloss file can be adjusted to be stricter or more flexible on drawdown purposes. * `MultiMetricHyperOptLoss` - Optimizes by several key metrics to achieve balanced performance. The primary focus is on maximizing Profit and minimizing Drawdown, while also considering additional metrics such as Profit Factor, Expectancy Ratio and Winrate. Moreover, it applies a penalty for epochs with a low number of trades, encouraging strategies with adequate trade frequency. diff --git a/tests/optimize/test_hyperoptloss.py b/tests/optimize/test_hyperoptloss.py index 8f1b1c786..7a356ace9 100644 --- a/tests/optimize/test_hyperoptloss.py +++ b/tests/optimize/test_hyperoptloss.py @@ -153,6 +153,7 @@ def test_loss_calculation_has_limited_profit(hyperopt_conf, hyperopt_results) -> "SharpeHyperOptLossDaily", "MaxDrawDownHyperOptLoss", "MaxDrawDownRelativeHyperOptLoss", + "MaxDrawDownPerPairHyperOptLoss", "CalmarHyperOptLoss", "ProfitDrawDownHyperOptLoss", "MultiMetricHyperOptLoss", @@ -165,6 +166,42 @@ def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunct results_under = hyperopt_results.copy() results_under["profit_abs"] = hyperopt_results["profit_abs"] / 2 - 0.2 results_under["profit_ratio"] = hyperopt_results["profit_ratio"] / 2 + pair_results = [ + { + "key": "ETH/USDT", + "max_drawdown_abs": 50.0, + "profit_total_abs": 100.0, + }, + { + "key": "BTC/USDT", + "max_drawdown_abs": 50.0, + "profit_total_abs": 100.0, + } + ] + pair_results_over = [ + { + "key": "ETH/USDT", + "max_drawdown_abs": 25.0, + "profit_total_abs": 200.0, + }, + { + "key": "BTC/USDT", + "max_drawdown_abs": 25.0, + "profit_total_abs": 200.0, + } + ] + pair_results_under = [ + { + "key": "ETH/USDT", + "max_drawdown_abs": 100.0, + "profit_total_abs": 50.0, + }, + { + "key": "BTC/USDT", + "max_drawdown_abs": 100.0, + "profit_total_abs": 50.0, + } + ] default_conf.update({"hyperopt_loss": lossfunction}) hl = HyperOptLossResolver.load_hyperoptloss(default_conf) @@ -175,7 +212,10 @@ def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunct max_date=datetime(2019, 5, 1), config=default_conf, processed=None, - backtest_stats={"profit_total": hyperopt_results["profit_abs"].sum()}, + backtest_stats={ + "profit_total": hyperopt_results["profit_abs"].sum(), + "results_per_pair": pair_results, + }, starting_balance=default_conf["dry_run_wallet"], ) over = hl.hyperopt_loss_function( @@ -185,7 +225,10 @@ def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunct max_date=datetime(2019, 5, 1), config=default_conf, processed=None, - backtest_stats={"profit_total": results_over["profit_abs"].sum()}, + backtest_stats={ + "profit_total": results_over["profit_abs"].sum(), + "results_per_pair": pair_results_over, + }, starting_balance=default_conf["dry_run_wallet"], ) under = hl.hyperopt_loss_function( @@ -195,7 +238,10 @@ def test_loss_functions_better_profits(default_conf, hyperopt_results, lossfunct max_date=datetime(2019, 5, 1), config=default_conf, processed=None, - backtest_stats={"profit_total": results_under["profit_abs"].sum()}, + backtest_stats={ + "profit_total": results_under["profit_abs"].sum(), + "results_per_pair": pair_results_under, + }, starting_balance=default_conf["dry_run_wallet"], ) assert over < correct