From 9582bd3cd72cb04cddf7a6d51fd93e4cab1a07e4 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 6 Apr 2026 09:58:35 +0200 Subject: [PATCH] feat: don't allow re-creation of existing logs This prevents lock spam - where 100ds of identical rows can be inserted into the database --- freqtrade/persistence/pairlock.py | 5 +++++ freqtrade/persistence/pairlock_middleware.py | 12 +++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/freqtrade/persistence/pairlock.py b/freqtrade/persistence/pairlock.py index eedc7286f..21439e5f7 100644 --- a/freqtrade/persistence/pairlock.py +++ b/freqtrade/persistence/pairlock.py @@ -29,6 +29,11 @@ class PairLock(ModelBase): active: Mapped[bool] = mapped_column(nullable=False, default=True, index=True) + @property + def lock_end_time_utc(self) -> datetime: + """Lock end time with UTC timezoneinfo""" + return self.lock_end_time.replace(tzinfo=UTC) + def __repr__(self) -> str: lock_time = self.lock_time.strftime(DATETIME_PRINT_FORMAT) lock_end_time = self.lock_end_time.strftime(DATETIME_PRINT_FORMAT) diff --git a/freqtrade/persistence/pairlock_middleware.py b/freqtrade/persistence/pairlock_middleware.py index 94544928d..c7a9fca83 100644 --- a/freqtrade/persistence/pairlock_middleware.py +++ b/freqtrade/persistence/pairlock_middleware.py @@ -42,6 +42,7 @@ class PairLocks: ) -> PairLock: """ Create PairLock from now to "until". + Does not create a new lock if there is already a lock with the same Reason, side and end time. Uses database by default, unless PairLocks.use_db is set to False, in which case a list is maintained. :param pair: pair to lock. use '*' to lock all pairs @@ -50,10 +51,19 @@ class PairLocks: :param now: Current timestamp. Used to determine lock start time. :param side: Side to lock pair, can be 'long', 'short' or '*' """ + lock_end_time = timeframe_to_next_date(PairLocks.timeframe, until) + existing_locks = PairLocks.get_pair_locks(pair, now, side=side) + for lock in existing_locks: + if ( + lock.reason == reason + and lock.lock_end_time_utc == lock_end_time + and lock.side == side + ): + return lock lock = PairLock( pair=pair, lock_time=now or datetime.now(UTC), - lock_end_time=timeframe_to_next_date(PairLocks.timeframe, until), + lock_end_time=lock_end_time, reason=reason, side=side, active=True,