Add tests for pairlock

This commit is contained in:
Matthias 2020-10-17 11:40:01 +02:00
parent e513871fd5
commit 7caa6cfe31
3 changed files with 60 additions and 12 deletions

View File

@ -678,11 +678,23 @@ class PairLock(_DECL_BASE):
active = Column(Boolean, nullable=False, default=True) active = Column(Boolean, nullable=False, default=True)
def __repr__(self): def __repr__(self):
lock_time = self.open_date.strftime(DATETIME_PRINT_FORMAT) lock_time = self.lock_time.strftime(DATETIME_PRINT_FORMAT)
lock_end_time = self.open_date.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}, ' 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})')
@staticmethod
def lock_pair(pair: str, until: datetime, reason: str = None) -> None:
lock = PairLock(
pair=pair,
lock_time=datetime.now(timezone.utc),
lock_end_time=until,
reason=reason,
active=True
)
PairLock.session.add(lock)
PairLock.session.flush()
@staticmethod @staticmethod
def get_pair_locks(pair: str, now: Optional[datetime] = None) -> List['PairLock']: def get_pair_locks(pair: str, now: Optional[datetime] = None) -> List['PairLock']:
""" """

View File

@ -287,15 +287,7 @@ class IStrategy(ABC):
:param until: datetime in UTC until the pair should be blocked from opening new trades. :param until: datetime in UTC until the pair should be blocked from opening new trades.
Needs to be timezone aware `datetime.now(timezone.utc)` Needs to be timezone aware `datetime.now(timezone.utc)`
""" """
lock = PairLock( PairLock.lock_pair(pair, until, reason)
pair=pair,
lock_time=datetime.now(timezone.utc),
lock_end_time=until,
reason=reason,
active=True
)
PairLock.session.add(lock)
PairLock.session.flush()
def unlock_pair(self, pair: str) -> None: def unlock_pair(self, pair: str) -> None:
""" """

View File

@ -1,5 +1,6 @@
# pragma pylint: disable=missing-docstring, C0103 # pragma pylint: disable=missing-docstring, C0103
import logging import logging
from datetime import datetime, timedelta, timezone
from unittest.mock import MagicMock from unittest.mock import MagicMock
import arrow import arrow
@ -8,7 +9,7 @@ from sqlalchemy import create_engine
from freqtrade import constants from freqtrade import constants
from freqtrade.exceptions import DependencyException, OperationalException from freqtrade.exceptions import DependencyException, OperationalException
from freqtrade.persistence import Order, Trade, clean_dry_run_db, init_db from freqtrade.persistence import Order, PairLock, Trade, clean_dry_run_db, init_db
from tests.conftest import create_mock_trades, log_has, log_has_re from tests.conftest import create_mock_trades, log_has, log_has_re
@ -1158,3 +1159,46 @@ def test_select_order(fee):
assert order.ft_order_side == 'stoploss' assert order.ft_order_side == 'stoploss'
order = trades[4].select_order('sell', False) order = trades[4].select_order('sell', False)
assert order is None assert order is None
@pytest.mark.usefixtures("init_persistence")
def test_PairLock(default_conf):
# No lock should be present
assert len(PairLock.query.all()) == 0
pair = 'ETH/BTC'
assert not PairLock.is_pair_locked(pair)
PairLock.lock_pair(pair, arrow.utcnow().shift(minutes=4).datetime)
# ETH/BTC locked for 4 minutes
assert PairLock.is_pair_locked(pair)
# XRP/BTC should not be locked now
pair = 'XRP/BTC'
assert not PairLock.is_pair_locked(pair)
# Unlocking a pair that's not locked should not raise an error
PairLock.unlock_pair(pair)
# Unlock original pair
pair = 'ETH/BTC'
PairLock.unlock_pair(pair)
assert not PairLock.is_pair_locked(pair)
pair = 'BTC/USDT'
# Lock until 14:30
lock_time = datetime(2020, 5, 1, 14, 30, 0, tzinfo=timezone.utc)
PairLock.lock_pair(pair, lock_time)
# Lock is in the past, so we must fake the lock
lock = PairLock.query.filter(PairLock.pair == pair).first()
lock.lock_time = lock_time - timedelta(hours=2)
assert not PairLock.is_pair_locked(pair)
assert PairLock.is_pair_locked(pair, lock_time + timedelta(minutes=-10))
assert PairLock.is_pair_locked(pair, lock_time + timedelta(minutes=-50))
# Should not be locked after time expired
assert not PairLock.is_pair_locked(pair, lock_time + timedelta(minutes=10))
locks = PairLock.get_pair_locks(pair, lock_time + timedelta(minutes=-2))
assert len(locks) == 1
assert 'PairLock' in str(locks[0])