Implement global stop (First try)

This commit is contained in:
Matthias 2020-10-14 20:03:56 +02:00
parent 246b4a57a4
commit f39a534fc0
6 changed files with 23 additions and 9 deletions

View File

@ -27,6 +27,7 @@ AVAILABLE_PAIRLISTS = ['StaticPairList', 'VolumePairList',
'AgeFilter', 'PerformanceFilter', 'PrecisionFilter', 'AgeFilter', 'PerformanceFilter', 'PrecisionFilter',
'PriceFilter', 'RangeStabilityFilter', 'ShuffleFilter', 'PriceFilter', 'RangeStabilityFilter', 'ShuffleFilter',
'SpreadFilter'] 'SpreadFilter']
AVAILABLE_PROTECTIONS = ['StoplossGuard']
AVAILABLE_DATAHANDLERS = ['json', 'jsongz', 'hdf5'] AVAILABLE_DATAHANDLERS = ['json', 'jsongz', 'hdf5']
DRY_RUN_WALLET = 1000 DRY_RUN_WALLET = 1000
DATETIME_PRINT_FORMAT = '%Y-%m-%d %H:%M:%S' DATETIME_PRINT_FORMAT = '%Y-%m-%d %H:%M:%S'

View File

@ -23,6 +23,7 @@ from freqtrade.exchange import timeframe_to_minutes
from freqtrade.misc import safe_value_fallback, safe_value_fallback2 from freqtrade.misc import safe_value_fallback, safe_value_fallback2
from freqtrade.pairlist.pairlistmanager import PairListManager from freqtrade.pairlist.pairlistmanager import PairListManager
from freqtrade.persistence import Order, PairLocks, Trade, cleanup_db, init_db from freqtrade.persistence import Order, PairLocks, Trade, cleanup_db, init_db
from freqtrade.plugins.protectionmanager import ProtectionManager
from freqtrade.resolvers import ExchangeResolver, StrategyResolver from freqtrade.resolvers import ExchangeResolver, StrategyResolver
from freqtrade.rpc import RPCManager, RPCMessageType from freqtrade.rpc import RPCManager, RPCMessageType
from freqtrade.state import State from freqtrade.state import State
@ -78,6 +79,8 @@ class FreqtradeBot:
self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists) self.dataprovider = DataProvider(self.config, self.exchange, self.pairlists)
self.protections = ProtectionManager(self.config)
# Attach Dataprovider to Strategy baseclass # Attach Dataprovider to Strategy baseclass
IStrategy.dp = self.dataprovider IStrategy.dp = self.dataprovider
# Attach Wallets to Strategy baseclass # Attach Wallets to Strategy baseclass
@ -178,7 +181,7 @@ class FreqtradeBot:
self.exit_positions(trades) self.exit_positions(trades)
# Then looking for buy opportunities # Then looking for buy opportunities
if self.get_free_open_trades(): if self.get_free_open_trades() and not self.protections.global_stop():
self.enter_positions() self.enter_positions()
Trade.session.flush() Trade.session.flush()

View File

@ -0,0 +1,2 @@
# flake8: noqa: F401
# from freqtrade.plugins.protectionmanager import ProtectionManager

View File

@ -7,7 +7,7 @@ from typing import Dict, List
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
from freqtrade.plugins.protections import IProtection from freqtrade.plugins.protections import IProtection
from freqtrade.resolvers import ProtectionResolver from freqtrade.resolvers import ProtectionResolver
from datetime import datetime
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -18,8 +18,7 @@ class ProtectionManager():
self._config = config self._config = config
self._protection_handlers: List[IProtection] = [] self._protection_handlers: List[IProtection] = []
self._tickers_needed = False for protection_handler_config in self._config.get('protections', []):
for protection_handler_config in self._config.get('protections', None):
if 'method' not in protection_handler_config: if 'method' not in protection_handler_config:
logger.warning(f"No method found in {protection_handler_config}, ignoring.") logger.warning(f"No method found in {protection_handler_config}, ignoring.")
continue continue
@ -28,11 +27,10 @@ class ProtectionManager():
config=config, config=config,
protection_config=protection_handler_config, protection_config=protection_handler_config,
) )
self._tickers_needed |= protection_handler.needstickers
self._protection_handlers.append(protection_handler) self._protection_handlers.append(protection_handler)
if not self._protection_handlers: if not self._protection_handlers:
raise OperationalException("No protection Handlers defined") logger.info("No protection Handlers defined.")
@property @property
def name_list(self) -> List[str]: def name_list(self) -> List[str]:
@ -45,4 +43,14 @@ class ProtectionManager():
""" """
List of short_desc for each Pairlist Handler List of short_desc for each Pairlist Handler
""" """
return [{p.name: p.short_desc()} for p in self._pairlist_handlers] return [{p.name: p.short_desc()} for p in self._protection_handlers]
def global_stop(self) -> bool:
now = datetime.utcnow()
for protection_handler in self._protection_handlers:
result = protection_handler.global_stop(now)
# Early stopping - first positive result stops the application
if result:
return True
return False

View File

@ -26,7 +26,7 @@ class IProtection(ABC):
""" """
@abstractmethod @abstractmethod
def stop_trade_enters_global(self, date_now: datetime) -> bool: def global_stop(self, date_now: datetime) -> bool:
""" """
Stops trading (position entering) for all pairs Stops trading (position entering) for all pairs
This must evaluate to true for the whole period of the "cooldown period". This must evaluate to true for the whole period of the "cooldown period".

View File

@ -47,7 +47,7 @@ class StoplossGuard(IProtection):
return False return False
def stop_trade_enters_global(self, date_now: datetime) -> bool: def global_stop(self, date_now: datetime) -> bool:
""" """
Stops trading (position entering) for all pairs Stops trading (position entering) for all pairs
This must evaluate to true for the whole period of the "cooldown period". This must evaluate to true for the whole period of the "cooldown period".