From 59091ef2b774d5e9cc481e0047dbd8db34967156 Mon Sep 17 00:00:00 2001 From: Matthias Date: Tue, 17 Nov 2020 19:43:12 +0100 Subject: [PATCH] Add helper method to calculate protection until --- freqtrade/freqtradebot.py | 3 +++ freqtrade/plugins/protectionmanager.py | 3 ++- .../plugins/protections/cooldown_period.py | 4 ++-- freqtrade/plugins/protections/iprotection.py | 19 +++++++++++++++++-- .../plugins/protections/low_profit_pairs.py | 4 ++-- .../plugins/protections/stoploss_guard.py | 2 +- 6 files changed, 27 insertions(+), 8 deletions(-) diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 7bfd64c2d..f2ee4d7f0 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -182,6 +182,7 @@ class FreqtradeBot: # Evaluate if protections should apply self.protections.global_stop() + # Then looking for buy opportunities if self.get_free_open_trades(): self.enter_positions() @@ -1416,6 +1417,8 @@ class FreqtradeBot: # Updating wallets when order is closed if not trade.is_open: self.protections.stop_per_pair(trade.pair) + # Evaluate if protections should apply + # self.protections.global_stop() self.wallets.update() return False diff --git a/freqtrade/plugins/protectionmanager.py b/freqtrade/plugins/protectionmanager.py index 64c7208ce..a79447f02 100644 --- a/freqtrade/plugins/protectionmanager.py +++ b/freqtrade/plugins/protectionmanager.py @@ -54,7 +54,8 @@ class ProtectionManager(): # Early stopping - first positive result blocks further trades if result and until: - PairLocks.lock_pair('*', until, reason) + if not PairLocks.is_global_lock(until): + PairLocks.lock_pair('*', until, reason) result = True return result diff --git a/freqtrade/plugins/protections/cooldown_period.py b/freqtrade/plugins/protections/cooldown_period.py index ed618f6d4..56635984b 100644 --- a/freqtrade/plugins/protections/cooldown_period.py +++ b/freqtrade/plugins/protections/cooldown_period.py @@ -42,8 +42,8 @@ class CooldownPeriod(IProtection): trade = Trade.get_trades(filters).first() if trade: self.log_on_refresh(logger.info, f"Cooldown for {pair} for {self._stop_duration}.") - until = trade.close_date.replace( - tzinfo=timezone.utc) + timedelta(minutes=self._stop_duration) + until = self.calculate_lock_end([trade], self._stop_duration) + return True, until, self._reason() return False, None, None diff --git a/freqtrade/plugins/protections/iprotection.py b/freqtrade/plugins/protections/iprotection.py index 5dbcf72f6..8048fccf0 100644 --- a/freqtrade/plugins/protections/iprotection.py +++ b/freqtrade/plugins/protections/iprotection.py @@ -1,10 +1,11 @@ import logging from abc import ABC, abstractmethod -from datetime import datetime -from typing import Any, Dict, Optional, Tuple +from datetime import datetime, timedelta, timezone +from typing import Any, Dict, List, Optional, Tuple from freqtrade.mixins import LoggingMixin +from freqtrade.persistence import Trade logger = logging.getLogger(__name__) @@ -45,3 +46,17 @@ class IProtection(LoggingMixin, ABC): :return: Tuple of [bool, until, reason]. If true, this pair will be locked with until """ + + @staticmethod + def calculate_lock_end(trades: List[Trade], stop_minutes: int) -> datetime: + """ + Get lock end time + """ + max_date: datetime = max([trade.close_date for trade in trades]) + # comming from Database, tzinfo is not set. + if max_date.tzinfo is None: + max_date = max_date.replace(tzinfo=timezone.utc) + + until = max_date + timedelta(minutes=stop_minutes) + + return until diff --git a/freqtrade/plugins/protections/low_profit_pairs.py b/freqtrade/plugins/protections/low_profit_pairs.py index dc5e1ba24..38d0886bb 100644 --- a/freqtrade/plugins/protections/low_profit_pairs.py +++ b/freqtrade/plugins/protections/low_profit_pairs.py @@ -3,7 +3,6 @@ import logging from datetime import datetime, timedelta from typing import Any, Dict - from freqtrade.persistence import Trade from freqtrade.plugins.protections import IProtection, ProtectionReturn @@ -57,7 +56,8 @@ class LowProfitPairs(IProtection): logger.info, f"Trading for {pair} stopped due to {profit} < {self._required_profit} " f"within {self._lookback_period} minutes.") - until = date_now + timedelta(minutes=self._stop_duration) + until = self.calculate_lock_end(trades, self._stop_duration) + return True, until, self._reason(profit) return False, None, None diff --git a/freqtrade/plugins/protections/stoploss_guard.py b/freqtrade/plugins/protections/stoploss_guard.py index 408492063..6335172f8 100644 --- a/freqtrade/plugins/protections/stoploss_guard.py +++ b/freqtrade/plugins/protections/stoploss_guard.py @@ -55,7 +55,7 @@ class StoplossGuard(IProtection): if len(trades) > self._trade_limit: self.log_on_refresh(logger.info, f"Trading stopped due to {self._trade_limit} " f"stoplosses within {self._lookback_period} minutes.") - until = date_now + timedelta(minutes=self._stop_duration) + until = self.calculate_lock_end(trades, self._stop_duration) return True, until, self._reason() return False, None, None