remove code duplicates

This commit is contained in:
gcarq 2017-11-17 17:54:31 +01:00
parent 8655c6c264
commit bdff29a472
4 changed files with 35 additions and 23 deletions

View File

@ -11,14 +11,14 @@ from typing import Dict, Optional, List
import requests import requests
from cachetools import cached, TTLCache from cachetools import cached, TTLCache
from jsonschema import validate
from freqtrade import __version__, exchange, persistence from freqtrade import __version__, exchange, persistence
from freqtrade.analyze import get_signal, SignalType from freqtrade.analyze import get_signal, SignalType
from freqtrade.misc import CONF_SCHEMA, State, get_state, update_state, parse_args, throttle
from freqtrade.misc import ( from freqtrade.misc import (
FreqtradeException FreqtradeException
) )
from freqtrade.misc import State, get_state, update_state, parse_args, throttle, \
load_config
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.rpc import telegram from freqtrade.rpc import telegram
@ -335,12 +335,7 @@ def main():
) )
# Load and validate configuration # Load and validate configuration
with open(args.config) as file: _CONF = load_config(args.config)
_CONF = json.load(file)
if 'internals' not in _CONF:
_CONF['internals'] = {}
logger.info('Validating configuration ...')
validate(_CONF, CONF_SCHEMA)
# Initialize all modules and start main loop # Initialize all modules and start main loop
if args.dynamic_whitelist: if args.dynamic_whitelist:

View File

@ -1,10 +1,12 @@
import argparse import argparse
import enum import enum
import json
import logging import logging
import os import os
import time import time
from typing import Any, Callable, List from typing import Any, Callable, List, Dict
from jsonschema import validate
from wrapt import synchronized from wrapt import synchronized
from freqtrade import __version__ from freqtrade import __version__
@ -45,6 +47,21 @@ def get_state() -> State:
return _STATE return _STATE
def load_config(path: str) -> Dict:
"""
Loads a config file from the given path
:param path: path as str
:return: configuration as dictionary
"""
with open(path) as file:
conf = json.load(file)
if 'internals' not in conf:
conf['internals'] = {}
logger.info('Validating configuration ...')
validate(conf, CONF_SCHEMA)
return conf
def throttle(func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any: def throttle(func: Callable[..., Any], min_secs: float, *args, **kwargs) -> Any:
""" """
Throttles the given callable that it Throttles the given callable that it

View File

@ -1,13 +1,12 @@
# pragma pylint: disable=missing-docstring # pragma pylint: disable=missing-docstring
import json
import logging import logging
import os import os
from typing import Tuple, Dict from typing import Tuple, Dict
import arrow import arrow
import pytest import pytest
from arrow import Arrow
from pandas import DataFrame from pandas import DataFrame
from tabulate import tabulate from tabulate import tabulate
@ -16,6 +15,7 @@ from freqtrade.analyze import parse_ticker_dataframe, populate_indicators, \
populate_buy_trend, populate_sell_trend 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
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.tests import load_backtesting_data from freqtrade.tests import load_backtesting_data
@ -32,11 +32,6 @@ def format_results(results: DataFrame):
) )
def print_pair_results(pair: str, results: DataFrame):
print('For currency {}:'.format(pair))
print(format_results(results[results.currency == pair]))
def preprocess(backdata) -> Dict[str, DataFrame]: def preprocess(backdata) -> Dict[str, DataFrame]:
processed = {} processed = {}
for pair, pair_data in backdata.items(): for pair, pair_data in backdata.items():
@ -44,7 +39,7 @@ def preprocess(backdata) -> Dict[str, DataFrame]:
return processed return processed
def get_timeframe(data: Dict[str, Dict]) -> Tuple[Arrow, Arrow]: def get_timeframe(data: Dict[str, Dict]) -> Tuple[arrow.Arrow, arrow.Arrow]:
""" """
Get the maximum timeframe for the given backtest data Get the maximum timeframe for the given backtest data
:param data: dictionary with backtesting data :param data: dictionary with backtesting data
@ -118,38 +113,40 @@ def backtest(backtest_conf, processed, mocker):
@pytest.mark.skipif(not os.environ.get('BACKTEST'), reason="BACKTEST not set") @pytest.mark.skipif(not os.environ.get('BACKTEST'), reason="BACKTEST not set")
def test_backtest(backtest_conf, mocker): def test_backtest(backtest_conf, mocker):
print('') print('')
exchange._API = Bittrex({'key': '', 'secret': ''})
config = None # Load configuration file based on env variable
conf_path = os.environ.get('BACKTEST_CONFIG') conf_path = os.environ.get('BACKTEST_CONFIG')
if conf_path: if conf_path:
print('Using config: {} ...'.format(conf_path)) print('Using config: {} ...'.format(conf_path))
with open(conf_path, 'r') as conf_file: config = load_config(conf_path)
config = json.load(conf_file) else:
config = backtest_conf
# Parse ticker interval
ticker_interval = int(os.environ.get('BACKTEST_TICKER_INTERVAL') or 5) ticker_interval = int(os.environ.get('BACKTEST_TICKER_INTERVAL') or 5)
print('Using ticker_interval: {} ...'.format(ticker_interval)) print('Using ticker_interval: {} ...'.format(ticker_interval))
data = {} data = {}
if os.environ.get('BACKTEST_LIVE'): if os.environ.get('BACKTEST_LIVE'):
print('Downloading data for all pairs in whitelist ...') print('Downloading data for all pairs in whitelist ...')
exchange._API = Bittrex({'key': '', 'secret': ''})
for pair in config['exchange']['pair_whitelist']: for pair in config['exchange']['pair_whitelist']:
data[pair] = exchange.get_ticker_history(pair, ticker_interval) data[pair] = exchange.get_ticker_history(pair, ticker_interval)
else: else:
print('Using local backtesting data (ignoring whitelist in given config)...') print('Using local backtesting data (ignoring whitelist in given config)...')
data = load_backtesting_data(ticker_interval) data = load_backtesting_data(ticker_interval)
config = config or backtest_conf
print('Using stake_currency: {} ...\nUsing stake_amount: {} ...'.format( print('Using stake_currency: {} ...\nUsing stake_amount: {} ...'.format(
config['stake_currency'], config['stake_amount'] config['stake_currency'], config['stake_amount']
)) ))
# Print timeframe
min_date, max_date = get_timeframe(data) min_date, max_date = get_timeframe(data)
print('Measuring data from {} up to {} ...'.format( print('Measuring data from {} up to {} ...'.format(
min_date.isoformat(), max_date.isoformat() min_date.isoformat(), max_date.isoformat()
)) ))
# Execute backtest and print results
results = backtest(config, preprocess(data), mocker) results = backtest(config, preprocess(data), mocker)
print('====================== BACKTESTING REPORT ======================================\n\n' print('====================== BACKTESTING REPORT ======================================\n\n'
'NOTE: This Report doesn\'t respect the limits of max_open_trades, \n' 'NOTE: This Report doesn\'t respect the limits of max_open_trades, \n'

View File

@ -9,6 +9,8 @@ import pytest
from hyperopt import fmin, tpe, hp, Trials, STATUS_OK from hyperopt import fmin, tpe, hp, Trials, STATUS_OK
from pandas import DataFrame from pandas import DataFrame
from freqtrade import exchange
from freqtrade.exchange import Bittrex
from freqtrade.tests.test_backtesting import backtest, format_results from freqtrade.tests.test_backtesting import backtest, format_results
from freqtrade.tests.test_backtesting import preprocess from freqtrade.tests.test_backtesting import preprocess
from freqtrade.vendor.qtpylib.indicators import crossed_above from freqtrade.vendor.qtpylib.indicators import crossed_above
@ -70,6 +72,7 @@ def buy_strategy_generator(params):
def test_hyperopt(backtest_conf, backdata, mocker): def test_hyperopt(backtest_conf, backdata, mocker):
mocked_buy_trend = mocker.patch('freqtrade.tests.test_backtesting.populate_buy_trend') mocked_buy_trend = mocker.patch('freqtrade.tests.test_backtesting.populate_buy_trend')
processed = preprocess(backdata) processed = preprocess(backdata)
exchange._API = Bittrex({'key': '', 'secret': ''})
def optimizer(params): def optimizer(params):
mocked_buy_trend.side_effect = buy_strategy_generator(params) mocked_buy_trend.side_effect = buy_strategy_generator(params)