Merge pull request #1879 from freqtrade/refactor_optimize__init__

Speed up startup time
This commit is contained in:
Matthias
2019-05-29 06:18:57 +02:00
committed by GitHub
18 changed files with 283 additions and 301 deletions

View File

@@ -2,8 +2,7 @@
import logging
from freqtrade.data.converter import parse_ticker_dataframe, ohlcv_fill_up_missing_data
from freqtrade.data.history import load_pair_history
from freqtrade.optimize import validate_backtest_data, get_timeframe
from freqtrade.data.history import load_pair_history, validate_backtest_data, get_timeframe
from freqtrade.tests.conftest import log_has

View File

@@ -2,24 +2,25 @@
import json
import os
from pathlib import Path
import uuid
from pathlib import Path
from shutil import copyfile
import arrow
from pandas import DataFrame
import pytest
from pandas import DataFrame
from freqtrade import OperationalException
from freqtrade.arguments import TimeRange
from freqtrade.data import history
from freqtrade.data.history import (download_pair_history,
load_cached_data_for_updating,
load_tickerdata_file,
make_testdata_path,
load_tickerdata_file, make_testdata_path,
trim_tickerlist)
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.misc import file_dump_json
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
_BTC_UNITTEST_LENGTH = 13681
@@ -495,3 +496,62 @@ def test_file_dump_json_tofile() -> None:
# Remove the 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(
history.load_data(
datadir=None,
ticker_interval='1m',
pairs=['UNITTEST/BTC']
)
)
min_date, max_date = history.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_validate_backtest_data_warn(default_conf, mocker, caplog) -> None:
patch_exchange(mocker)
strategy = DefaultStrategy(default_conf)
data = strategy.tickerdata_to_dataframe(
history.load_data(
datadir=None,
ticker_interval='1m',
pairs=['UNITTEST/BTC'],
fill_up_missing=False
)
)
min_date, max_date = history.get_timeframe(data)
caplog.clear()
assert history.validate_backtest_data(data, min_date, max_date,
timeframe_to_minutes('1m'))
assert len(caplog.record_tuples) == 1
assert log_has(
"UNITTEST/BTC has missing frames: expected 14396, got 13680, that's 716 missing values",
caplog.record_tuples)
def test_validate_backtest_data(default_conf, mocker, caplog) -> None:
patch_exchange(mocker)
strategy = DefaultStrategy(default_conf)
timerange = TimeRange('index', 'index', 200, 250)
data = strategy.tickerdata_to_dataframe(
history.load_data(
datadir=None,
ticker_interval='5m',
pairs=['UNITTEST/BTC'],
timerange=timerange
)
)
min_date, max_date = history.get_timeframe(data)
caplog.clear()
assert not history.validate_backtest_data(data, min_date, max_date,
timeframe_to_minutes('5m'))
assert len(caplog.record_tuples) == 0

View File

@@ -2,17 +2,17 @@
import logging
from unittest.mock import MagicMock
from pandas import DataFrame
import pytest
from pandas import DataFrame
from freqtrade.optimize import get_timeframe
from freqtrade.data.history import get_timeframe
from freqtrade.optimize.backtesting import Backtesting
from freqtrade.strategy.interface import SellType
from freqtrade.tests.optimize import (BTrade, BTContainer, _build_backtest_dataframe,
_get_frame_time_from_offset, tests_ticker_interval)
from freqtrade.tests.conftest import patch_exchange
from freqtrade.tests.optimize import (BTContainer, BTrade,
_build_backtest_dataframe,
_get_frame_time_from_offset,
tests_ticker_interval)
# Test 1 Minus 8% Close
# Test with Stop-loss at 1%

View File

@@ -17,9 +17,9 @@ from freqtrade.data import history
from freqtrade.data.btanalysis import evaluate_result_multi
from freqtrade.data.converter import parse_ticker_dataframe
from freqtrade.data.dataprovider import DataProvider
from freqtrade.optimize import get_timeframe
from freqtrade.optimize.backtesting import (Backtesting, setup_configuration,
start)
from freqtrade.data.history import get_timeframe
from freqtrade.optimize import setup_configuration, start_backtesting
from freqtrade.optimize.backtesting import Backtesting
from freqtrade.state import RunMode
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import SellType
@@ -178,7 +178,7 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
'backtesting'
]
config = setup_configuration(get_args(args))
config = setup_configuration(get_args(args), RunMode.BACKTEST)
assert 'max_open_trades' in config
assert 'stake_currency' in config
assert 'stake_amount' in config
@@ -228,7 +228,7 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
'--export-filename', 'foo_bar.json'
]
config = setup_configuration(get_args(args))
config = setup_configuration(get_args(args), RunMode.BACKTEST)
assert 'max_open_trades' in config
assert 'stake_currency' in config
assert 'stake_amount' in config
@@ -290,7 +290,7 @@ def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog
]
with pytest.raises(DependencyException, match=r'.*stake amount.*'):
setup_configuration(get_args(args))
setup_configuration(get_args(args), RunMode.BACKTEST)
def test_start(mocker, fee, default_conf, caplog) -> None:
@@ -307,7 +307,7 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
'backtesting'
]
args = get_args(args)
start(args)
start_backtesting(args)
assert log_has(
'Starting freqtrade in Backtesting mode',
caplog.record_tuples
@@ -472,7 +472,7 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None:
return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
mocker.patch('freqtrade.data.history.load_data', mocked_load_data)
mocker.patch('freqtrade.optimize.get_timeframe', get_timeframe)
mocker.patch('freqtrade.data.history.get_timeframe', get_timeframe)
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock())
patch_exchange(mocker)
mocker.patch.multiple(
@@ -507,7 +507,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
return Arrow(2017, 11, 14, 21, 17), Arrow(2017, 11, 14, 22, 59)
mocker.patch('freqtrade.data.history.load_data', MagicMock(return_value={}))
mocker.patch('freqtrade.optimize.get_timeframe', get_timeframe)
mocker.patch('freqtrade.data.history.get_timeframe', get_timeframe)
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', MagicMock())
patch_exchange(mocker)
mocker.patch.multiple(
@@ -847,7 +847,7 @@ def test_backtest_start_live(default_conf, mocker, caplog):
'--disable-max-market-positions'
]
args = get_args(args)
start(args)
start_backtesting(args)
# check the logs, that will contain the backtest result
exists = [
'Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
@@ -901,7 +901,7 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog):
'TestStrategy',
]
args = get_args(args)
start(args)
start_backtesting(args)
# 2 backtests, 4 tables
assert backtestmock.call_count == 2
assert gen_table_mock.call_count == 4

View File

@@ -7,7 +7,8 @@ from unittest.mock import MagicMock
from freqtrade.arguments import Arguments
from freqtrade.edge import PairInfo
from freqtrade.optimize.edge_cli import EdgeCli, setup_configuration, start
from freqtrade.optimize import start_edge, setup_configuration
from freqtrade.optimize.edge_cli import EdgeCli
from freqtrade.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange
@@ -27,8 +28,8 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
'edge'
]
config = setup_configuration(get_args(args))
assert config['runmode'] == RunMode.EDGECLI
config = setup_configuration(get_args(args), RunMode.EDGE)
assert config['runmode'] == RunMode.EDGE
assert 'max_open_trades' in config
assert 'stake_currency' in config
@@ -67,14 +68,14 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N
'--stoplosses=-0.01,-0.10,-0.001'
]
config = setup_configuration(get_args(args))
config = setup_configuration(get_args(args), RunMode.EDGE)
assert 'max_open_trades' in config
assert 'stake_currency' in config
assert 'stake_amount' in config
assert 'exchange' in config
assert 'pair_whitelist' in config['exchange']
assert 'datadir' in config
assert config['runmode'] == RunMode.EDGECLI
assert config['runmode'] == RunMode.EDGE
assert log_has(
'Using data folder: {} ...'.format(config['datadir']),
caplog.record_tuples
@@ -106,7 +107,7 @@ def test_start(mocker, fee, edge_conf, caplog) -> None:
'edge'
]
args = get_args(args)
start(args)
start_edge(args)
assert log_has(
'Starting freqtrade in Edge mode',
caplog.record_tuples

View File

@@ -3,6 +3,7 @@ import json
import os
from datetime import datetime
from unittest.mock import MagicMock
from filelock import Timeout
import pandas as pd
import pytest
@@ -11,8 +12,9 @@ from freqtrade import DependencyException
from freqtrade.data.converter import parse_ticker_dataframe
from freqtrade.data.history import load_tickerdata_file
from freqtrade.optimize.default_hyperopt import DefaultHyperOpts
from freqtrade.optimize.hyperopt import Hyperopt, setup_configuration, start
from freqtrade.resolvers import HyperOptResolver
from freqtrade.optimize.hyperopt import Hyperopt, HYPEROPT_LOCKFILE
from freqtrade.optimize import setup_configuration, start_hyperopt
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
from freqtrade.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange
from freqtrade.tests.optimize.test_backtesting import get_args
@@ -52,7 +54,7 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca
'hyperopt'
]
config = setup_configuration(get_args(args))
config = setup_configuration(get_args(args), RunMode.HYPEROPT)
assert 'max_open_trades' in config
assert 'stake_currency' in config
assert 'stake_amount' in config
@@ -100,7 +102,7 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo
'--print-all'
]
config = setup_configuration(get_args(args))
config = setup_configuration(get_args(args), RunMode.HYPEROPT)
assert 'max_open_trades' in config
assert 'stake_currency' in config
assert 'stake_amount' in config
@@ -183,7 +185,7 @@ def test_start(mocker, default_conf, caplog) -> None:
'--epochs', '5'
]
args = get_args(args)
start(args)
start_hyperopt(args)
import pprint
pprint.pprint(caplog.record_tuples)
@@ -214,7 +216,7 @@ def test_start_no_data(mocker, default_conf, caplog) -> None:
'--epochs', '5'
]
args = get_args(args)
start(args)
start_hyperopt(args)
import pprint
pprint.pprint(caplog.record_tuples)
@@ -239,13 +241,35 @@ def test_start_failure(mocker, default_conf, caplog) -> None:
]
args = get_args(args)
with pytest.raises(DependencyException):
start(args)
start_hyperopt(args)
assert log_has(
"Please don't use --strategy for hyperopt.",
caplog.record_tuples
)
def test_start_filelock(mocker, default_conf, caplog) -> None:
start_mock = MagicMock(side_effect=Timeout(HYPEROPT_LOCKFILE))
mocker.patch(
'freqtrade.configuration.Configuration._load_config_file',
lambda *args, **kwargs: default_conf
)
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
patch_exchange(mocker)
args = [
'--config', 'config.json',
'hyperopt',
'--epochs', '5'
]
args = get_args(args)
start_hyperopt(args)
assert log_has(
"Another running instance of freqtrade Hyperopt detected.",
caplog.record_tuples
)
def test_loss_calculation_prefer_correct_trade_count(hyperopt) -> None:
correct = hyperopt.calculate_loss(1, hyperopt.target_trades, 20)

View File

@@ -1,66 +0,0 @@
# pragma pylint: disable=missing-docstring, protected-access, C0103
from freqtrade import optimize
from freqtrade.arguments import TimeRange
from freqtrade.data import history
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.tests.conftest import log_has, patch_exchange
def test_get_timeframe(default_conf, mocker) -> None:
patch_exchange(mocker)
strategy = DefaultStrategy(default_conf)
data = strategy.tickerdata_to_dataframe(
history.load_data(
datadir=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'
def test_validate_backtest_data_warn(default_conf, mocker, caplog) -> None:
patch_exchange(mocker)
strategy = DefaultStrategy(default_conf)
data = strategy.tickerdata_to_dataframe(
history.load_data(
datadir=None,
ticker_interval='1m',
pairs=['UNITTEST/BTC'],
fill_up_missing=False
)
)
min_date, max_date = optimize.get_timeframe(data)
caplog.clear()
assert optimize.validate_backtest_data(data, min_date, max_date,
timeframe_to_minutes('1m'))
assert len(caplog.record_tuples) == 1
assert log_has(
"UNITTEST/BTC has missing frames: expected 14396, got 13680, that's 716 missing values",
caplog.record_tuples)
def test_validate_backtest_data(default_conf, mocker, caplog) -> None:
patch_exchange(mocker)
strategy = DefaultStrategy(default_conf)
timerange = TimeRange('index', 'index', 200, 250)
data = strategy.tickerdata_to_dataframe(
history.load_data(
datadir=None,
ticker_interval='5m',
pairs=['UNITTEST/BTC'],
timerange=timerange
)
)
min_date, max_date = optimize.get_timeframe(data)
caplog.clear()
assert not optimize.validate_backtest_data(data, min_date, max_date,
timeframe_to_minutes('5m'))
assert len(caplog.record_tuples) == 0

View File

@@ -19,7 +19,7 @@ def test_parse_args_backtesting(mocker) -> None:
Test that main() can start backtesting and also ensure we can pass some specific arguments
further argument parsing is done in test_arguments.py
"""
backtesting_mock = mocker.patch('freqtrade.optimize.backtesting.start', MagicMock())
backtesting_mock = mocker.patch('freqtrade.optimize.start_backtesting', MagicMock())
main(['backtesting'])
assert backtesting_mock.call_count == 1
call_args = backtesting_mock.call_args[0][0]
@@ -32,7 +32,7 @@ def test_parse_args_backtesting(mocker) -> None:
def test_main_start_hyperopt(mocker) -> None:
hyperopt_mock = mocker.patch('freqtrade.optimize.hyperopt.start', MagicMock())
hyperopt_mock = mocker.patch('freqtrade.optimize.start_hyperopt', MagicMock())
main(['hyperopt'])
assert hyperopt_mock.call_count == 1
call_args = hyperopt_mock.call_args[0][0]