mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-09-20 09:31:12 +00:00
Fixed implementation of unlock_at and updated unit tests
This commit is contained in:
parent
57118691d8
commit
77b4689ac8
|
@ -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(
|
||||
|
|
|
@ -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:
|
||||
"""
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
|
|
Loading…
Reference in New Issue
Block a user