Merge pull request #315 from kryofly/tests_jan05

tests cover more backtesting
This commit is contained in:
Janne Sinivirta 2018-01-06 09:26:20 +02:00 committed by GitHub
commit 41933c31ca
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 73 additions and 39 deletions

View File

@ -12,6 +12,27 @@ from freqtrade.analyze import populate_indicators, parse_ticker_dataframe
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def load_tickerdata_file(pair, ticker_interval):
"""
Load a pair from file,
:return dict OR empty if unsuccesful
"""
path = testdata_path()
file = '{abspath}/{pair}-{ticker_interval}.json'.format(
abspath=path,
pair=pair,
ticker_interval=ticker_interval,
)
# The file does not exist we download it
if not os.path.isfile(file):
return None
# Read the file, load the json
with open(file) as tickerdata:
pairdata = json.load(tickerdata)
return pairdata
def load_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None, def load_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None,
refresh_pairs: Optional[bool] = False) -> Dict[str, List]: refresh_pairs: Optional[bool] = False) -> Dict[str, List]:
""" """
@ -20,7 +41,6 @@ def load_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None,
:param pairs: list of pairs :param pairs: list of pairs
:return: dict :return: dict
""" """
path = testdata_path()
result = {} result = {}
_pairs = pairs or hyperopt_optimize_conf()['exchange']['pair_whitelist'] _pairs = pairs or hyperopt_optimize_conf()['exchange']['pair_whitelist']
@ -31,18 +51,13 @@ def load_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None,
download_pairs(_pairs) download_pairs(_pairs)
for pair in _pairs: for pair in _pairs:
file = '{abspath}/{pair}-{ticker_interval}.json'.format( pairdata = load_tickerdata_file(pair, ticker_interval)
abspath=path, if not pairdata:
pair=pair, # download the tickerdata from exchange
ticker_interval=ticker_interval,
)
# The file does not exist we download it
if not os.path.isfile(file):
download_backtesting_testdata(pair=pair, interval=ticker_interval) download_backtesting_testdata(pair=pair, interval=ticker_interval)
# and retry reading the pair
# Read the file, load the json pairdata = load_tickerdata_file(pair, ticker_interval)
with open(file) as tickerdata: result[pair] = pairdata
result[pair] = json.load(tickerdata)
return result return result

View File

@ -12,8 +12,9 @@ from freqtrade import exchange
from freqtrade.analyze import populate_buy_trend, populate_sell_trend from freqtrade.analyze import populate_buy_trend, populate_sell_trend
from freqtrade.exchange import Bittrex from freqtrade.exchange import Bittrex
from freqtrade.main import min_roi_reached from freqtrade.main import min_roi_reached
from freqtrade.misc import load_config import freqtrade.misc as misc
from freqtrade.optimize import load_data, preprocess from freqtrade.optimize import preprocess
import freqtrade.optimize as optimize
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -149,7 +150,7 @@ def start(args):
exchange._API = Bittrex({'key': '', 'secret': ''}) exchange._API = Bittrex({'key': '', 'secret': ''})
logger.info('Using config: %s ...', args.config) logger.info('Using config: %s ...', args.config)
config = load_config(args.config) config = misc.load_config(args.config)
logger.info('Using ticker_interval: %s ...', args.ticker_interval) logger.info('Using ticker_interval: %s ...', args.ticker_interval)
@ -161,8 +162,8 @@ def start(args):
data[pair] = exchange.get_ticker_history(pair, args.ticker_interval) data[pair] = exchange.get_ticker_history(pair, args.ticker_interval)
else: else:
logger.info('Using local backtesting data (using whitelist in given config) ...') logger.info('Using local backtesting data (using whitelist in given config) ...')
data = load_data(pairs=pairs, ticker_interval=args.ticker_interval, data = optimize.load_data(pairs=pairs, ticker_interval=args.ticker_interval,
refresh_pairs=args.refresh_pairs) refresh_pairs=args.refresh_pairs)
logger.info('Using stake_currency: %s ...', config['stake_currency']) logger.info('Using stake_currency: %s ...', config['stake_currency'])
logger.info('Using stake_amount: %s ...', config['stake_amount']) logger.info('Using stake_amount: %s ...', config['stake_amount'])

View File

@ -1,13 +1,14 @@
# pragma pylint: disable=missing-docstring,W0212 # pragma pylint: disable=missing-docstring,W0212
import logging
import math import math
import pandas as pd import pandas as pd
# from unittest.mock import MagicMock from unittest.mock import MagicMock
from freqtrade import exchange, optimize from freqtrade import exchange, optimize
from freqtrade.exchange import Bittrex from freqtrade.exchange import Bittrex
from freqtrade.optimize import preprocess from freqtrade.optimize import preprocess
from freqtrade.optimize.backtesting import backtest, generate_text_table, get_timeframe from freqtrade.optimize.backtesting import backtest, generate_text_table, get_timeframe
# import freqtrade.optimize.backtesting as backtesting import freqtrade.optimize.backtesting as backtesting
def test_generate_text_table(): def test_generate_text_table():
@ -61,7 +62,6 @@ def test_backtest_1min_ticker_interval(default_conf, mocker):
def trim_dictlist(dl, num): def trim_dictlist(dl, num):
new = {} new = {}
for pair, pair_data in dl.items(): for pair, pair_data in dl.items():
# Can't figure out why -num wont work
new[pair] = pair_data[num:] new[pair] = pair_data[num:]
return new return new
@ -148,21 +148,29 @@ def test_backtest_pricecontours(default_conf, mocker):
for [contour, numres] in tests: for [contour, numres] in tests:
simple_backtest(default_conf, contour, numres) simple_backtest(default_conf, contour, numres)
# Please make this work, the load_config needs to be mocked
# and cleanups. def mocked_load_data(pairs=[], ticker_interval=0, refresh_pairs=False):
# def test_backtest_start(default_conf, mocker): tickerdata = optimize.load_tickerdata_file('BTC_UNITEST', 1)
# default_conf['exchange']['pair_whitelist'] = ['BTC_UNITEST'] pairdata = {'BTC_UNITEST': tickerdata}
# mocker.patch.dict('freqtrade.main._CONF', default_conf) return trim_dictlist(pairdata, -100)
# # see https://pypi.python.org/pypi/pytest-mock/
# # and http://www.voidspace.org.uk/python/mock/patch.html
# # No usage example of simple function mocking, def test_backtest_start(default_conf, mocker, caplog):
# # and no documentation of side_effect default_conf['exchange']['pair_whitelist'] = ['BTC_UNITEST']
# mocker.patch('freqtrade.misc.load_config', new=lambda s, t: {}) mocker.patch.dict('freqtrade.main._CONF', default_conf)
# args = MagicMock() mocker.patch('freqtrade.misc.load_config', new=lambda s: default_conf)
# args.level = 10 mocker.patch.multiple('freqtrade.optimize',
# #load_config('foo') load_data=mocked_load_data)
# backtesting.start(args) args = MagicMock()
# args.ticker_interval = 1
# Check what sideeffect backtstesting has done. args.level = 10
# Probably need to capture standard-output and args.live = False
# check for the generated report table. backtesting.start(args)
# check the logs, that will contain the backtest result
exists = ['Using max_open_trades: 1 ...',
'Using stake_amount: 0.001 ...',
'Measuring data from 2017-11-14T21:17:00+00:00 up to 2017-11-14T22:59:00+00:00 ...']
for line in exists:
assert ('freqtrade.optimize.backtesting',
logging.INFO,
line) in caplog.record_tuples

View File

@ -5,7 +5,11 @@ import logging
from shutil import copyfile from shutil import copyfile
from freqtrade import exchange, optimize from freqtrade import exchange, optimize
from freqtrade.exchange import Bittrex from freqtrade.exchange import Bittrex
from freqtrade.optimize.__init__ import testdata_path, download_pairs, download_backtesting_testdata from freqtrade.optimize.__init__ import testdata_path, download_pairs,\
download_backtesting_testdata, load_tickerdata_file
# Change this if modifying BTC_UNITEST testdatafile
_btc_unittest_length = 13681
def _backup_file(file: str, copy_file: bool = False) -> None: def _backup_file(file: str, copy_file: bool = False) -> None:
@ -164,3 +168,9 @@ def test_download_backtesting_testdata(default_conf, ticker_history, mocker):
download_backtesting_testdata(pair="BTC-STORJ", interval=5) download_backtesting_testdata(pair="BTC-STORJ", interval=5)
assert os.path.isfile(file2) is True assert os.path.isfile(file2) is True
_clean_test_file(file2) _clean_test_file(file2)
def test_load_tickerdata_file():
assert not load_tickerdata_file('BTC_UNITEST', 7)
tickerdata = load_tickerdata_file('BTC_UNITEST', 1)
assert _btc_unittest_length == len(tickerdata)