integrate hyperopt and implement subcommand
This commit is contained in:
parent
7fa5846c6b
commit
b9c4eafd96
@ -128,18 +128,20 @@ def parse_args(args: List[str]):
|
|||||||
|
|
||||||
def build_subcommands(parser: argparse.ArgumentParser) -> None:
|
def build_subcommands(parser: argparse.ArgumentParser) -> None:
|
||||||
""" Builds and attaches all subcommands """
|
""" Builds and attaches all subcommands """
|
||||||
from freqtrade.optimize import backtesting
|
from freqtrade.optimize import backtesting, hyperopt
|
||||||
|
|
||||||
subparsers = parser.add_subparsers(dest='subparser')
|
subparsers = parser.add_subparsers(dest='subparser')
|
||||||
backtest = subparsers.add_parser('backtesting', help='backtesting module')
|
|
||||||
backtest.set_defaults(func=backtesting.start)
|
# Add backtesting subcommand
|
||||||
backtest.add_argument(
|
backtesting_cmd = subparsers.add_parser('backtesting', help='backtesting module')
|
||||||
|
backtesting_cmd.set_defaults(func=backtesting.start)
|
||||||
|
backtesting_cmd.add_argument(
|
||||||
'-l', '--live',
|
'-l', '--live',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='live',
|
dest='live',
|
||||||
help='using live data',
|
help='using live data',
|
||||||
)
|
)
|
||||||
backtest.add_argument(
|
backtesting_cmd.add_argument(
|
||||||
'-i', '--ticker-interval',
|
'-i', '--ticker-interval',
|
||||||
help='specify ticker interval in minutes (default: 5)',
|
help='specify ticker interval in minutes (default: 5)',
|
||||||
dest='ticker_interval',
|
dest='ticker_interval',
|
||||||
@ -147,13 +149,17 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None:
|
|||||||
type=int,
|
type=int,
|
||||||
metavar='INT',
|
metavar='INT',
|
||||||
)
|
)
|
||||||
backtest.add_argument(
|
backtesting_cmd.add_argument(
|
||||||
'--realistic-simulation',
|
'--realistic-simulation',
|
||||||
help='uses max_open_trades from config to simulate real world limitations',
|
help='uses max_open_trades from config to simulate real world limitations',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='realistic_simulation',
|
dest='realistic_simulation',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add hyperopt subcommand
|
||||||
|
hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module')
|
||||||
|
hyperopt_cmd.set_defaults(func=hyperopt.start)
|
||||||
|
|
||||||
|
|
||||||
# Required json-schema for user specified config
|
# Required json-schema for user specified config
|
||||||
CONF_SCHEMA = {
|
CONF_SCHEMA = {
|
||||||
|
@ -1 +1,41 @@
|
|||||||
from . import backtesting
|
# pragma pylint: disable=missing-docstring
|
||||||
|
|
||||||
|
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
from typing import Optional, List, Dict
|
||||||
|
|
||||||
|
from pandas import DataFrame
|
||||||
|
|
||||||
|
from freqtrade.analyze import populate_indicators, parse_ticker_dataframe
|
||||||
|
|
||||||
|
|
||||||
|
def load_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None) -> Dict[str, List]:
|
||||||
|
"""
|
||||||
|
Loads ticker history data for the given parameters
|
||||||
|
:param ticker_interval: ticker interval in minutes
|
||||||
|
:param pairs: list of pairs
|
||||||
|
:return: dict
|
||||||
|
"""
|
||||||
|
path = os.path.abspath(os.path.dirname(__file__))
|
||||||
|
result = {}
|
||||||
|
_pairs = pairs or [
|
||||||
|
'BTC_BCC', 'BTC_ETH', 'BTC_DASH', 'BTC_POWR', 'BTC_ETC',
|
||||||
|
'BTC_VTC', 'BTC_WAVES', 'BTC_LSK', 'BTC_XLM', 'BTC_OK',
|
||||||
|
]
|
||||||
|
for pair in _pairs:
|
||||||
|
with open('{abspath}/../tests/testdata/{pair}-{ticker_interval}.json'.format(
|
||||||
|
abspath=path,
|
||||||
|
pair=pair,
|
||||||
|
ticker_interval=ticker_interval,
|
||||||
|
)) as tickerdata:
|
||||||
|
result[pair] = json.load(tickerdata)
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def preprocess(tickerdata: Dict[str, List]) -> Dict[str, DataFrame]:
|
||||||
|
"""Creates a dataframe and populates indicators for given ticker data"""
|
||||||
|
processed = {}
|
||||||
|
for pair, pair_data in tickerdata.items():
|
||||||
|
processed[pair] = populate_indicators(parse_ticker_dataframe(pair_data))
|
||||||
|
return processed
|
||||||
|
@ -9,34 +9,17 @@ from pandas import DataFrame
|
|||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade import exchange
|
from freqtrade import exchange
|
||||||
from freqtrade.analyze import parse_ticker_dataframe, populate_indicators, \
|
from freqtrade.analyze import 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.misc import load_config
|
||||||
|
from freqtrade.optimize import load_data, preprocess
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.tests import load_backtesting_data
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def format_results(results: DataFrame):
|
|
||||||
return ('Made {:6d} buys. Average profit {: 5.2f}%. '
|
|
||||||
'Total profit was {: 7.3f}. Average duration {:5.1f} mins.').format(
|
|
||||||
len(results.index),
|
|
||||||
results.profit.mean() * 100.0,
|
|
||||||
results.profit.sum(),
|
|
||||||
results.duration.mean() * 5,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def preprocess(backdata) -> Dict[str, DataFrame]:
|
|
||||||
processed = {}
|
|
||||||
for pair, pair_data in backdata.items():
|
|
||||||
processed[pair] = populate_indicators(parse_ticker_dataframe(pair_data))
|
|
||||||
return processed
|
|
||||||
|
|
||||||
|
|
||||||
def get_timeframe(data: Dict[str, Dict]) -> Tuple[arrow.Arrow, 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
|
||||||
@ -151,7 +134,7 @@ 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:
|
||||||
print('Using local backtesting data (ignoring whitelist in given config)...')
|
print('Using local backtesting data (ignoring whitelist in given config)...')
|
||||||
data = load_backtesting_data(args.ticker_interval)
|
data = load_data(args.ticker_interval)
|
||||||
|
|
||||||
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']
|
||||||
|
@ -1,29 +1,124 @@
|
|||||||
# pragma pylint: disable=missing-docstring,W0212
|
# pragma pylint: disable=missing-docstring,W0212
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from math import exp
|
from math import exp
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
|
|
||||||
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 import exchange, optimize
|
||||||
from freqtrade.exchange import Bittrex
|
from freqtrade.exchange import Bittrex
|
||||||
from freqtrade.optimize.backtesting import backtest, format_results
|
from freqtrade.optimize.backtesting import backtest
|
||||||
from freqtrade.optimize.backtesting import preprocess
|
|
||||||
from freqtrade.tests import load_backtesting_data
|
|
||||||
from freqtrade.vendor.qtpylib.indicators import crossed_above
|
from freqtrade.vendor.qtpylib.indicators import crossed_above
|
||||||
|
|
||||||
logging.disable(logging.DEBUG) # disable debug logs that slow backtesting a lot
|
|
||||||
|
|
||||||
# set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data
|
# set TARGET_TRADES to suit your number concurrent trades so its realistic to 20days of data
|
||||||
TARGET_TRADES = 1100
|
TARGET_TRADES = 1100
|
||||||
TOTAL_TRIES = 4
|
TOTAL_TRIES = 4
|
||||||
# pylint: disable=C0103
|
# pylint: disable=C0103
|
||||||
current_tries = 0
|
current_tries = 0
|
||||||
|
|
||||||
|
# Configuration and data used by hyperopt
|
||||||
|
PROCESSED = optimize.preprocess(optimize.load_data())
|
||||||
|
OPTIMIZE_CONFIG = {
|
||||||
|
'max_open_trades': 3,
|
||||||
|
'stake_currency': 'BTC',
|
||||||
|
'stake_amount': 0.01,
|
||||||
|
'minimal_roi': {
|
||||||
|
'40': 0.0,
|
||||||
|
'30': 0.01,
|
||||||
|
'20': 0.02,
|
||||||
|
'0': 0.04,
|
||||||
|
},
|
||||||
|
'stoploss': -0.10,
|
||||||
|
}
|
||||||
|
|
||||||
|
SPACE = {
|
||||||
|
'mfi': hp.choice('mfi', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True, 'value': hp.quniform('mfi-value', 5, 25, 1)}
|
||||||
|
]),
|
||||||
|
'fastd': hp.choice('fastd', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True, 'value': hp.quniform('fastd-value', 10, 50, 1)}
|
||||||
|
]),
|
||||||
|
'adx': hp.choice('adx', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True, 'value': hp.quniform('adx-value', 15, 50, 1)}
|
||||||
|
]),
|
||||||
|
'rsi': hp.choice('rsi', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True, 'value': hp.quniform('rsi-value', 20, 40, 1)}
|
||||||
|
]),
|
||||||
|
'uptrend_long_ema': hp.choice('uptrend_long_ema', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True}
|
||||||
|
]),
|
||||||
|
'uptrend_short_ema': hp.choice('uptrend_short_ema', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True}
|
||||||
|
]),
|
||||||
|
'over_sar': hp.choice('over_sar', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True}
|
||||||
|
]),
|
||||||
|
'green_candle': hp.choice('green_candle', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True}
|
||||||
|
]),
|
||||||
|
'uptrend_sma': hp.choice('uptrend_sma', [
|
||||||
|
{'enabled': False},
|
||||||
|
{'enabled': True}
|
||||||
|
]),
|
||||||
|
'trigger': hp.choice('trigger', [
|
||||||
|
{'type': 'lower_bb'},
|
||||||
|
{'type': 'faststoch10'},
|
||||||
|
{'type': 'ao_cross_zero'},
|
||||||
|
{'type': 'ema5_cross_ema10'},
|
||||||
|
{'type': 'macd_cross_signal'},
|
||||||
|
{'type': 'sar_reversal'},
|
||||||
|
{'type': 'stochf_cross'},
|
||||||
|
{'type': 'ht_sine'},
|
||||||
|
]),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def optimizer(params):
|
||||||
|
from freqtrade.optimize import backtesting
|
||||||
|
backtesting.populate_buy_trend = buy_strategy_generator(params)
|
||||||
|
|
||||||
|
results = backtest(OPTIMIZE_CONFIG, PROCESSED)
|
||||||
|
|
||||||
|
result = format_results(results)
|
||||||
|
|
||||||
|
total_profit = results.profit.sum() * 1000
|
||||||
|
trade_count = len(results.index)
|
||||||
|
|
||||||
|
trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2)
|
||||||
|
profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000
|
||||||
|
|
||||||
|
# pylint: disable=W0603
|
||||||
|
global current_tries
|
||||||
|
current_tries += 1
|
||||||
|
print('{:5d}/{}: {}'.format(current_tries, TOTAL_TRIES, result))
|
||||||
|
|
||||||
|
return {
|
||||||
|
'loss': trade_loss + profit_loss,
|
||||||
|
'status': STATUS_OK,
|
||||||
|
'result': result
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def format_results(results: DataFrame):
|
||||||
|
return ('Made {:6d} buys. Average profit {: 5.2f}%. '
|
||||||
|
'Total profit was {: 7.3f}. Average duration {:5.1f} mins.').format(
|
||||||
|
len(results.index),
|
||||||
|
results.profit.mean() * 100.0,
|
||||||
|
results.profit.sum(),
|
||||||
|
results.duration.mean() * 5,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def buy_strategy_generator(params):
|
def buy_strategy_generator(params):
|
||||||
def populate_buy_trend(dataframe: DataFrame) -> DataFrame:
|
def populate_buy_trend(dataframe: DataFrame) -> DataFrame:
|
||||||
@ -70,94 +165,14 @@ def buy_strategy_generator(params):
|
|||||||
return populate_buy_trend
|
return populate_buy_trend
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not os.environ.get('BACKTEST', False), reason="BACKTEST not set")
|
def start(args):
|
||||||
def test_hyperopt(backtest_conf, mocker):
|
# TODO: parse args
|
||||||
mocked_buy_trend = mocker.patch('freqtrade.tests.test_backtesting.populate_buy_trend')
|
|
||||||
|
|
||||||
backdata = load_backtesting_data()
|
|
||||||
processed = preprocess(backdata)
|
|
||||||
exchange._API = Bittrex({'key': '', 'secret': ''})
|
exchange._API = Bittrex({'key': '', 'secret': ''})
|
||||||
|
|
||||||
def optimizer(params):
|
|
||||||
mocked_buy_trend.side_effect = buy_strategy_generator(params)
|
|
||||||
|
|
||||||
results = backtest(backtest_conf, processed, mocker)
|
|
||||||
|
|
||||||
result = format_results(results)
|
|
||||||
|
|
||||||
total_profit = results.profit.sum() * 1000
|
|
||||||
trade_count = len(results.index)
|
|
||||||
|
|
||||||
trade_loss = 1 - 0.35 * exp(-(trade_count - TARGET_TRADES) ** 2 / 10 ** 5.2)
|
|
||||||
profit_loss = max(0, 1 - total_profit / 10000) # max profit 10000
|
|
||||||
|
|
||||||
# pylint: disable=W0603
|
|
||||||
global current_tries
|
|
||||||
current_tries += 1
|
|
||||||
print('{:5d}/{}: {}'.format(current_tries, TOTAL_TRIES, result))
|
|
||||||
|
|
||||||
return {
|
|
||||||
'loss': trade_loss + profit_loss,
|
|
||||||
'status': STATUS_OK,
|
|
||||||
'result': result
|
|
||||||
}
|
|
||||||
|
|
||||||
space = {
|
|
||||||
'mfi': hp.choice('mfi', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True, 'value': hp.quniform('mfi-value', 5, 25, 1)}
|
|
||||||
]),
|
|
||||||
'fastd': hp.choice('fastd', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True, 'value': hp.quniform('fastd-value', 10, 50, 1)}
|
|
||||||
]),
|
|
||||||
'adx': hp.choice('adx', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True, 'value': hp.quniform('adx-value', 15, 50, 1)}
|
|
||||||
]),
|
|
||||||
'rsi': hp.choice('rsi', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True, 'value': hp.quniform('rsi-value', 20, 40, 1)}
|
|
||||||
]),
|
|
||||||
'uptrend_long_ema': hp.choice('uptrend_long_ema', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True}
|
|
||||||
]),
|
|
||||||
'uptrend_short_ema': hp.choice('uptrend_short_ema', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True}
|
|
||||||
]),
|
|
||||||
'over_sar': hp.choice('over_sar', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True}
|
|
||||||
]),
|
|
||||||
'green_candle': hp.choice('green_candle', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True}
|
|
||||||
]),
|
|
||||||
'uptrend_sma': hp.choice('uptrend_sma', [
|
|
||||||
{'enabled': False},
|
|
||||||
{'enabled': True}
|
|
||||||
]),
|
|
||||||
'trigger': hp.choice('trigger', [
|
|
||||||
{'type': 'lower_bb'},
|
|
||||||
{'type': 'faststoch10'},
|
|
||||||
{'type': 'ao_cross_zero'},
|
|
||||||
{'type': 'ema5_cross_ema10'},
|
|
||||||
{'type': 'macd_cross_signal'},
|
|
||||||
{'type': 'sar_reversal'},
|
|
||||||
{'type': 'stochf_cross'},
|
|
||||||
{'type': 'ht_sine'},
|
|
||||||
]),
|
|
||||||
}
|
|
||||||
trials = Trials()
|
trials = Trials()
|
||||||
best = fmin(fn=optimizer, space=space, algo=tpe.suggest, max_evals=TOTAL_TRIES, trials=trials)
|
best = fmin(fn=optimizer, space=SPACE, algo=tpe.suggest, max_evals=TOTAL_TRIES, trials=trials)
|
||||||
print('\n\n\n\n==================== HYPEROPT BACKTESTING REPORT ==============================')
|
print('\n\n\n\n==================== HYPEROPT BACKTESTING REPORT ==============================')
|
||||||
print('Best parameters {}'.format(best))
|
print('Best parameters {}'.format(best))
|
||||||
newlist = sorted(trials.results, key=itemgetter('loss'))
|
newlist = sorted(trials.results, key=itemgetter('loss'))
|
||||||
print('Result: {}'.format(newlist[0]['result']))
|
print('Result: {}'.format(newlist[0]['result']))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
# for profiling with cProfile and line_profiler
|
|
||||||
pytest.main([__file__, '-s'])
|
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
# pragma pylint: disable=missing-docstring
|
|
||||||
import json
|
|
||||||
import os
|
|
||||||
from typing import Optional, List
|
|
||||||
|
|
||||||
|
|
||||||
def load_backtesting_data(ticker_interval: int = 5, pairs: Optional[List[str]] = None):
|
|
||||||
path = os.path.abspath(os.path.dirname(__file__))
|
|
||||||
result = {}
|
|
||||||
_pairs = pairs or [
|
|
||||||
'BTC_BCC', 'BTC_ETH', 'BTC_DASH', 'BTC_POWR', 'BTC_ETC',
|
|
||||||
'BTC_VTC', 'BTC_WAVES', 'BTC_LSK', 'BTC_XLM', 'BTC_OK',
|
|
||||||
]
|
|
||||||
for pair in _pairs:
|
|
||||||
with open('{abspath}/testdata/{pair}-{ticker_interval}.json'.format(
|
|
||||||
abspath=path,
|
|
||||||
pair=pair,
|
|
||||||
ticker_interval=ticker_interval,
|
|
||||||
)) as tickerdata:
|
|
||||||
result[pair] = json.load(tickerdata)
|
|
||||||
return result
|
|
@ -51,22 +51,6 @@ def default_conf():
|
|||||||
return configuration
|
return configuration
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="module")
|
|
||||||
def backtest_conf():
|
|
||||||
return {
|
|
||||||
"max_open_trades": 3,
|
|
||||||
"stake_currency": "BTC",
|
|
||||||
"stake_amount": 0.01,
|
|
||||||
"minimal_roi": {
|
|
||||||
"40": 0.0,
|
|
||||||
"30": 0.01,
|
|
||||||
"20": 0.02,
|
|
||||||
"0": 0.04
|
|
||||||
},
|
|
||||||
"stoploss": -0.10
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def update():
|
def update():
|
||||||
_update = Update(0)
|
_update = Update(0)
|
||||||
|
@ -78,10 +78,10 @@ def test_parse_args_backtesting(mocker):
|
|||||||
|
|
||||||
def test_parse_args_backtesting_invalid():
|
def test_parse_args_backtesting_invalid():
|
||||||
with pytest.raises(SystemExit, match=r'2'):
|
with pytest.raises(SystemExit, match=r'2'):
|
||||||
parse_args(['--ticker-interval'])
|
parse_args(['backtesting --ticker-interval'])
|
||||||
|
|
||||||
with pytest.raises(SystemExit, match=r'2'):
|
with pytest.raises(SystemExit, match=r'2'):
|
||||||
parse_args(['--ticker-interval', 'abc'])
|
parse_args(['backtesting --ticker-interval', 'abc'])
|
||||||
|
|
||||||
|
|
||||||
def test_parse_args_backtesting_custom(mocker):
|
def test_parse_args_backtesting_custom(mocker):
|
||||||
@ -99,6 +99,19 @@ def test_parse_args_backtesting_custom(mocker):
|
|||||||
assert call_args.ticker_interval == 1
|
assert call_args.ticker_interval == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse_args_hyperopt(mocker):
|
||||||
|
hyperopt_mock = mocker.patch('freqtrade.optimize.hyperopt.start', MagicMock())
|
||||||
|
args = parse_args(['hyperopt'])
|
||||||
|
assert args is None
|
||||||
|
assert hyperopt_mock.call_count == 1
|
||||||
|
|
||||||
|
call_args = hyperopt_mock.call_args[0][0]
|
||||||
|
assert call_args.config == 'config.json'
|
||||||
|
assert call_args.loglevel == 20
|
||||||
|
assert call_args.subparser == 'hyperopt'
|
||||||
|
assert call_args.func is not None
|
||||||
|
|
||||||
|
|
||||||
def test_load_config(default_conf, mocker):
|
def test_load_config(default_conf, mocker):
|
||||||
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
|
file_mock = mocker.patch('freqtrade.misc.open', mocker.mock_open(
|
||||||
read_data=json.dumps(default_conf)
|
read_data=json.dumps(default_conf)
|
||||||
|
@ -1,18 +1,16 @@
|
|||||||
# pragma pylint: disable=missing-docstring,W0212
|
# pragma pylint: disable=missing-docstring,W0212
|
||||||
|
|
||||||
|
|
||||||
from freqtrade import exchange
|
from freqtrade import exchange, optimize
|
||||||
from freqtrade.exchange import Bittrex
|
from freqtrade.exchange import Bittrex
|
||||||
from freqtrade.optimize.backtesting import backtest, preprocess
|
from freqtrade.optimize.backtesting import backtest
|
||||||
from freqtrade.tests import load_backtesting_data
|
|
||||||
|
|
||||||
|
|
||||||
def test_backtest(backtest_conf, mocker):
|
def test_backtest(default_conf, mocker):
|
||||||
mocker.patch.dict('freqtrade.main._CONF', backtest_conf)
|
mocker.patch.dict('freqtrade.main._CONF', default_conf)
|
||||||
exchange._API = Bittrex({'key': '', 'secret': ''})
|
exchange._API = Bittrex({'key': '', 'secret': ''})
|
||||||
|
|
||||||
data = load_backtesting_data(ticker_interval=5, pairs=['BTC_ETH'])
|
data = optimize.load_data(ticker_interval=5, pairs=['BTC_ETH'])
|
||||||
results = backtest(backtest_conf, preprocess(data), 10, True)
|
results = backtest(default_conf, optimize.preprocess(data), 10, True)
|
||||||
num_resutls = len(results)
|
num_resutls = len(results)
|
||||||
assert num_resutls > 0
|
assert num_resutls > 0
|
||||||
|
|
||||||
|
6
freqtrade/tests/test_optimize_hyperopt.py
Normal file
6
freqtrade/tests/test_optimize_hyperopt.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# pragma pylint: disable=missing-docstring,W0212
|
||||||
|
|
||||||
|
|
||||||
|
def test_optimizer(default_conf, mocker):
|
||||||
|
# TODO: implement test
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user