Merge branch 'develop' into fix/backtest_toomanyopen
This commit is contained in:
@@ -31,8 +31,8 @@ class BTContainer(NamedTuple):
|
||||
|
||||
|
||||
def _get_frame_time_from_offset(offset):
|
||||
return ticker_start_time.shift(
|
||||
minutes=(offset * TICKER_INTERVAL_MINUTES[tests_ticker_interval])).datetime
|
||||
return ticker_start_time.shift(minutes=(offset * TICKER_INTERVAL_MINUTES[tests_ticker_interval])
|
||||
).datetime.replace(tzinfo=None)
|
||||
|
||||
|
||||
def _build_backtest_dataframe(ticker_with_signals):
|
||||
|
@@ -1,4 +1,4 @@
|
||||
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, unused-argument
|
||||
# pragma pylint: disable=missing-docstring, W0212, line-too-long, C0103, C0330, unused-argument
|
||||
import logging
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
@@ -35,15 +35,15 @@ tc0 = BTContainer(data=[
|
||||
# TC2: Stop-Loss Triggered 3% Loss
|
||||
tc1 = BTContainer(data=[
|
||||
# D O H L C V B S
|
||||
[0, 5000, 5025, 4975, 4987, 6172, 1, 0],
|
||||
[1, 5000, 5025, 4975, 4987, 6172, 0, 0], # enter trade (signal on last candle)
|
||||
[2, 4987, 5012, 4962, 4975, 6172, 0, 0],
|
||||
[3, 4975, 5000, 4800, 4962, 6172, 0, 0], # exit with stoploss hit
|
||||
[4, 4962, 4987, 4937, 4950, 6172, 0, 0],
|
||||
[5, 4950, 4975, 4925, 4950, 6172, 0, 0]],
|
||||
[0, 5000, 5025, 4975, 4987, 6172, 1, 0],
|
||||
[1, 5000, 5025, 4975, 4987, 6172, 0, 0], # enter trade (signal on last candle)
|
||||
[2, 4987, 5012, 4962, 4975, 6172, 0, 0],
|
||||
[3, 4975, 5000, 4800, 4962, 6172, 0, 0], # exit with stoploss hit
|
||||
[4, 4962, 4987, 4937, 4950, 6172, 0, 0],
|
||||
[5, 4950, 4975, 4925, 4950, 6172, 0, 0]],
|
||||
stop_loss=-0.03, roi=1, profit_perc=-0.03,
|
||||
trades=[BTrade(sell_reason=SellType.STOP_LOSS, open_tick=1, close_tick=3)]
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
# Test 3 Candle drops 4%, Recovers 1%.
|
||||
@@ -128,7 +128,7 @@ tc6 = BTContainer(data=[
|
||||
[5, 4950, 4975, 4925, 4950, 6172, 0, 0]],
|
||||
stop_loss=-0.02, roi=0.03, profit_perc=0.03,
|
||||
trades=[BTrade(sell_reason=SellType.ROI, open_tick=1, close_tick=2)]
|
||||
)
|
||||
)
|
||||
|
||||
TESTS = [
|
||||
tc0,
|
||||
|
@@ -638,6 +638,7 @@ def test_backtest_only_sell(mocker, default_conf):
|
||||
|
||||
def test_backtest_alternate_buy_sell(default_conf, fee, mocker):
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch('freqtrade.optimize.backtesting.file_dump_json', MagicMock())
|
||||
backtest_conf = _make_backtest_conf(mocker, conf=default_conf, pair='UNITTEST/BTC')
|
||||
# We need to enable sell-signal - otherwise it sells on ROI!!
|
||||
default_conf['experimental'] = {"use_sell_signal": True}
|
||||
|
131
freqtrade/tests/optimize/test_edge_cli.py
Normal file
131
freqtrade/tests/optimize/test_edge_cli.py
Normal file
@@ -0,0 +1,131 @@
|
||||
# pragma pylint: disable=missing-docstring, C0103, C0330
|
||||
# pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
import json
|
||||
from typing import List
|
||||
from freqtrade.edge import PairInfo
|
||||
from freqtrade.arguments import Arguments
|
||||
from freqtrade.optimize.edge_cli import (EdgeCli, setup_configuration, start)
|
||||
from freqtrade.tests.conftest import log_has, patch_exchange
|
||||
|
||||
|
||||
def get_args(args) -> List[str]:
|
||||
return Arguments(args, '').get_parsed_arg()
|
||||
|
||||
|
||||
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
||||
read_data=json.dumps(default_conf)
|
||||
))
|
||||
|
||||
args = [
|
||||
'--config', 'config.json',
|
||||
'--strategy', 'DefaultStrategy',
|
||||
'edge'
|
||||
]
|
||||
|
||||
config = setup_configuration(get_args(args))
|
||||
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 log_has(
|
||||
'Using data folder: {} ...'.format(config['datadir']),
|
||||
caplog.record_tuples
|
||||
)
|
||||
assert 'ticker_interval' in config
|
||||
assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
|
||||
|
||||
assert 'refresh_pairs' not in config
|
||||
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
||||
|
||||
assert 'timerange' not in config
|
||||
assert 'stoploss_range' not in config
|
||||
|
||||
|
||||
def test_setup_configuration_with_arguments(mocker, edge_conf, caplog) -> None:
|
||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
||||
read_data=json.dumps(edge_conf)
|
||||
))
|
||||
|
||||
args = [
|
||||
'--config', 'config.json',
|
||||
'--strategy', 'DefaultStrategy',
|
||||
'--datadir', '/foo/bar',
|
||||
'edge',
|
||||
'--ticker-interval', '1m',
|
||||
'--refresh-pairs-cached',
|
||||
'--timerange', ':100',
|
||||
'--stoplosses=-0.01,-0.10,-0.001'
|
||||
]
|
||||
|
||||
config = setup_configuration(get_args(args))
|
||||
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 log_has(
|
||||
'Using data folder: {} ...'.format(config['datadir']),
|
||||
caplog.record_tuples
|
||||
)
|
||||
assert 'ticker_interval' in config
|
||||
assert log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
|
||||
assert log_has(
|
||||
'Using ticker_interval: 1m ...',
|
||||
caplog.record_tuples
|
||||
)
|
||||
|
||||
assert 'refresh_pairs' in config
|
||||
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
||||
assert 'timerange' in config
|
||||
assert log_has(
|
||||
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
||||
caplog.record_tuples
|
||||
)
|
||||
|
||||
|
||||
def test_start(mocker, fee, edge_conf, caplog) -> None:
|
||||
start_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.edge_cli.EdgeCli.start', start_mock)
|
||||
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
|
||||
read_data=json.dumps(edge_conf)
|
||||
))
|
||||
args = [
|
||||
'--config', 'config.json',
|
||||
'--strategy', 'DefaultStrategy',
|
||||
'edge'
|
||||
]
|
||||
args = get_args(args)
|
||||
start(args)
|
||||
assert log_has(
|
||||
'Starting freqtrade in Edge mode',
|
||||
caplog.record_tuples
|
||||
)
|
||||
assert start_mock.call_count == 1
|
||||
|
||||
|
||||
def test_edge_init(mocker, edge_conf) -> None:
|
||||
patch_exchange(mocker)
|
||||
edge_cli = EdgeCli(edge_conf)
|
||||
assert edge_cli.config == edge_conf
|
||||
assert callable(edge_cli.edge.calculate)
|
||||
|
||||
|
||||
def test_generate_edge_table(edge_conf, mocker):
|
||||
patch_exchange(mocker)
|
||||
edge_cli = EdgeCli(edge_conf)
|
||||
|
||||
results = {}
|
||||
results['ETH/BTC'] = PairInfo(-0.01, 0.60, 2, 1, 3, 10, 60)
|
||||
|
||||
assert edge_cli._generate_edge_table(results).count(':|') == 7
|
||||
assert edge_cli._generate_edge_table(results).count('| ETH/BTC |') == 1
|
||||
assert edge_cli._generate_edge_table(results).count(
|
||||
'| risk reward ratio | required risk reward | expectancy |') == 1
|
@@ -176,7 +176,7 @@ def test_roi_table_generation(hyperopt) -> None:
|
||||
'roi_p3': 3,
|
||||
}
|
||||
|
||||
assert hyperopt.generate_roi_table(params) == {0: 6, 15: 3, 25: 1, 30: 0}
|
||||
assert hyperopt.custom_hyperopt.generate_roi_table(params) == {0: 6, 15: 3, 25: 1, 30: 0}
|
||||
|
||||
|
||||
def test_start_calls_optimizer(mocker, default_conf, caplog) -> None:
|
||||
@@ -244,7 +244,8 @@ def test_populate_indicators(hyperopt) -> None:
|
||||
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
|
||||
tickerlist = {'UNITTEST/BTC': tick}
|
||||
dataframes = hyperopt.strategy.tickerdata_to_dataframe(tickerlist)
|
||||
dataframe = hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'})
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
# Check if some indicators are generated. We will not test all of them
|
||||
assert 'adx' in dataframe
|
||||
@@ -256,9 +257,10 @@ def test_buy_strategy_generator(hyperopt) -> None:
|
||||
tick = load_tickerdata_file(None, 'UNITTEST/BTC', '1m')
|
||||
tickerlist = {'UNITTEST/BTC': tick}
|
||||
dataframes = hyperopt.strategy.tickerdata_to_dataframe(tickerlist)
|
||||
dataframe = hyperopt.populate_indicators(dataframes['UNITTEST/BTC'], {'pair': 'UNITTEST/BTC'})
|
||||
dataframe = hyperopt.custom_hyperopt.populate_indicators(dataframes['UNITTEST/BTC'],
|
||||
{'pair': 'UNITTEST/BTC'})
|
||||
|
||||
populate_buy_trend = hyperopt.buy_strategy_generator(
|
||||
populate_buy_trend = hyperopt.custom_hyperopt.buy_strategy_generator(
|
||||
{
|
||||
'adx-value': 20,
|
||||
'fastd-value': 20,
|
||||
|
Reference in New Issue
Block a user