Move most logic to history

This commit is contained in:
Matthias 2019-10-20 14:02:53 +02:00
parent 9c7696a8ce
commit 704121c197
3 changed files with 29 additions and 15 deletions

View File

@ -8,6 +8,7 @@ Includes:
import logging
import operator
from copy import deepcopy
from datetime import datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Tuple
@ -19,7 +20,7 @@ from pandas import DataFrame
from freqtrade import OperationalException, misc
from freqtrade.configuration import TimeRange
from freqtrade.data.converter import parse_ticker_dataframe, trades_to_ohlcv
from freqtrade.exchange import Exchange, timeframe_to_minutes
from freqtrade.exchange import Exchange, timeframe_to_minutes, timeframe_to_seconds
logger = logging.getLogger(__name__)
@ -127,7 +128,8 @@ def load_pair_history(pair: str,
refresh_pairs: bool = False,
exchange: Optional[Exchange] = None,
fill_up_missing: bool = True,
drop_incomplete: bool = True
drop_incomplete: bool = True,
startup_candles: int = 0,
) -> DataFrame:
"""
Loads cached ticker history for the given pair.
@ -140,9 +142,15 @@ def load_pair_history(pair: str,
:param exchange: Exchange object (needed when using "refresh_pairs")
:param fill_up_missing: Fill missing values with "No action"-candles
:param drop_incomplete: Drop last candle assuming it may be incomplete.
:param startup_candles: Additional candles to load at the start of the period
:return: DataFrame with ohlcv data
"""
timerange_startup = deepcopy(timerange)
if startup_candles:
logger.info('Using indicator startup period: %s ...', startup_candles)
timerange_startup.subtract_start(timeframe_to_seconds(ticker_interval) * startup_candles)
# The user forced the refresh of pairs
if refresh_pairs:
download_pair_history(datadir=datadir,
@ -151,11 +159,11 @@ def load_pair_history(pair: str,
ticker_interval=ticker_interval,
timerange=timerange)
pairdata = load_tickerdata_file(datadir, pair, ticker_interval, timerange=timerange)
pairdata = load_tickerdata_file(datadir, pair, ticker_interval, timerange=timerange_startup)
if pairdata:
if timerange:
_validate_pairdata(pair, pairdata, timerange)
if timerange_startup:
_validate_pairdata(pair, pairdata, timerange_startup)
return parse_ticker_dataframe(pairdata, ticker_interval, pair=pair,
fill_missing=fill_up_missing,
drop_incomplete=drop_incomplete)
@ -174,10 +182,20 @@ def load_data(datadir: Path,
exchange: Optional[Exchange] = None,
timerange: Optional[TimeRange] = None,
fill_up_missing: bool = True,
startup_candles: int = 0,
) -> Dict[str, DataFrame]:
"""
Loads ticker history data for a list of pairs
:return: dict(<pair>:<tickerlist>)
:param datadir: Path to the data storage location.
:param ticker_interval: Ticker-interval (e.g. "5m")
:param pairs: List of pairs to load
:param refresh_pairs: Refresh pairs from exchange.
(Note: Requires exchange to be passed as well.)
:param exchange: Exchange object (needed when using "refresh_pairs")
:param timerange: Limit data to be loaded to this timerange
:param fill_up_missing: Fill missing values with "No action"-candles
:param startup_candles: Additional candles to load at the start of the period
:return: dict(<pair>:<Dataframe>)
TODO: refresh_pairs is still used by edge to keep the data uptodate.
This should be replaced in the future. Instead, writing the current candles to disk
from dataprovider should be implemented, as this would avoid loading ohlcv data twice.

View File

@ -92,7 +92,6 @@ class Backtesting:
# Get maximum required startup period
self.required_startup = max([strat.startup_candle_count for strat in self.strategylist])
self.required_startup_s = self.required_startup * timeframe_to_seconds(self.ticker_interval)
# Load one (first) strategy
self._set_strategy(self.strategylist[0])
@ -422,11 +421,6 @@ class Backtesting:
timerange = TimeRange.parse_timerange(None if self.config.get(
'timerange') is None else str(self.config.get('timerange')))
logger.info('Using indicator startup period: %s ...', self.required_startup)
# Timerange_startup is timerange - startup-candles
timerange_startup = deepcopy(timerange)
timerange_startup.subtract_start(self.required_startup_s)
data = history.load_data(
datadir=Path(self.config['datadir']),
@ -453,10 +447,12 @@ class Backtesting:
'Loading backtest data from %s up to %s (%s days)..',
min_date.isoformat(), max_date.isoformat(), (max_date - min_date).days
)
if not timerange_startup.starttype:
if not timerange.starttype:
# If no startts was defined, we need to move the backtesting start
logger.info("Moving start-date by %s candles.", self.required_startup)
timerange.startts = min_date.timestamp + self.required_startup_s
timerange.startts = (min_date.timestamp
+ timeframe_to_seconds(self.ticker_interval)
* self.required_startup)
timerange.starttype = 'date'
for strat in self.strategylist:

View File

@ -117,7 +117,7 @@ def simple_backtest(config, contour, num_results, mocker, testdatadir) -> None:
def mocked_load_data(datadir, pairs=[], ticker_interval='0m', refresh_pairs=False,
timerange=None, exchange=None, live=False):
timerange=None, exchange=None, live=False, startup_candles=0):
tickerdata = history.load_tickerdata_file(datadir, 'UNITTEST/BTC', '1m', timerange=timerange)
pairdata = {'UNITTEST/BTC': parse_ticker_dataframe(tickerdata, '1m', pair="UNITTEST/BTC",
fill_missing=True)}