max_open_trades should be an integer
Max open trades will be always an integer in the strategy (-1 for infinity), but in the config -1 will be parsed as infinity
This commit is contained in:
parent
1c5e172683
commit
f2fa476dc6
@ -332,7 +332,7 @@ def analyze_trade_parallelism(results: pd.DataFrame, timeframe: str) -> pd.DataF
|
|||||||
|
|
||||||
|
|
||||||
def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
|
def evaluate_result_multi(results: pd.DataFrame, timeframe: str,
|
||||||
max_open_trades: int | float) -> pd.DataFrame:
|
max_open_trades: int) -> pd.DataFrame:
|
||||||
"""
|
"""
|
||||||
Find overlapping trades by expanding each trade once per period it was open
|
Find overlapping trades by expanding each trade once per period it was open
|
||||||
and then counting overlaps
|
and then counting overlaps
|
||||||
|
@ -521,7 +521,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
self.log_once(f"Pair {pair} is currently locked.", logger.info)
|
self.log_once(f"Pair {pair} is currently locked.", logger.info)
|
||||||
return False
|
return False
|
||||||
stake_amount = self.wallets.get_trade_stake_amount(
|
stake_amount = self.wallets.get_trade_stake_amount(
|
||||||
pair, self.edge, self.config['max_open_trades'])
|
pair, self.edge)
|
||||||
|
|
||||||
bid_check_dom = self.config.get('entry_pricing', {}).get('check_depth_of_market', {})
|
bid_check_dom = self.config.get('entry_pricing', {}).get('check_depth_of_market', {})
|
||||||
if ((bid_check_dom.get('enabled', False)) and
|
if ((bid_check_dom.get('enabled', False)) and
|
||||||
|
@ -920,7 +920,7 @@ class Backtesting:
|
|||||||
trade.close(exit_row[OPEN_IDX], show_msg=False)
|
trade.close(exit_row[OPEN_IDX], show_msg=False)
|
||||||
LocalTrade.close_bt_trade(trade)
|
LocalTrade.close_bt_trade(trade)
|
||||||
|
|
||||||
def trade_slot_available(self, max_open_trades: int | float, open_trade_count: int) -> bool:
|
def trade_slot_available(self, max_open_trades: int, open_trade_count: int) -> bool:
|
||||||
# Always allow trades when max_open_trades is enabled.
|
# Always allow trades when max_open_trades is enabled.
|
||||||
if max_open_trades <= 0 or open_trade_count < max_open_trades:
|
if max_open_trades <= 0 or open_trade_count < max_open_trades:
|
||||||
return True
|
return True
|
||||||
@ -1051,7 +1051,7 @@ class Backtesting:
|
|||||||
|
|
||||||
def backtest_loop(
|
def backtest_loop(
|
||||||
self, row: Tuple, pair: str, current_time: datetime, end_date: datetime,
|
self, row: Tuple, pair: str, current_time: datetime, end_date: datetime,
|
||||||
max_open_trades: int | float,
|
max_open_trades: int,
|
||||||
open_trade_count_start: int, is_first: bool = True) -> int:
|
open_trade_count_start: int, is_first: bool = True) -> int:
|
||||||
"""
|
"""
|
||||||
NOTE: This method is used by Hyperopt at each iteration. Please keep it optimized.
|
NOTE: This method is used by Hyperopt at each iteration. Please keep it optimized.
|
||||||
@ -1123,7 +1123,7 @@ class Backtesting:
|
|||||||
|
|
||||||
def backtest(self, processed: Dict,
|
def backtest(self, processed: Dict,
|
||||||
start_date: datetime, end_date: datetime,
|
start_date: datetime, end_date: datetime,
|
||||||
max_open_trades: int | float = 0) -> Dict[str, Any]:
|
max_open_trades: int = 0) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Implement backtesting functionality
|
Implement backtesting functionality
|
||||||
|
|
||||||
@ -1228,7 +1228,8 @@ class Backtesting:
|
|||||||
# Use max_open_trades in backtesting, except --disable-max-market-positions is set
|
# Use max_open_trades in backtesting, except --disable-max-market-positions is set
|
||||||
if self.config.get('use_max_market_positions', True):
|
if self.config.get('use_max_market_positions', True):
|
||||||
# Must come from strategy config, as the strategy may modify this setting.
|
# Must come from strategy config, as the strategy may modify this setting.
|
||||||
max_open_trades = self.strategy.config['max_open_trades']
|
max_open_trades = self.strategy.config['max_open_trades'] \
|
||||||
|
if self.strategy.config['max_open_trades'] != float('inf') else -1
|
||||||
else:
|
else:
|
||||||
logger.info(
|
logger.info(
|
||||||
'Ignoring max_open_trades (--disable-max-market-positions was used) ...')
|
'Ignoring max_open_trades (--disable-max-market-positions was used) ...')
|
||||||
|
@ -119,11 +119,14 @@ class Hyperopt:
|
|||||||
|
|
||||||
# Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set
|
# Use max_open_trades for hyperopt as well, except --disable-max-market-positions is set
|
||||||
if self.config.get('use_max_market_positions', True):
|
if self.config.get('use_max_market_positions', True):
|
||||||
self.max_open_trades = self.config['max_open_trades']
|
self.max_open_trades = self.config['max_open_trades'] \
|
||||||
|
if self.config['max_open_trades'] != float('inf') else -1
|
||||||
else:
|
else:
|
||||||
logger.debug('Ignoring max_open_trades (--disable-max-market-positions was used) ...')
|
logger.debug('Ignoring max_open_trades (--disable-max-market-positions was used) ...')
|
||||||
self.max_open_trades = 0
|
self.max_open_trades = 0
|
||||||
|
|
||||||
|
print("Strategy max open trades", self.max_open_trades)
|
||||||
|
|
||||||
if HyperoptTools.has_space(self.config, 'sell'):
|
if HyperoptTools.has_space(self.config, 'sell'):
|
||||||
# Make sure use_exit_signal is enabled
|
# Make sure use_exit_signal is enabled
|
||||||
self.config['use_exit_signal'] = True
|
self.config['use_exit_signal'] = True
|
||||||
|
@ -191,7 +191,7 @@ def generate_tag_metrics(tag_type: str,
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def generate_exit_reason_stats(max_open_trades: int | float, results: DataFrame) -> List[Dict]:
|
def generate_exit_reason_stats(max_open_trades: int, results: DataFrame) -> List[Dict]:
|
||||||
"""
|
"""
|
||||||
Generate small table outlining Backtest results
|
Generate small table outlining Backtest results
|
||||||
:param max_open_trades: Max_open_trades parameter
|
:param max_open_trades: Max_open_trades parameter
|
||||||
|
@ -104,13 +104,21 @@ class StrategyResolver(IResolver):
|
|||||||
if (attribute in config
|
if (attribute in config
|
||||||
and not isinstance(getattr(type(strategy), attribute, None), property)):
|
and not isinstance(getattr(type(strategy), attribute, None), property)):
|
||||||
# Ensure Properties are not overwritten
|
# Ensure Properties are not overwritten
|
||||||
setattr(strategy, attribute, config[attribute])
|
val = config[attribute]
|
||||||
|
# max_open_trades set to float('inf') in the config will be copied as -1 in the strategy
|
||||||
|
if attribute == 'max_open_trades' and val == float('inf'):
|
||||||
|
val = -1
|
||||||
|
setattr(strategy, attribute, val)
|
||||||
logger.info("Override strategy '%s' with value in config file: %s.",
|
logger.info("Override strategy '%s' with value in config file: %s.",
|
||||||
attribute, config[attribute])
|
attribute, config[attribute])
|
||||||
elif hasattr(strategy, attribute):
|
elif hasattr(strategy, attribute):
|
||||||
val = getattr(strategy, attribute)
|
val = getattr(strategy, attribute)
|
||||||
# None's cannot exist in the config, so do not copy them
|
# None's cannot exist in the config, so do not copy them
|
||||||
if val is not None:
|
if val is not None:
|
||||||
|
# max_open_trades set to -1 in the strategy will be copied as infinity in the config
|
||||||
|
if attribute == 'max_open_trades' and val == -1:
|
||||||
|
config[attribute] = float('inf')
|
||||||
|
else:
|
||||||
config[attribute] = val
|
config[attribute] = val
|
||||||
# Explicitly check for None here as other "falsy" values are possible
|
# Explicitly check for None here as other "falsy" values are possible
|
||||||
elif default is not None:
|
elif default is not None:
|
||||||
@ -129,8 +137,6 @@ class StrategyResolver(IResolver):
|
|||||||
key=lambda t: t[0]))
|
key=lambda t: t[0]))
|
||||||
if hasattr(strategy, 'stoploss'):
|
if hasattr(strategy, 'stoploss'):
|
||||||
strategy.stoploss = float(strategy.stoploss)
|
strategy.stoploss = float(strategy.stoploss)
|
||||||
if hasattr(strategy, 'max_open_trades') and strategy.max_open_trades == -1:
|
|
||||||
strategy.max_open_trades = float('inf')
|
|
||||||
return strategy
|
return strategy
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -55,7 +55,7 @@ class IStrategy(ABC, HyperStrategyMixin):
|
|||||||
stoploss: float
|
stoploss: float
|
||||||
|
|
||||||
# max open trades for the strategy
|
# max open trades for the strategy
|
||||||
max_open_trades: int | float
|
max_open_trades: int
|
||||||
|
|
||||||
# trailing stoploss
|
# trailing stoploss
|
||||||
trailing_stop: bool = False
|
trailing_stop: bool = False
|
||||||
|
@ -371,19 +371,20 @@ def test_strategy_max_open_trades_infinity_from_strategy(caplog, default_conf):
|
|||||||
strategy = StrategyResolver.load_strategy(default_conf)
|
strategy = StrategyResolver.load_strategy(default_conf)
|
||||||
|
|
||||||
# this test assumes -1 set to 'max_open_trades' in CURRENT_TEST_STRATEGY
|
# this test assumes -1 set to 'max_open_trades' in CURRENT_TEST_STRATEGY
|
||||||
assert strategy.max_open_trades == float('inf')
|
assert strategy.max_open_trades == -1
|
||||||
|
assert default_conf['max_open_trades'] == float('inf')
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_max_open_trades_infinity_from_config(caplog, default_conf):
|
def test_strategy_max_open_trades_infinity_from_config(caplog, default_conf):
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
default_conf.update({
|
default_conf.update({
|
||||||
'strategy': CURRENT_TEST_STRATEGY,
|
'strategy': CURRENT_TEST_STRATEGY,
|
||||||
'max_open_trades': -1
|
'max_open_trades': float('inf')
|
||||||
})
|
})
|
||||||
|
|
||||||
strategy = StrategyResolver.load_strategy(default_conf)
|
strategy = StrategyResolver.load_strategy(default_conf)
|
||||||
|
|
||||||
assert strategy.max_open_trades == float('inf')
|
assert strategy.max_open_trades == -1
|
||||||
|
|
||||||
|
|
||||||
@ pytest.mark.filterwarnings("ignore:deprecated")
|
@ pytest.mark.filterwarnings("ignore:deprecated")
|
||||||
|
Loading…
Reference in New Issue
Block a user