Fixed implementation of unlock_at and updated unit tests

This commit is contained in:
simwai 2024-07-05 22:14:35 +02:00
parent 57118691d8
commit 77b4689ac8
6 changed files with 45 additions and 16 deletions

View File

@ -46,6 +46,9 @@ class CooldownPeriod(IProtection):
# Ignore type error as we know we only get closed trades.
trade = sorted(trades, key=lambda t: t.close_date)[-1] # type: ignore
self.log_once(f"Cooldown for {pair} for {self.stop_duration_str}.", logger.info)
self.set_unlock_at_as_stop_duration()
until = self.calculate_lock_end([trade], self._stop_duration)
return ProtectionReturn(

View File

@ -47,18 +47,7 @@ class IProtection(LoggingMixin, ABC):
else:
self._lookback_period = int(protection_config.get("lookback_period", 60))
if "unlock_at" in protection_config:
now_time = datetime.now(timezone.utc)
unlock_at = datetime.strptime(protection_config["unlock_at"], "%H:%M").replace(
day=now_time.day, year=now_time.year, month=now_time.month
)
if unlock_at.time() < now_time.time():
unlock_at = unlock_at.replace(day=now_time.day + 1)
unlock_at = unlock_at.replace(tzinfo=timezone.utc)
self._stop_duration = self.calculate_timespan(now_time, unlock_at)
self.unlock_at = unlock_at
self.set_unlock_at_as_stop_duration()
LoggingMixin.__init__(self, logger)
@ -101,6 +90,36 @@ class IProtection(LoggingMixin, ABC):
return self.unlock_at.strftime("%H:%M")
return None
def set_unlock_at_as_stop_duration(self) -> None:
"""
Calculates the stop_duration based on the unlock_at protection config value and sets it.
"""
if "unlock_at" in self._protection_config:
self._stop_duration = self.calculate_unlock_at()
return None
logger.warning(
"Couldn't update the stop duration, because unlock_at is not set in the "
"protection config."
)
def calculate_unlock_at(self) -> int:
"""
Calculate and update the stop duration based on the unlock at config.
"""
now_time = datetime.now(timezone.utc)
unlock_at = datetime.strptime(
str(self._protection_config.get("unlock_at_config")), "%H:%M"
).replace(day=now_time.day, year=now_time.year, month=now_time.month)
if unlock_at.time() < now_time.time():
unlock_at = unlock_at.replace(day=now_time.day + 1)
self.unlock_at = unlock_at.replace(tzinfo=timezone.utc)
result = IProtection.calculate_timespan(now_time, self.unlock_at)
return result
@abstractmethod
def short_desc(self) -> str:
"""

View File

@ -73,6 +73,8 @@ class LowProfitPairs(IProtection):
f"within {self._lookback_period} minutes.",
logger.info,
)
self.set_unlock_at_as_stop_duration()
until = self.calculate_lock_end(trades, self._stop_duration)
return ProtectionReturn(

View File

@ -73,6 +73,8 @@ class MaxDrawdown(IProtection):
f" within {self.lookback_period_str}.",
logger.info,
)
self.set_unlock_at_as_stop_duration()
until = self.calculate_lock_end(trades, self._stop_duration)
return ProtectionReturn(

View File

@ -81,7 +81,10 @@ class StoplossGuard(IProtection):
f"stoplosses within {self._lookback_period} minutes.",
logger.info,
)
self.set_unlock_at_as_stop_duration()
until = self.calculate_lock_end(trades, self._stop_duration)
return ProtectionReturn(
lock=True,
until=until,

View File

@ -189,7 +189,7 @@ def test_protections_init(default_conf, timeframe, expected_lookback, expected_s
if isinstance(expected_stop, int):
assert man._protection_handlers[0]._stop_duration == expected_stop
else:
assert man._protection_handlers[0].unlock_at.strftime("%H:%M") == expected_stop
assert man._protection_handlers[0].unlock_at_str == expected_stop
@pytest.mark.parametrize("is_short", [False, True])
@ -701,19 +701,19 @@ def test_MaxDrawdown(mocker, default_conf, fee, caplog):
"unlock_at": "01:00",
},
"[{'StoplossGuard': 'StoplossGuard - Frequent Stoploss Guard, "
"2 stoplosses with profit < -5.00% within 12 candles. Unlocking trading at 01:00.'}]",
"2 stoplosses with profit < -5.00% within 12 candles.'}]",
None,
),
(
{"method": "LowProfitPairs", "lookback_period_candles": 11, "unlock_at": "03:00"},
"[{'LowProfitPairs': 'LowProfitPairs - Low Profit Protection, locks pairs with "
"profit < 0.0 within 11 candles. Unlocking trading at 03:00.'}]",
"profit < 0.0 within 11 candles.'}]",
None,
),
(
{"method": "MaxDrawdown", "lookback_period_candles": 20, "unlock_at": "04:00"},
"[{'MaxDrawdown': 'MaxDrawdown - Max drawdown protection, stop trading "
"if drawdown is > 0.0 within 20 candles. Unlocking trading at 04:00.'}]",
"if drawdown is > 0.0 within 20 candles.'}]",
None,
),
],