Convert position_stacking to attribute of backtest
This commit is contained in:
parent
8534dfb0d4
commit
6252ae466e
@ -151,6 +151,7 @@ class Backtesting:
|
|||||||
self.trading_mode: TradingMode = config.get('trading_mode', TradingMode.SPOT)
|
self.trading_mode: TradingMode = config.get('trading_mode', TradingMode.SPOT)
|
||||||
# strategies which define "can_short=True" will fail to load in Spot mode.
|
# strategies which define "can_short=True" will fail to load in Spot mode.
|
||||||
self._can_short = self.trading_mode != TradingMode.SPOT
|
self._can_short = self.trading_mode != TradingMode.SPOT
|
||||||
|
self._position_stacking: bool = self.config.get('position_stacking', False)
|
||||||
|
|
||||||
self.init_backtest()
|
self.init_backtest()
|
||||||
|
|
||||||
@ -1069,12 +1070,12 @@ 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, position_stacking: bool, enable_protections: bool,
|
max_open_trades: int, enable_protections: bool,
|
||||||
open_trade_count_start: int) -> int:
|
open_trade_count_start: int) -> 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.
|
||||||
|
|
||||||
Backtesting processing for one candle.
|
Backtesting processing for one candle/pair.
|
||||||
"""
|
"""
|
||||||
for t in list(LocalTrade.bt_trades_open_pp[pair]):
|
for t in list(LocalTrade.bt_trades_open_pp[pair]):
|
||||||
# 1. Manage currently open orders of active trades
|
# 1. Manage currently open orders of active trades
|
||||||
@ -1090,7 +1091,7 @@ class Backtesting:
|
|||||||
# don't open on the last row
|
# don't open on the last row
|
||||||
trade_dir = self.check_for_trade_entry(row)
|
trade_dir = self.check_for_trade_entry(row)
|
||||||
if (
|
if (
|
||||||
(position_stacking or len(LocalTrade.bt_trades_open_pp[pair]) == 0)
|
(self._position_stacking or len(LocalTrade.bt_trades_open_pp[pair]) == 0)
|
||||||
and self.trade_slot_available(max_open_trades, open_trade_count_start)
|
and self.trade_slot_available(max_open_trades, open_trade_count_start)
|
||||||
and current_time != end_date
|
and current_time != end_date
|
||||||
and trade_dir is not None
|
and trade_dir is not None
|
||||||
@ -1137,9 +1138,9 @@ class Backtesting:
|
|||||||
self.run_protections(enable_protections, pair, current_time, trade.trade_direction)
|
self.run_protections(enable_protections, pair, current_time, trade.trade_direction)
|
||||||
return open_trade_count_start
|
return open_trade_count_start
|
||||||
|
|
||||||
def backtest(self, processed: Dict, # noqa: max-complexity: 13
|
def backtest(self, processed: Dict,
|
||||||
start_date: datetime, end_date: datetime,
|
start_date: datetime, end_date: datetime,
|
||||||
max_open_trades: int = 0, position_stacking: bool = False,
|
max_open_trades: int = 0,
|
||||||
enable_protections: bool = False) -> Dict[str, Any]:
|
enable_protections: bool = False) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Implement backtesting functionality
|
Implement backtesting functionality
|
||||||
@ -1153,7 +1154,6 @@ class Backtesting:
|
|||||||
:param start_date: backtesting timerange start datetime
|
:param start_date: backtesting timerange start datetime
|
||||||
:param end_date: backtesting timerange end datetime
|
:param end_date: backtesting timerange end datetime
|
||||||
:param max_open_trades: maximum number of concurrent trades, <= 0 means unlimited
|
:param max_open_trades: maximum number of concurrent trades, <= 0 means unlimited
|
||||||
:param position_stacking: do we allow position stacking?
|
|
||||||
:param enable_protections: Should protections be enabled?
|
:param enable_protections: Should protections be enabled?
|
||||||
:return: DataFrame with trades (results of backtesting)
|
:return: DataFrame with trades (results of backtesting)
|
||||||
"""
|
"""
|
||||||
@ -1187,7 +1187,7 @@ class Backtesting:
|
|||||||
|
|
||||||
open_trade_count_start = self.backtest_loop(
|
open_trade_count_start = self.backtest_loop(
|
||||||
row, pair, current_time, end_date, max_open_trades,
|
row, pair, current_time, end_date, max_open_trades,
|
||||||
position_stacking, enable_protections, open_trade_count_start)
|
enable_protections, open_trade_count_start)
|
||||||
|
|
||||||
# Move time one configured time_interval ahead.
|
# Move time one configured time_interval ahead.
|
||||||
self.progress.increment()
|
self.progress.increment()
|
||||||
@ -1249,7 +1249,6 @@ class Backtesting:
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=max_open_trades,
|
max_open_trades=max_open_trades,
|
||||||
position_stacking=self.config.get('position_stacking', False),
|
|
||||||
enable_protections=self.config.get('enable_protections', False),
|
enable_protections=self.config.get('enable_protections', False),
|
||||||
)
|
)
|
||||||
backtest_end_time = datetime.now(timezone.utc)
|
backtest_end_time = datetime.now(timezone.utc)
|
||||||
|
@ -122,7 +122,6 @@ class Hyperopt:
|
|||||||
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
|
||||||
self.position_stacking = self.config.get('position_stacking', False)
|
|
||||||
|
|
||||||
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
|
||||||
@ -339,7 +338,6 @@ class Hyperopt:
|
|||||||
start_date=self.min_date,
|
start_date=self.min_date,
|
||||||
end_date=self.max_date,
|
end_date=self.max_date,
|
||||||
max_open_trades=self.max_open_trades,
|
max_open_trades=self.max_open_trades,
|
||||||
position_stacking=self.position_stacking,
|
|
||||||
enable_protections=self.config.get('enable_protections', False),
|
enable_protections=self.config.get('enable_protections', False),
|
||||||
)
|
)
|
||||||
backtest_end_time = datetime.now(timezone.utc)
|
backtest_end_time = datetime.now(timezone.utc)
|
||||||
|
@ -97,7 +97,6 @@ def _make_backtest_conf(mocker, datadir, conf=None, pair='UNITTEST/BTC'):
|
|||||||
'start_date': min_date,
|
'start_date': min_date,
|
||||||
'end_date': max_date,
|
'end_date': max_date,
|
||||||
'max_open_trades': 10,
|
'max_open_trades': 10,
|
||||||
'position_stacking': False,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -735,7 +734,6 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=10,
|
max_open_trades=10,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
results = result['results']
|
results = result['results']
|
||||||
assert not results.empty
|
assert not results.empty
|
||||||
@ -822,7 +820,6 @@ def test_backtest_timedout_entry_orders(default_conf, fee, mocker, testdatadir)
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=1,
|
max_open_trades=1,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
assert result['timedout_entry_orders'] == 10
|
assert result['timedout_entry_orders'] == 10
|
||||||
@ -848,7 +845,6 @@ def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=1,
|
max_open_trades=1,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
assert not results['results'].empty
|
assert not results['results'].empty
|
||||||
assert len(results['results']) == 1
|
assert len(results['results']) == 1
|
||||||
@ -880,7 +876,6 @@ def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> N
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=10,
|
max_open_trades=10,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -935,7 +930,6 @@ def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadi
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=10,
|
max_open_trades=10,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
assert count == 5
|
assert count == 5
|
||||||
|
|
||||||
@ -979,7 +973,6 @@ def test_backtest_pricecontours_protections(default_conf, fee, mocker, testdatad
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=1,
|
max_open_trades=1,
|
||||||
position_stacking=False,
|
|
||||||
enable_protections=default_conf.get('enable_protections', False),
|
enable_protections=default_conf.get('enable_protections', False),
|
||||||
)
|
)
|
||||||
assert len(results['results']) == numres
|
assert len(results['results']) == numres
|
||||||
@ -1023,7 +1016,6 @@ def test_backtest_pricecontours(default_conf, fee, mocker, testdatadir,
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=1,
|
max_open_trades=1,
|
||||||
position_stacking=False,
|
|
||||||
enable_protections=default_conf.get('enable_protections', False),
|
enable_protections=default_conf.get('enable_protections', False),
|
||||||
)
|
)
|
||||||
assert len(results['results']) == expected
|
assert len(results['results']) == expected
|
||||||
@ -1136,7 +1128,6 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
|||||||
'start_date': min_date,
|
'start_date': min_date,
|
||||||
'end_date': max_date,
|
'end_date': max_date,
|
||||||
'max_open_trades': 3,
|
'max_open_trades': 3,
|
||||||
'position_stacking': False,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
results = backtesting.backtest(**backtest_conf)
|
results = backtesting.backtest(**backtest_conf)
|
||||||
@ -1159,7 +1150,6 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
|||||||
'start_date': min_date,
|
'start_date': min_date,
|
||||||
'end_date': max_date,
|
'end_date': max_date,
|
||||||
'max_open_trades': 1,
|
'max_open_trades': 1,
|
||||||
'position_stacking': False,
|
|
||||||
}
|
}
|
||||||
results = backtesting.backtest(**backtest_conf)
|
results = backtesting.backtest(**backtest_conf)
|
||||||
assert len(evaluate_result_multi(results['results'], '5m', 1)) == 0
|
assert len(evaluate_result_multi(results['results'], '5m', 1)) == 0
|
||||||
|
@ -42,7 +42,6 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
|
|||||||
start_date=min_date,
|
start_date=min_date,
|
||||||
end_date=max_date,
|
end_date=max_date,
|
||||||
max_open_trades=10,
|
max_open_trades=10,
|
||||||
position_stacking=False,
|
|
||||||
)
|
)
|
||||||
results = result['results']
|
results = result['results']
|
||||||
assert not results.empty
|
assert not results.empty
|
||||||
|
@ -336,7 +336,7 @@ def test_start_calls_optimizer(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
||||||
assert hasattr(hyperopt, "max_open_trades")
|
assert hasattr(hyperopt, "max_open_trades")
|
||||||
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
||||||
assert hasattr(hyperopt, "position_stacking")
|
assert hasattr(hyperopt.backtesting, "_position_stacking")
|
||||||
|
|
||||||
|
|
||||||
def test_hyperopt_format_results(hyperopt):
|
def test_hyperopt_format_results(hyperopt):
|
||||||
@ -704,7 +704,7 @@ def test_simplified_interface_roi_stoploss(mocker, hyperopt_conf, capsys) -> Non
|
|||||||
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
||||||
assert hasattr(hyperopt, "max_open_trades")
|
assert hasattr(hyperopt, "max_open_trades")
|
||||||
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
||||||
assert hasattr(hyperopt, "position_stacking")
|
assert hasattr(hyperopt.backtesting, "_position_stacking")
|
||||||
|
|
||||||
|
|
||||||
def test_simplified_interface_all_failed(mocker, hyperopt_conf, caplog) -> None:
|
def test_simplified_interface_all_failed(mocker, hyperopt_conf, caplog) -> None:
|
||||||
@ -778,7 +778,7 @@ def test_simplified_interface_buy(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
||||||
assert hasattr(hyperopt, "max_open_trades")
|
assert hasattr(hyperopt, "max_open_trades")
|
||||||
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
||||||
assert hasattr(hyperopt, "position_stacking")
|
assert hasattr(hyperopt.backtesting, "_position_stacking")
|
||||||
|
|
||||||
|
|
||||||
def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
||||||
@ -821,7 +821,7 @@ def test_simplified_interface_sell(mocker, hyperopt_conf, capsys) -> None:
|
|||||||
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
assert hasattr(hyperopt.backtesting.strategy, "advise_entry")
|
||||||
assert hasattr(hyperopt, "max_open_trades")
|
assert hasattr(hyperopt, "max_open_trades")
|
||||||
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
assert hyperopt.max_open_trades == hyperopt_conf['max_open_trades']
|
||||||
assert hasattr(hyperopt, "position_stacking")
|
assert hasattr(hyperopt.backtesting, "_position_stacking")
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("space", [
|
@pytest.mark.parametrize("space", [
|
||||||
|
Loading…
Reference in New Issue
Block a user