From 3d65ba2dcbb72f8e96e6ea4e3df65cc34eed5035 Mon Sep 17 00:00:00 2001 From: Matthias Date: Mon, 1 Mar 2021 07:51:33 +0100 Subject: [PATCH] Add rpc method to delete locks --- freqtrade/persistence/models.py | 1 + freqtrade/rpc/rpc.py | 24 ++++++++++++++++++++++-- tests/rpc/test_rpc.py | 21 ++++++++++++++++++++- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/freqtrade/persistence/models.py b/freqtrade/persistence/models.py index dff59819c..3c9a10fb7 100644 --- a/freqtrade/persistence/models.py +++ b/freqtrade/persistence/models.py @@ -765,6 +765,7 @@ class PairLock(_DECL_BASE): def to_json(self) -> Dict[str, Any]: return { + 'id': self.id, 'pair': self.pair, 'lock_time': self.lock_time.strftime(DATETIME_PRINT_FORMAT), 'lock_timestamp': int(self.lock_time.replace(tzinfo=timezone.utc).timestamp() * 1000), diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 7549c38be..37a2dc1e5 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -3,7 +3,7 @@ This module contains class to define a RPC communications """ import logging from abc import abstractmethod -from datetime import date, datetime, timedelta +from datetime import date, datetime, timedelta, timezone from enum import Enum from math import isnan from typing import Any, Dict, List, Optional, Tuple, Union @@ -20,6 +20,7 @@ from freqtrade.exchange import timeframe_to_minutes, timeframe_to_msecs from freqtrade.loggers import bufferHandler from freqtrade.misc import shorten_date from freqtrade.persistence import PairLocks, Trade +from freqtrade.persistence.models import PairLock from freqtrade.plugins.pairlist.pairlist_helpers import expand_pairlist from freqtrade.rpc.fiat_convert import CryptoToFiatConverter from freqtrade.state import State @@ -663,7 +664,7 @@ class RPC: } def _rpc_locks(self) -> Dict[str, Any]: - """ Returns the current locks""" + """ Returns the current locks """ locks = PairLocks.get_pair_locks(None) return { @@ -671,6 +672,25 @@ class RPC: 'locks': [lock.to_json() for lock in locks] } + def _rpc_delete_lock(self, lockid: Optional[int] = None, + pair: Optional[str] = None) -> Dict[str, Any]: + """ Delete specific lock(s) """ + locks = [] + + if pair: + locks = PairLocks.get_pair_locks(pair) + if lockid: + locks = PairLock.query.filter(PairLock.id == lockid).all() + + for lock in locks: + lock.active = False + lock.lock_end_time = datetime.now(timezone.utc) + + # session is always the same + PairLock.session.flush() + + return self._rpc_locks() + def _rpc_whitelist(self) -> Dict: """ Returns the currently active whitelist""" res = {'method': self._freqtrade.pairlists.name_list, diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py index 60d9950aa..f745be506 100644 --- a/tests/rpc/test_rpc.py +++ b/tests/rpc/test_rpc.py @@ -1,7 +1,8 @@ # pragma pylint: disable=missing-docstring, C0103 # pragma pylint: disable=invalid-sequence-index, invalid-name, too-many-arguments -from datetime import datetime +from datetime import datetime, timedelta, timezone +from freqtrade.persistence.pairlock_middleware import PairLocks from unittest.mock import ANY, MagicMock, PropertyMock import pytest @@ -911,6 +912,24 @@ def test_rpcforcebuy_disabled(mocker, default_conf) -> None: rpc._rpc_forcebuy(pair, None) +@pytest.mark.usefixtures("init_persistence") +def test_rpc_delete_lock(mocker, default_conf): + freqtradebot = get_patched_freqtradebot(mocker, default_conf) + rpc = RPC(freqtradebot) + pair = 'ETH/BTC' + + PairLocks.lock_pair(pair, datetime.now(timezone.utc) + timedelta(minutes=4)) + PairLocks.lock_pair(pair, datetime.now(timezone.utc) + timedelta(minutes=5)) + PairLocks.lock_pair(pair, datetime.now(timezone.utc) + timedelta(minutes=10)) + locks = rpc._rpc_locks() + assert locks['lock_count'] == 3 + locks1 = rpc._rpc_delete_lock(lockid=locks['locks'][0]['id']) + assert locks1['lock_count'] == 2 + + locks2 = rpc._rpc_delete_lock(pair=pair) + assert locks2['lock_count'] == 0 + + def test_rpc_whitelist(mocker, default_conf) -> None: mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())