Merge pull request #5798 from incrementby1/personal-branch
Add function to unlock PairLocks by reason
This commit is contained in:
@@ -896,7 +896,7 @@ class PairLock(_DECL_BASE):
|
||||
lock_time = self.lock_time.strftime(DATETIME_PRINT_FORMAT)
|
||||
lock_end_time = self.lock_end_time.strftime(DATETIME_PRINT_FORMAT)
|
||||
return (f'PairLock(id={self.id}, pair={self.pair}, lock_time={lock_time}, '
|
||||
f'lock_end_time={lock_end_time})')
|
||||
f'lock_end_time={lock_end_time}, reason={self.reason}, active={self.active})')
|
||||
|
||||
@staticmethod
|
||||
def query_pair_locks(pair: Optional[str], now: datetime) -> Query:
|
||||
@@ -905,7 +905,6 @@ class PairLock(_DECL_BASE):
|
||||
:param pair: Pair to check for. Returns all current locks if pair is empty
|
||||
:param now: Datetime object (generated via datetime.now(timezone.utc)).
|
||||
"""
|
||||
|
||||
filters = [PairLock.lock_end_time > now,
|
||||
# Only active locks
|
||||
PairLock.active.is_(True), ]
|
||||
|
||||
@@ -103,6 +103,36 @@ class PairLocks():
|
||||
if PairLocks.use_db:
|
||||
PairLock.query.session.commit()
|
||||
|
||||
@staticmethod
|
||||
def unlock_reason(reason: str, now: Optional[datetime] = None) -> None:
|
||||
"""
|
||||
Release all locks for this reason.
|
||||
:param reason: Which reason to unlock
|
||||
:param now: Datetime object (generated via datetime.now(timezone.utc)).
|
||||
defaults to datetime.now(timezone.utc)
|
||||
"""
|
||||
if not now:
|
||||
now = datetime.now(timezone.utc)
|
||||
|
||||
if PairLocks.use_db:
|
||||
# used in live modes
|
||||
logger.info(f"Releasing all locks with reason '{reason}':")
|
||||
filters = [PairLock.lock_end_time > now,
|
||||
PairLock.active.is_(True),
|
||||
PairLock.reason == reason
|
||||
]
|
||||
locks = PairLock.query.filter(*filters)
|
||||
for lock in locks:
|
||||
logger.info(f"Releasing lock for {lock.pair} with reason '{reason}'.")
|
||||
lock.active = False
|
||||
PairLock.query.session.commit()
|
||||
else:
|
||||
# used in backtesting mode; don't show log messages for speed
|
||||
locks = PairLocks.get_pair_locks(None)
|
||||
for lock in locks:
|
||||
if lock.reason == reason:
|
||||
lock.active = False
|
||||
|
||||
@staticmethod
|
||||
def is_global_lock(now: Optional[datetime] = None) -> bool:
|
||||
"""
|
||||
@@ -128,7 +158,9 @@ class PairLocks():
|
||||
|
||||
@staticmethod
|
||||
def get_all_locks() -> List[PairLock]:
|
||||
|
||||
"""
|
||||
Return all locks, also locks with expired end date
|
||||
"""
|
||||
if PairLocks.use_db:
|
||||
return PairLock.query.all()
|
||||
else:
|
||||
|
||||
@@ -443,6 +443,15 @@ class IStrategy(ABC, HyperStrategyMixin):
|
||||
"""
|
||||
PairLocks.unlock_pair(pair, datetime.now(timezone.utc))
|
||||
|
||||
def unlock_reason(self, reason: str) -> None:
|
||||
"""
|
||||
Unlocks all pairs previously locked using lock_pair with specified reason.
|
||||
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 reason: Unlock pairs to allow trading again
|
||||
"""
|
||||
PairLocks.unlock_reason(reason, datetime.now(timezone.utc))
|
||||
|
||||
def is_pair_locked(self, pair: str, candle_date: datetime = None) -> bool:
|
||||
"""
|
||||
Checks if a pair is currently locked
|
||||
|
||||
Reference in New Issue
Block a user