diff --git a/freqtrade/strategy/interface.py b/freqtrade/strategy/interface.py index 985ff37de..4f2e990d2 100644 --- a/freqtrade/strategy/interface.py +++ b/freqtrade/strategy/interface.py @@ -168,11 +168,24 @@ class IStrategy(ABC): """ Locks pair until a given timestamp happens. Locked pairs are not analyzed, and are prevented from opening new trades. + Locks can only count up (allowing users to lock pairs for a longer period of time). + To remove a lock from a pair, use `unlock_pair()` :param pair: Pair to lock :param until: datetime in UTC until the pair should be blocked from opening new trades. Needs to be timezone aware `datetime.now(timezone.utc)` """ - self._pair_locked_until[pair] = until + if pair not in self._pair_locked_until or self._pair_locked_until[pair] < until: + self._pair_locked_until[pair] = until + + def unlock_pair(self, pair) -> None: + """ + Unlocks a pair previously locked using lock_pair. + Not used by freqtrade itself, but intended to be used if users lock pairs + manually from within the strategy, to allow an easy way to unlock pairs. + :param pair: Unlock pair to allow trading again + """ + if pair in self._pair_locked_until: + del self._pair_locked_until[pair] def is_pair_locked(self, pair: str) -> bool: """ diff --git a/tests/strategy/test_interface.py b/tests/strategy/test_interface.py index 605622b8f..89c38bda1 100644 --- a/tests/strategy/test_interface.py +++ b/tests/strategy/test_interface.py @@ -302,6 +302,19 @@ def test_is_pair_locked(default_conf): # ETH/BTC locked for 4 minutes assert strategy.is_pair_locked(pair) + # Test lock does not change + lock = strategy._pair_locked_until[pair] + strategy.lock_pair(pair, arrow.utcnow().shift(minutes=2).datetime) + assert lock == strategy._pair_locked_until[pair] + # XRP/BTC should not be locked now pair = 'XRP/BTC' assert not strategy.is_pair_locked(pair) + + # Unlocking a pair that's not locked should not raise an error + strategy.unlock_pair(pair) + + # Unlock original pair + pair = 'ETH/BTC' + strategy.unlock_pair(pair) + assert not strategy.is_pair_locked(pair)