Update protection-interface to support per-side locks

This commit is contained in:
Matthias
2022-04-23 19:58:20 +02:00
parent 6ff3b178b0
commit 9e199165b4
9 changed files with 58 additions and 44 deletions

View File

@@ -1,7 +1,7 @@
import logging
from datetime import datetime, timedelta
from typing import Any, Dict
from typing import Any, Dict, Optional
from freqtrade.enums import ExitType
from freqtrade.persistence import Trade
@@ -21,6 +21,7 @@ class StoplossGuard(IProtection):
self._trade_limit = protection_config.get('trade_limit', 10)
self._disable_global_stop = protection_config.get('only_per_pair', False)
self._only_per_side = protection_config.get('only_per_side', False)
def short_desc(self) -> str:
"""
@@ -36,7 +37,8 @@ class StoplossGuard(IProtection):
return (f'{self._trade_limit} stoplosses in {self._lookback_period} min, '
f'locking for {self._stop_duration} min.')
def _stoploss_guard(self, date_now: datetime, pair: str = None) -> ProtectionReturn:
def _stoploss_guard(
self, date_now: datetime, pair: Optional[str], side: str) -> ProtectionReturn:
"""
Evaluate recent trades
"""
@@ -48,15 +50,19 @@ class StoplossGuard(IProtection):
ExitType.STOPLOSS_ON_EXCHANGE.value)
and trade.close_profit and trade.close_profit < 0)]
if self._only_per_side and side:
# Long or short trades only
trades = [trade for trade in trades if trade.trade_direction == side]
if len(trades) < self._trade_limit:
return False, None, None
return False, None, None, None
self.log_once(f"Trading stopped due to {self._trade_limit} "
f"stoplosses within {self._lookback_period} minutes.", logger.info)
until = self.calculate_lock_end(trades, self._stop_duration)
return True, until, self._reason()
return True, until, self._reason(), (side if self._only_per_side else None)
def global_stop(self, date_now: datetime) -> ProtectionReturn:
def global_stop(self, date_now: datetime, side: str) -> ProtectionReturn:
"""
Stops trading (position entering) for all pairs
This must evaluate to true for the whole period of the "cooldown period".
@@ -64,14 +70,14 @@ class StoplossGuard(IProtection):
If true, all pairs will be locked with <reason> until <until>
"""
if self._disable_global_stop:
return False, None, None
return self._stoploss_guard(date_now, None)
return False, None, None, None
return self._stoploss_guard(date_now, None, side)
def stop_per_pair(self, pair: str, date_now: datetime) -> ProtectionReturn:
def stop_per_pair(self, pair: str, date_now: datetime, side: str) -> ProtectionReturn:
"""
Stops trading (position entering) for this pair
This must evaluate to true for the whole period of the "cooldown period".
:return: Tuple of [bool, until, reason].
If true, this pair will be locked with <reason> until <until>
"""
return self._stoploss_guard(date_now, pair)
return self._stoploss_guard(date_now, pair, side)