extract backtesting abort functionality
This commit is contained in:
parent
5474d5ee64
commit
005da97183
@ -189,6 +189,15 @@ class Backtesting:
|
|||||||
self.rejected_trades = 0
|
self.rejected_trades = 0
|
||||||
self.dataprovider.clear_cache()
|
self.dataprovider.clear_cache()
|
||||||
|
|
||||||
|
def check_abort(self):
|
||||||
|
"""
|
||||||
|
Check if abort was requested, raise DependencyException if that's the case
|
||||||
|
Only applies to Interactive backtest mode (webserver mode)
|
||||||
|
"""
|
||||||
|
if self.abort:
|
||||||
|
self.abort = False
|
||||||
|
raise DependencyException("Stop requested")
|
||||||
|
|
||||||
def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]:
|
def _get_ohlcv_as_lists(self, processed: Dict[str, DataFrame]) -> Dict[str, Tuple]:
|
||||||
"""
|
"""
|
||||||
Helper function to convert a processed dataframes into lists for performance reasons.
|
Helper function to convert a processed dataframes into lists for performance reasons.
|
||||||
@ -203,8 +212,7 @@ class Backtesting:
|
|||||||
|
|
||||||
# Create dict with data
|
# Create dict with data
|
||||||
for pair, pair_data in processed.items():
|
for pair, pair_data in processed.items():
|
||||||
if self.abort:
|
self.check_abort()
|
||||||
raise DependencyException("Stop requested")
|
|
||||||
self.progress.increment()
|
self.progress.increment()
|
||||||
if not pair_data.empty:
|
if not pair_data.empty:
|
||||||
pair_data.loc[:, 'buy'] = 0 # cleanup if buy_signal is exist
|
pair_data.loc[:, 'buy'] = 0 # cleanup if buy_signal is exist
|
||||||
@ -422,8 +430,7 @@ class Backtesting:
|
|||||||
# Loop timerange and get candle for each pair at that point in time
|
# Loop timerange and get candle for each pair at that point in time
|
||||||
while tmp <= end_date:
|
while tmp <= end_date:
|
||||||
open_trade_count_start = open_trade_count
|
open_trade_count_start = open_trade_count
|
||||||
if self.abort:
|
self.check_abort()
|
||||||
raise DependencyException("Stop requested")
|
|
||||||
for i, pair in enumerate(data):
|
for i, pair in enumerate(data):
|
||||||
row_index = indexes[pair]
|
row_index = indexes[pair]
|
||||||
try:
|
try:
|
||||||
|
@ -52,8 +52,8 @@ async def api_start_backtest(bt_settings: BacktestRequest, background_tasks: Bac
|
|||||||
# TODO: Investigate if enabling protections can be dynamically ingested from here...
|
# TODO: Investigate if enabling protections can be dynamically ingested from here...
|
||||||
from freqtrade.optimize.backtesting import Backtesting
|
from freqtrade.optimize.backtesting import Backtesting
|
||||||
ApiServer._bt = Backtesting(btconfig)
|
ApiServer._bt = Backtesting(btconfig)
|
||||||
# Reset data if backtesting is reloaded
|
|
||||||
|
|
||||||
|
# Only reload data if timeframe or timerange changed.
|
||||||
if (not ApiServer._backtestdata or not ApiServer._bt_timerange
|
if (not ApiServer._backtestdata or not ApiServer._bt_timerange
|
||||||
or lastconfig.get('timerange') != btconfig['timerange']
|
or lastconfig.get('timerange') != btconfig['timerange']
|
||||||
or lastconfig.get('timeframe') != strat.timeframe):
|
or lastconfig.get('timeframe') != strat.timeframe):
|
||||||
|
@ -346,6 +346,20 @@ def test_data_to_dataframe_bt(default_conf, mocker, testdatadir) -> None:
|
|||||||
assert processed['UNITTEST/BTC'].equals(processed2['UNITTEST/BTC'])
|
assert processed['UNITTEST/BTC'].equals(processed2['UNITTEST/BTC'])
|
||||||
|
|
||||||
|
|
||||||
|
def test_backtest_abort(default_conf, mocker, testdatadir) -> None:
|
||||||
|
patch_exchange(mocker)
|
||||||
|
backtesting = Backtesting(default_conf)
|
||||||
|
backtesting.check_abort()
|
||||||
|
|
||||||
|
backtesting.abort = True
|
||||||
|
|
||||||
|
with pytest.raises(DependencyException, match="Stop requested"):
|
||||||
|
backtesting.check_abort()
|
||||||
|
# abort flag resets
|
||||||
|
assert backtesting.abort is False
|
||||||
|
assert backtesting.progress.progress == 0
|
||||||
|
|
||||||
|
|
||||||
def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
def test_backtesting_start(default_conf, mocker, testdatadir, caplog) -> None:
|
||||||
def get_timerange(input1):
|
def get_timerange(input1):
|
||||||
return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
|
return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
|
||||||
|
@ -1252,10 +1252,6 @@ def test_api_backtesting(botclient, mocker, fee):
|
|||||||
assert not result['running']
|
assert not result['running']
|
||||||
assert result['status_msg'] == 'Backtest reset'
|
assert result['status_msg'] == 'Backtest reset'
|
||||||
|
|
||||||
# bt_mock = mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest_one_strategy',
|
|
||||||
# return_value=(1, 2))
|
|
||||||
# stats_mock = mocker.patch('freqtrade.optimize.optimize_reports.generate_backtest_stats')
|
|
||||||
# bt_mock.load_bt_data = MagicMock(return_value=(xxx, 'asdfadf'))
|
|
||||||
# start backtesting
|
# start backtesting
|
||||||
data = {
|
data = {
|
||||||
"strategy": "DefaultStrategy",
|
"strategy": "DefaultStrategy",
|
||||||
@ -1285,6 +1281,13 @@ def test_api_backtesting(botclient, mocker, fee):
|
|||||||
assert result['progress'] == 1
|
assert result['progress'] == 1
|
||||||
assert result['backtest_result']
|
assert result['backtest_result']
|
||||||
|
|
||||||
|
rc = client_get(client, f"{BASE_URI}/backtest/abort")
|
||||||
|
assert_response(rc)
|
||||||
|
result = rc.json()
|
||||||
|
assert result['status'] == 'not_running'
|
||||||
|
assert not result['running']
|
||||||
|
assert result['status_msg'] == 'Backtest ended'
|
||||||
|
|
||||||
# Delete backtesting to avoid leakage since the backtest-object may stick around.
|
# Delete backtesting to avoid leakage since the backtest-object may stick around.
|
||||||
rc = client_delete(client, f"{BASE_URI}/backtest")
|
rc = client_delete(client, f"{BASE_URI}/backtest")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
|
Loading…
Reference in New Issue
Block a user