From: Jérôme Benoit Date: Mon, 1 Dec 2025 13:13:03 +0000 (+0100) Subject: feat(qav3): add configuration section for protections X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=6f119b647a8992756f6754265920f77440494b75;p=freqai-strategies.git feat(qav3): add configuration section for protections Signed-off-by: Jérôme Benoit --- diff --git a/README.md b/README.md index cce3d88..65ac4b2 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,13 @@ docker compose up -d --build | Path | Default | Type / Range | Description | | ---------------------------------------------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | _Protections_ | | | | -| estimated_trade_duration_candles | 48 | int >= 1 | Heuristic for StoplossGuard tuning. | +| custom_protections.trade_duration_candles | 72 | int >= 1 | Estimated trade duration in candles. Scales protections stop duration candles and trade limit. | +| custom_protections.lookback_period_fraction | 0.5 | float (0,1] | Fraction of fit_live_predictions_candles used to calculate lookback_period_candles for MaxDrawdown and StoplossGuard protections. | +| custom_protections.cooldown.enabled | true | bool | Enable/disable CooldownPeriod protection. | +| custom_protections.cooldown.stop_duration_candles | 4 | int >= 1 | Number of candles to wait before allowing new trades after a trade is closed. | +| custom_protections.drawdown.enabled | true | bool | Enable/disable MaxDrawdown protection. | +| custom_protections.drawdown.max_allowed_drawdown | 0.2 | float (0,1) | Maximum allowed drawdown. | +| custom_protections.stoploss.enabled | true | bool | Enable/disable StoplossGuard protection. | | _Leverage_ | | | | | leverage | proposed_leverage | float [1.0, max_leverage] | Leverage. Fallback to proposed_leverage for the pair. | | _Exit pricing_ | | | | @@ -46,7 +52,7 @@ docker compose up -d --build | exit_pricing.thresholds_calibration.decline_quantile | 0.90 | float (0,1) | PnL decline quantile threshold. | | _Reversal confirmation_ | | | | | reversal_confirmation.lookback_period | 0 | int >= 0 | Prior confirming candles; 0 = none. | -| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle relaxation factor. | +| reversal_confirmation.decay_ratio | 0.5 | float (0,1] | Geometric per-candle volatility adjusted reversal threshold relaxation factor. | | reversal_confirmation.min_natr_ratio_percent | 0.01 | float [0,1] | Lower bound fraction for volatility adjusted reversal threshold. | | reversal_confirmation.max_natr_ratio_percent | 0.1 | float [0,1] | Upper bound fraction (>= lower bound) for volatility adjusted reversal threshold. | | _Regressor model_ | | | | diff --git a/quickadapter/user_data/strategies/QuickAdapterV3.py b/quickadapter/user_data/strategies/QuickAdapterV3.py index 671d261..24b95e7 100644 --- a/quickadapter/user_data/strategies/QuickAdapterV3.py +++ b/quickadapter/user_data/strategies/QuickAdapterV3.py @@ -194,54 +194,71 @@ class QuickAdapterV3(IStrategy): fit_live_predictions_candles = int( self.config.get("freqai", {}).get("fit_live_predictions_candles", 100) ) - estimated_trade_duration_candles = int( - self.config.get("estimated_trade_duration_candles", 60) + protections = self.config.get("custom_protections", {}) + trade_duration_candles = int(protections.get("trade_duration_candles", 72)) + lookback_period_fraction = float( + protections.get("lookback_period_fraction", 0.5) ) - lookback_period_candles = max(1, int(round(fit_live_predictions_candles * 0.5))) - cooldown_stop_duration_candles = 4 + lookback_period_candles = max( + 1, int(round(fit_live_predictions_candles * lookback_period_fraction)) + ) + + cooldown = protections.get("cooldown", {}) + cooldown_stop_duration_candles = int(cooldown.get("stop_duration_candles", 4)) stoploss_stop_duration_candles = max( - cooldown_stop_duration_candles, estimated_trade_duration_candles + cooldown_stop_duration_candles, trade_duration_candles ) drawdown_stop_duration_candles = max( - fit_live_predictions_candles, - estimated_trade_duration_candles * 2, stoploss_stop_duration_candles, + fit_live_predictions_candles, ) max_open_trades = int(self.config.get("max_open_trades", 0)) stoploss_trade_limit = min( max( - 1, - int( - round( - lookback_period_candles - / max(1, estimated_trade_duration_candles) - ) - ), + 2, + int(round(lookback_period_candles / max(1, trade_duration_candles))), ), - max(1, int(round(max_open_trades * 0.5))), + max(2, int(round(max_open_trades * 0.75))), ) - return [ - { - "method": "CooldownPeriod", - "stop_duration_candles": cooldown_stop_duration_candles, - }, - { - "method": "MaxDrawdown", - "lookback_period_candles": lookback_period_candles, - "trade_limit": int(round(1.5 * max_open_trades)), - "stop_duration_candles": drawdown_stop_duration_candles, - "max_allowed_drawdown": 0.2, - }, - { - "method": "StoplossGuard", - "lookback_period_candles": lookback_period_candles, - "trade_limit": stoploss_trade_limit, - "stop_duration_candles": stoploss_stop_duration_candles, - "only_per_pair": True, - }, - ] + protections_list = [] + + if cooldown.get("enabled", True): + protections_list.append( + { + "method": "CooldownPeriod", + "stop_duration_candles": cooldown_stop_duration_candles, + } + ) + + drawdown = protections.get("drawdown", {}) + if drawdown.get("enabled", True): + protections_list.append( + { + "method": "MaxDrawdown", + "lookback_period_candles": lookback_period_candles, + "trade_limit": 2 * max_open_trades, + "stop_duration_candles": drawdown_stop_duration_candles, + "max_allowed_drawdown": float( + drawdown.get("max_allowed_drawdown", 0.2) + ), + } + ) + + stoploss = protections.get("stoploss", {}) + if stoploss.get("enabled", True): + protections_list.append( + { + "method": "StoplossGuard", + "lookback_period_candles": lookback_period_candles, + "trade_limit": stoploss_trade_limit, + "stop_duration_candles": stoploss_stop_duration_candles, + "only_per_pair": True, + } + ) + + return protections_list use_exit_signal = True