refactor get_timeframe out of backtesting class
This commit is contained in:
parent
8a3272e7c5
commit
d7459bbbf3
@ -11,7 +11,10 @@ except ImportError:
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
from typing import Optional, List, Dict, Tuple, Any
|
from typing import Optional, List, Dict, Tuple, Any
|
||||||
|
import operator
|
||||||
|
|
||||||
import arrow
|
import arrow
|
||||||
|
from pandas import DataFrame
|
||||||
|
|
||||||
from freqtrade import misc, constants, OperationalException
|
from freqtrade import misc, constants, OperationalException
|
||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
@ -59,6 +62,20 @@ def trim_tickerlist(tickerlist: List[Dict], timerange: TimeRange) -> List[Dict]:
|
|||||||
return tickerlist[start_index:stop_index]
|
return tickerlist[start_index:stop_index]
|
||||||
|
|
||||||
|
|
||||||
|
def get_timeframe(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]:
|
||||||
|
"""
|
||||||
|
Get the maximum timeframe for the given backtest data
|
||||||
|
:param data: dictionary with preprocessed backtesting data
|
||||||
|
:return: tuple containing min_date, max_date
|
||||||
|
"""
|
||||||
|
timeframe = [
|
||||||
|
(arrow.get(frame['date'].min()), arrow.get(frame['date'].max()))
|
||||||
|
for frame in data.values()
|
||||||
|
]
|
||||||
|
return min(timeframe, key=operator.itemgetter(0))[0], \
|
||||||
|
max(timeframe, key=operator.itemgetter(1))[1]
|
||||||
|
|
||||||
|
|
||||||
def load_tickerdata_file(
|
def load_tickerdata_file(
|
||||||
datadir: str, pair: str,
|
datadir: str, pair: str,
|
||||||
ticker_interval: str,
|
ticker_interval: str,
|
||||||
|
@ -4,14 +4,12 @@
|
|||||||
This module contains the backtesting logic
|
This module contains the backtesting logic
|
||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
import operator
|
|
||||||
from argparse import Namespace
|
from argparse import Namespace
|
||||||
from copy import deepcopy
|
from copy import deepcopy
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Dict, List, NamedTuple, Optional, Tuple
|
from typing import Any, Dict, List, NamedTuple, Optional
|
||||||
|
|
||||||
import arrow
|
|
||||||
from pandas import DataFrame
|
from pandas import DataFrame
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
@ -91,20 +89,6 @@ class Backtesting(object):
|
|||||||
self.advise_buy = strategy.advise_buy
|
self.advise_buy = strategy.advise_buy
|
||||||
self.advise_sell = strategy.advise_sell
|
self.advise_sell = strategy.advise_sell
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_timeframe(data: Dict[str, DataFrame]) -> Tuple[arrow.Arrow, arrow.Arrow]:
|
|
||||||
"""
|
|
||||||
Get the maximum timeframe for the given backtest data
|
|
||||||
:param data: dictionary with preprocessed backtesting data
|
|
||||||
:return: tuple containing min_date, max_date
|
|
||||||
"""
|
|
||||||
timeframe = [
|
|
||||||
(arrow.get(frame['date'].min()), arrow.get(frame['date'].max()))
|
|
||||||
for frame in data.values()
|
|
||||||
]
|
|
||||||
return min(timeframe, key=operator.itemgetter(0))[0], \
|
|
||||||
max(timeframe, key=operator.itemgetter(1))[1]
|
|
||||||
|
|
||||||
def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame,
|
def _generate_text_table(self, data: Dict[str, Dict], results: DataFrame,
|
||||||
skip_nan: bool = False) -> str:
|
skip_nan: bool = False) -> str:
|
||||||
"""
|
"""
|
||||||
@ -373,7 +357,7 @@ class Backtesting(object):
|
|||||||
preprocessed = self.strategy.tickerdata_to_dataframe(data)
|
preprocessed = self.strategy.tickerdata_to_dataframe(data)
|
||||||
|
|
||||||
# Print timeframe
|
# Print timeframe
|
||||||
min_date, max_date = self.get_timeframe(preprocessed)
|
min_date, max_date = optimize.get_timeframe(preprocessed)
|
||||||
logger.info(
|
logger.info(
|
||||||
'Measuring data from %s up to %s (%s days)..',
|
'Measuring data from %s up to %s (%s days)..',
|
||||||
min_date.isoformat(),
|
min_date.isoformat(),
|
||||||
|
@ -336,22 +336,6 @@ def test_tickerdata_to_dataframe(default_conf, mocker) -> None:
|
|||||||
assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC'])
|
assert data['UNITTEST/BTC'].equals(data2['UNITTEST/BTC'])
|
||||||
|
|
||||||
|
|
||||||
def test_get_timeframe(default_conf, mocker) -> None:
|
|
||||||
patch_exchange(mocker)
|
|
||||||
backtesting = Backtesting(default_conf)
|
|
||||||
|
|
||||||
data = backtesting.strategy.tickerdata_to_dataframe(
|
|
||||||
optimize.load_data(
|
|
||||||
None,
|
|
||||||
ticker_interval='1m',
|
|
||||||
pairs=['UNITTEST/BTC']
|
|
||||||
)
|
|
||||||
)
|
|
||||||
min_date, max_date = backtesting.get_timeframe(data)
|
|
||||||
assert min_date.isoformat() == '2017-11-04T23:02:00+00:00'
|
|
||||||
assert max_date.isoformat() == '2017-11-14T22:58:00+00:00'
|
|
||||||
|
|
||||||
|
|
||||||
def test_generate_text_table(default_conf, mocker):
|
def test_generate_text_table(default_conf, mocker):
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
backtesting = Backtesting(default_conf)
|
backtesting = Backtesting(default_conf)
|
||||||
@ -451,17 +435,17 @@ def test_generate_text_table_strategyn(default_conf, mocker):
|
|||||||
|
|
||||||
|
|
||||||
def test_backtesting_start(default_conf, mocker, caplog) -> None:
|
def test_backtesting_start(default_conf, mocker, caplog) -> None:
|
||||||
def get_timeframe(input1, input2):
|
def get_timeframe(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)
|
||||||
|
|
||||||
mocker.patch('freqtrade.optimize.load_data', mocked_load_data)
|
mocker.patch('freqtrade.optimize.load_data', mocked_load_data)
|
||||||
|
mocker.patch('freqtrade.optimize.get_timeframe', get_timeframe)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.refresh_tickers', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.refresh_tickers', MagicMock())
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.optimize.backtesting.Backtesting',
|
'freqtrade.optimize.backtesting.Backtesting',
|
||||||
backtest=MagicMock(),
|
backtest=MagicMock(),
|
||||||
_generate_text_table=MagicMock(return_value='1'),
|
_generate_text_table=MagicMock(return_value='1'),
|
||||||
get_timeframe=get_timeframe,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
|
default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
|
||||||
@ -486,17 +470,17 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None:
|
|||||||
|
|
||||||
|
|
||||||
def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
|
def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
|
||||||
def get_timeframe(input1, input2):
|
def get_timeframe(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)
|
||||||
|
|
||||||
mocker.patch('freqtrade.optimize.load_data', MagicMock(return_value={}))
|
mocker.patch('freqtrade.optimize.load_data', MagicMock(return_value={}))
|
||||||
|
mocker.patch('freqtrade.optimize.get_timeframe', get_timeframe)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.refresh_tickers', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.refresh_tickers', MagicMock())
|
||||||
patch_exchange(mocker)
|
patch_exchange(mocker)
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.optimize.backtesting.Backtesting',
|
'freqtrade.optimize.backtesting.Backtesting',
|
||||||
backtest=MagicMock(),
|
backtest=MagicMock(),
|
||||||
_generate_text_table=MagicMock(return_value='1'),
|
_generate_text_table=MagicMock(return_value='1'),
|
||||||
get_timeframe=get_timeframe,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
|
default_conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
|
||||||
|
@ -15,7 +15,8 @@ from freqtrade.optimize.__init__ import (download_backtesting_testdata,
|
|||||||
load_cached_data_for_updating,
|
load_cached_data_for_updating,
|
||||||
load_tickerdata_file,
|
load_tickerdata_file,
|
||||||
make_testdata_path, trim_tickerlist)
|
make_testdata_path, trim_tickerlist)
|
||||||
from freqtrade.tests.conftest import get_patched_exchange, log_has
|
from freqtrade.strategy.default_strategy import DefaultStrategy
|
||||||
|
from freqtrade.tests.conftest import get_patched_exchange, log_has, patch_exchange
|
||||||
|
|
||||||
# Change this if modifying UNITTEST/BTC testdatafile
|
# Change this if modifying UNITTEST/BTC testdatafile
|
||||||
_BTC_UNITTEST_LENGTH = 13681
|
_BTC_UNITTEST_LENGTH = 13681
|
||||||
@ -433,3 +434,19 @@ def test_file_dump_json() -> None:
|
|||||||
|
|
||||||
# Remove the file
|
# Remove the file
|
||||||
_clean_test_file(file)
|
_clean_test_file(file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_timeframe(default_conf, mocker) -> None:
|
||||||
|
patch_exchange(mocker)
|
||||||
|
strategy = DefaultStrategy(default_conf)
|
||||||
|
|
||||||
|
data = strategy.tickerdata_to_dataframe(
|
||||||
|
optimize.load_data(
|
||||||
|
None,
|
||||||
|
ticker_interval='1m',
|
||||||
|
pairs=['UNITTEST/BTC']
|
||||||
|
)
|
||||||
|
)
|
||||||
|
min_date, max_date = optimize.get_timeframe(data)
|
||||||
|
assert min_date.isoformat() == '2017-11-04T23:02:00+00:00'
|
||||||
|
assert max_date.isoformat() == '2017-11-14T22:58:00+00:00'
|
||||||
|
Loading…
Reference in New Issue
Block a user