Add "allow_position_stacking" value to config, which allows rebuys of a pair
Add function unlock_reason(str: pair) which removes all PairLocks with reason Provide demo strategy that allows buying the same pair multiple times
This commit is contained in:
@@ -137,6 +137,12 @@ class Configuration:
|
||||
setup_logging(config)
|
||||
|
||||
def _process_trading_options(self, config: Dict[str, Any]) -> None:
|
||||
|
||||
# Allow_position_stacking defaults to False
|
||||
if not config.get('allow_position_stacking'):
|
||||
config['allow_position_stacking'] = False
|
||||
logger.info('Allow_position_stacking is set to ' + str(config['allow_position_stacking']))
|
||||
|
||||
if config['runmode'] not in TRADING_MODES:
|
||||
return
|
||||
|
||||
|
@@ -4,7 +4,7 @@ Freqtrade is the main module of this bot. It contains the class Freqtrade()
|
||||
import copy
|
||||
import logging
|
||||
import traceback
|
||||
from datetime import datetime, timezone
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from math import isclose
|
||||
from threading import Lock
|
||||
from typing import Any, Dict, List, Optional
|
||||
@@ -359,10 +359,12 @@ class FreqtradeBot(LoggingMixin):
|
||||
logger.info("Active pair whitelist is empty.")
|
||||
return trades_created
|
||||
# Remove pairs for currently opened trades from the whitelist
|
||||
for trade in Trade.get_open_trades():
|
||||
if trade.pair in whitelist:
|
||||
whitelist.remove(trade.pair)
|
||||
logger.debug('Ignoring %s in pair whitelist', trade.pair)
|
||||
# Allow rebuying of the same pair if allow_position_stacking is set to True
|
||||
if not self.config['allow_position_stacking']:
|
||||
for trade in Trade.get_open_trades():
|
||||
if trade.pair in whitelist:
|
||||
whitelist.remove(trade.pair)
|
||||
logger.debug('Ignoring %s in pair whitelist', trade.pair)
|
||||
|
||||
if not whitelist:
|
||||
logger.info("No currency pair in active pair whitelist, "
|
||||
@@ -592,6 +594,11 @@ class FreqtradeBot(LoggingMixin):
|
||||
|
||||
self._notify_enter(trade, order_type)
|
||||
|
||||
# Lock pair for 1 timeframe duration to prevent immediate rebuys
|
||||
if self.config['allow_position_stacking']:
|
||||
self.strategy.lock_pair(trade.pair, datetime.now(timezone.utc) + timedelta(minutes=timeframe_to_minutes(self.config['timeframe'])),
|
||||
reason='Prevent immediate rebuys')
|
||||
|
||||
return True
|
||||
|
||||
def _notify_enter(self, trade: Trade, order_type: str) -> None:
|
||||
|
@@ -103,6 +103,24 @@ class PairLocks():
|
||||
if PairLocks.use_db:
|
||||
PairLock.query.session.commit()
|
||||
|
||||
@staticmethod
|
||||
def unlock_reason(reason: str, now: Optional[datetime] = None) -> None:
|
||||
"""
|
||||
Release all locks for this reason.
|
||||
:param reason: Which reason to unlock
|
||||
:param now: Datetime object (generated via datetime.now(timezone.utc)).
|
||||
defaults to datetime.now(timezone.utc)
|
||||
"""
|
||||
if not now:
|
||||
now = datetime.now(timezone.utc)
|
||||
logger.info(f"Releasing all locks with reason \'{reason}\'.")
|
||||
locks = PairLocks.get_all_locks()
|
||||
for lock in locks:
|
||||
if lock.reason == reason:
|
||||
lock.active = False
|
||||
if PairLocks.use_db:
|
||||
PairLock.query.session.commit()
|
||||
|
||||
@staticmethod
|
||||
def is_global_lock(now: Optional[datetime] = None) -> bool:
|
||||
"""
|
||||
|
@@ -443,6 +443,15 @@ class IStrategy(ABC, HyperStrategyMixin):
|
||||
"""
|
||||
PairLocks.unlock_pair(pair, datetime.now(timezone.utc))
|
||||
|
||||
def unlock_reason(self, reason: str) -> None:
|
||||
"""
|
||||
Unlocks all pairs previously locked using lock_pair with specified reason.
|
||||
Not used by freqtrade itself, but intended to be used if users lock pairs
|
||||
manually from within the strategy, to allow an easy way to unlock pairs.
|
||||
:param reason: Unlock pairs to allow trading again
|
||||
"""
|
||||
PairLocks.unlock_reason(reason, datetime.now(timezone.utc))
|
||||
|
||||
def is_pair_locked(self, pair: str, candle_date: datetime = None) -> bool:
|
||||
"""
|
||||
Checks if a pair is currently locked
|
||||
|
Reference in New Issue
Block a user