mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 18:23:55 +00:00
Merge pull request #2120 from freqtrade/log_has_ref
[minor, tests] - use caplog instead of caplog.record_tuples
This commit is contained in:
commit
2463a4af2a
|
@ -17,6 +17,29 @@ Alternatively (if your system is not supported by the setup.sh script), follow t
|
||||||
|
|
||||||
This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`.
|
This will install all required tools for development, including `pytest`, `flake8`, `mypy`, and `coveralls`.
|
||||||
|
|
||||||
|
### Tests
|
||||||
|
|
||||||
|
New code should be covered by basic unittests. Depending on the complexity of the feature, Reviewers may request more in-depth unittests.
|
||||||
|
If necessary, the Freqtrade team can assist and give guidance with writing good tests (however please don't expect anyone to write the tests for you).
|
||||||
|
|
||||||
|
#### Checking log content in tests
|
||||||
|
|
||||||
|
Freqtrade uses 2 main methods to check log content in tests, `log_has()` and `log_has_re()` (to check using regex, in case of dynamic log-messages).
|
||||||
|
These are available from `conftest.py` and can be imported in any test module.
|
||||||
|
|
||||||
|
A sample check looks as follows:
|
||||||
|
|
||||||
|
``` python
|
||||||
|
from freqtrade.tests.conftest import log_has, log_has_re
|
||||||
|
|
||||||
|
def test_method_to_test(caplog):
|
||||||
|
method_to_test()
|
||||||
|
|
||||||
|
assert log_has("This event happened", caplog)
|
||||||
|
# Check regex with trailing number ...
|
||||||
|
assert log_has_re(r"This dynamic event happened and produced \d+", caplog)
|
||||||
|
```
|
||||||
|
|
||||||
## Modules
|
## Modules
|
||||||
|
|
||||||
### Dynamic Pairlist
|
### Dynamic Pairlist
|
||||||
|
|
|
@ -34,13 +34,13 @@ def log_has(line, logs):
|
||||||
# caplog mocker returns log as a tuple: ('freqtrade.something', logging.WARNING, 'foobar')
|
# caplog mocker returns log as a tuple: ('freqtrade.something', logging.WARNING, 'foobar')
|
||||||
# and we want to match line against foobar in the tuple
|
# and we want to match line against foobar in the tuple
|
||||||
return reduce(lambda a, b: a or b,
|
return reduce(lambda a, b: a or b,
|
||||||
filter(lambda x: x[2] == line, logs),
|
filter(lambda x: x[2] == line, logs.record_tuples),
|
||||||
False)
|
False)
|
||||||
|
|
||||||
|
|
||||||
def log_has_re(line, logs):
|
def log_has_re(line, logs):
|
||||||
return reduce(lambda a, b: a or b,
|
return reduce(lambda a, b: a or b,
|
||||||
filter(lambda x: re.match(line, x[2]), logs),
|
filter(lambda x: re.match(line, x[2]), logs.record_tuples),
|
||||||
False)
|
False)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ def test_parse_ticker_dataframe(ticker_history_list, caplog):
|
||||||
dataframe = parse_ticker_dataframe(ticker_history_list, '5m',
|
dataframe = parse_ticker_dataframe(ticker_history_list, '5m',
|
||||||
pair="UNITTEST/BTC", fill_missing=True)
|
pair="UNITTEST/BTC", fill_missing=True)
|
||||||
assert dataframe.columns.tolist() == columns
|
assert dataframe.columns.tolist() == columns
|
||||||
assert log_has('Parsing tickerlist to dataframe', caplog.record_tuples)
|
assert log_has('Parsing tickerlist to dataframe', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_ohlcv_fill_up_missing_data(caplog):
|
def test_ohlcv_fill_up_missing_data(caplog):
|
||||||
|
@ -34,8 +34,7 @@ def test_ohlcv_fill_up_missing_data(caplog):
|
||||||
assert (data.columns == data2.columns).all()
|
assert (data.columns == data2.columns).all()
|
||||||
|
|
||||||
assert log_has(f"Missing data fillup for UNITTEST/BTC: before: "
|
assert log_has(f"Missing data fillup for UNITTEST/BTC: before: "
|
||||||
f"{len(data)} - after: {len(data2)}",
|
f"{len(data)} - after: {len(data2)}", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
# Test fillup actually fixes invalid backtest data
|
# Test fillup actually fixes invalid backtest data
|
||||||
min_date, max_date = get_timeframe({'UNITTEST/BTC': data})
|
min_date, max_date = get_timeframe({'UNITTEST/BTC': data})
|
||||||
|
@ -97,8 +96,7 @@ def test_ohlcv_fill_up_missing_data2(caplog):
|
||||||
assert (data.columns == data2.columns).all()
|
assert (data.columns == data2.columns).all()
|
||||||
|
|
||||||
assert log_has(f"Missing data fillup for UNITTEST/BTC: before: "
|
assert log_has(f"Missing data fillup for UNITTEST/BTC: before: "
|
||||||
f"{len(data)} - after: {len(data2)}",
|
f"{len(data)} - after: {len(data2)}", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_ohlcv_drop_incomplete(caplog):
|
def test_ohlcv_drop_incomplete(caplog):
|
||||||
|
@ -140,11 +138,11 @@ def test_ohlcv_drop_incomplete(caplog):
|
||||||
data = parse_ticker_dataframe(ticks, ticker_interval, pair="UNITTEST/BTC",
|
data = parse_ticker_dataframe(ticks, ticker_interval, pair="UNITTEST/BTC",
|
||||||
fill_missing=False, drop_incomplete=False)
|
fill_missing=False, drop_incomplete=False)
|
||||||
assert len(data) == 4
|
assert len(data) == 4
|
||||||
assert not log_has("Dropping last candle", caplog.record_tuples)
|
assert not log_has("Dropping last candle", caplog)
|
||||||
|
|
||||||
# Drop last candle
|
# Drop last candle
|
||||||
data = parse_ticker_dataframe(ticks, ticker_interval, pair="UNITTEST/BTC",
|
data = parse_ticker_dataframe(ticks, ticker_interval, pair="UNITTEST/BTC",
|
||||||
fill_missing=False, drop_incomplete=True)
|
fill_missing=False, drop_incomplete=True)
|
||||||
assert len(data) == 3
|
assert len(data) == 3
|
||||||
|
|
||||||
assert log_has("Dropping last candle", caplog.record_tuples)
|
assert log_has("Dropping last candle", caplog)
|
||||||
|
|
|
@ -64,8 +64,7 @@ def test_load_data_30min_ticker(mocker, caplog, default_conf) -> None:
|
||||||
assert isinstance(ld, DataFrame)
|
assert isinstance(ld, DataFrame)
|
||||||
assert not log_has(
|
assert not log_has(
|
||||||
'Download history data for pair: "UNITTEST/BTC", interval: 30m '
|
'Download history data for pair: "UNITTEST/BTC", interval: 30m '
|
||||||
'and store in None.',
|
'and store in None.', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,8 +75,7 @@ def test_load_data_7min_ticker(mocker, caplog, default_conf) -> None:
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'No history data for pair: "UNITTEST/BTC", interval: 7m. '
|
'No history data for pair: "UNITTEST/BTC", interval: 7m. '
|
||||||
'Use --refresh-pairs-cached option or download_backtest_data.py '
|
'Use --refresh-pairs-cached option or download_backtest_data.py '
|
||||||
'script to download the data',
|
'script to download the data', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,8 +87,7 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog) -> None:
|
||||||
assert os.path.isfile(file) is True
|
assert os.path.isfile(file) is True
|
||||||
assert not log_has(
|
assert not log_has(
|
||||||
'Download history data for pair: "UNITTEST/BTC", interval: 1m '
|
'Download history data for pair: "UNITTEST/BTC", interval: 1m '
|
||||||
'and store in None.',
|
'and store in None.', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
_clean_test_file(file)
|
_clean_test_file(file)
|
||||||
|
|
||||||
|
@ -113,8 +110,7 @@ def test_load_data_with_new_pair_1min(ticker_history_list, mocker, caplog, defau
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'No history data for pair: "MEME/BTC", interval: 1m. '
|
'No history data for pair: "MEME/BTC", interval: 1m. '
|
||||||
'Use --refresh-pairs-cached option or download_backtest_data.py '
|
'Use --refresh-pairs-cached option or download_backtest_data.py '
|
||||||
'script to download the data',
|
'script to download the data', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# download a new pair if refresh_pairs is set
|
# download a new pair if refresh_pairs is set
|
||||||
|
@ -126,8 +122,7 @@ def test_load_data_with_new_pair_1min(ticker_history_list, mocker, caplog, defau
|
||||||
assert os.path.isfile(file) is True
|
assert os.path.isfile(file) is True
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'Download history data for pair: "MEME/BTC", interval: 1m '
|
'Download history data for pair: "MEME/BTC", interval: 1m '
|
||||||
'and store in None.',
|
'and store in None.', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
with pytest.raises(OperationalException, match=r'Exchange needs to be initialized when.*'):
|
with pytest.raises(OperationalException, match=r'Exchange needs to be initialized when.*'):
|
||||||
history.load_pair_history(datadir=None,
|
history.load_pair_history(datadir=None,
|
||||||
|
@ -149,7 +144,7 @@ def test_load_data_live(default_conf, mocker, caplog) -> None:
|
||||||
exchange=exchange)
|
exchange=exchange)
|
||||||
assert refresh_mock.call_count == 1
|
assert refresh_mock.call_count == 1
|
||||||
assert len(refresh_mock.call_args_list[0][0][0]) == 2
|
assert len(refresh_mock.call_args_list[0][0][0]) == 2
|
||||||
assert log_has('Live: Downloading data for all defined pairs ...', caplog.record_tuples)
|
assert log_has('Live: Downloading data for all defined pairs ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_load_data_live_noexchange(default_conf, mocker, caplog) -> None:
|
def test_load_data_live_noexchange(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -350,8 +345,7 @@ def test_download_backtesting_data_exception(ticker_history, mocker, caplog, def
|
||||||
_clean_test_file(file1_5)
|
_clean_test_file(file1_5)
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'Failed to download history data for pair: "MEME/BTC", interval: 1m. '
|
'Failed to download history data for pair: "MEME/BTC", interval: 1m. '
|
||||||
'Error: File Error',
|
'Error: File Error', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -380,7 +374,7 @@ def test_load_partial_missing(caplog) -> None:
|
||||||
start_real = tickerdata['UNITTEST/BTC'].iloc[0, 0]
|
start_real = tickerdata['UNITTEST/BTC'].iloc[0, 0]
|
||||||
assert log_has(f'Missing data at start for pair '
|
assert log_has(f'Missing data at start for pair '
|
||||||
f'UNITTEST/BTC, data starts at {start_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
f'UNITTEST/BTC, data starts at {start_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
# Make sure we start fresh - test missing data at end
|
# Make sure we start fresh - test missing data at end
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
start = arrow.get('2018-01-10T00:00:00')
|
start = arrow.get('2018-01-10T00:00:00')
|
||||||
|
@ -396,7 +390,7 @@ def test_load_partial_missing(caplog) -> None:
|
||||||
end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5)
|
end_real = arrow.get(tickerdata['UNITTEST/BTC'].iloc[-1, 0]).shift(minutes=5)
|
||||||
assert log_has(f'Missing data at end for pair '
|
assert log_has(f'Missing data at end for pair '
|
||||||
f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
f'UNITTEST/BTC, data ends at {end_real.strftime("%Y-%m-%d %H:%M:%S")}',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_init(default_conf, mocker) -> None:
|
def test_init(default_conf, mocker) -> None:
|
||||||
|
@ -560,7 +554,7 @@ def test_validate_backtest_data_warn(default_conf, mocker, caplog) -> None:
|
||||||
assert len(caplog.record_tuples) == 1
|
assert len(caplog.record_tuples) == 1
|
||||||
assert log_has(
|
assert log_has(
|
||||||
"UNITTEST/BTC has missing frames: expected 14396, got 13680, that's 716 missing values",
|
"UNITTEST/BTC has missing frames: expected 14396, got 13680, that's 716 missing values",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_backtest_data(default_conf, mocker, caplog) -> None:
|
def test_validate_backtest_data(default_conf, mocker, caplog) -> None:
|
||||||
|
|
|
@ -311,7 +311,7 @@ def test_edge_process_no_data(mocker, edge_conf, caplog):
|
||||||
|
|
||||||
assert not edge.calculate()
|
assert not edge.calculate()
|
||||||
assert len(edge._cached_pairs) == 0
|
assert len(edge._cached_pairs) == 0
|
||||||
assert log_has("No data found. Edge is stopped ...", caplog.record_tuples)
|
assert log_has("No data found. Edge is stopped ...", caplog)
|
||||||
assert edge._last_updated == 0
|
assert edge._last_updated == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,7 +326,7 @@ def test_edge_process_no_trades(mocker, edge_conf, caplog):
|
||||||
|
|
||||||
assert not edge.calculate()
|
assert not edge.calculate()
|
||||||
assert len(edge._cached_pairs) == 0
|
assert len(edge._cached_pairs) == 0
|
||||||
assert log_has("No trades found.", caplog.record_tuples)
|
assert log_has("No trades found.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_edge_init_error(mocker, edge_conf,):
|
def test_edge_init_error(mocker, edge_conf,):
|
||||||
|
|
|
@ -62,7 +62,7 @@ async def async_ccxt_exception(mocker, default_conf, api_mock, fun, mock_ccxt_fu
|
||||||
def test_init(default_conf, mocker, caplog):
|
def test_init(default_conf, mocker, caplog):
|
||||||
caplog.set_level(logging.INFO)
|
caplog.set_level(logging.INFO)
|
||||||
get_patched_exchange(mocker, default_conf)
|
get_patched_exchange(mocker, default_conf)
|
||||||
assert log_has('Instance is running with dry_run enabled', caplog.record_tuples)
|
assert log_has('Instance is running with dry_run enabled', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_init_ccxt_kwargs(default_conf, mocker, caplog):
|
def test_init_ccxt_kwargs(default_conf, mocker, caplog):
|
||||||
|
@ -71,8 +71,7 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog):
|
||||||
conf = copy.deepcopy(default_conf)
|
conf = copy.deepcopy(default_conf)
|
||||||
conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True}
|
conf['exchange']['ccxt_async_config'] = {'aiohttp_trust_env': True}
|
||||||
ex = Exchange(conf)
|
ex = Exchange(conf)
|
||||||
assert log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}",
|
assert log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
assert ex._api_async.aiohttp_trust_env
|
assert ex._api_async.aiohttp_trust_env
|
||||||
assert not ex._api.aiohttp_trust_env
|
assert not ex._api.aiohttp_trust_env
|
||||||
|
|
||||||
|
@ -81,20 +80,18 @@ def test_init_ccxt_kwargs(default_conf, mocker, caplog):
|
||||||
conf = copy.deepcopy(default_conf)
|
conf = copy.deepcopy(default_conf)
|
||||||
conf['exchange']['ccxt_config'] = {'TestKWARG': 11}
|
conf['exchange']['ccxt_config'] = {'TestKWARG': 11}
|
||||||
ex = Exchange(conf)
|
ex = Exchange(conf)
|
||||||
assert not log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}",
|
assert not log_has("Applying additional ccxt config: {'aiohttp_trust_env': True}", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
assert not ex._api_async.aiohttp_trust_env
|
assert not ex._api_async.aiohttp_trust_env
|
||||||
assert hasattr(ex._api, 'TestKWARG')
|
assert hasattr(ex._api, 'TestKWARG')
|
||||||
assert ex._api.TestKWARG == 11
|
assert ex._api.TestKWARG == 11
|
||||||
assert not hasattr(ex._api_async, 'TestKWARG')
|
assert not hasattr(ex._api_async, 'TestKWARG')
|
||||||
assert log_has("Applying additional ccxt config: {'TestKWARG': 11}",
|
assert log_has("Applying additional ccxt config: {'TestKWARG': 11}", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_destroy(default_conf, mocker, caplog):
|
def test_destroy(default_conf, mocker, caplog):
|
||||||
caplog.set_level(logging.DEBUG)
|
caplog.set_level(logging.DEBUG)
|
||||||
get_patched_exchange(mocker, default_conf)
|
get_patched_exchange(mocker, default_conf)
|
||||||
assert log_has('Exchange object destroyed, closing async loop', caplog.record_tuples)
|
assert log_has('Exchange object destroyed, closing async loop', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_init_exception(default_conf, mocker):
|
def test_init_exception(default_conf, mocker):
|
||||||
|
@ -120,8 +117,7 @@ def test_exchange_resolver(default_conf, mocker, caplog):
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||||
exchange = ExchangeResolver('Bittrex', default_conf).exchange
|
exchange = ExchangeResolver('Bittrex', default_conf).exchange
|
||||||
assert isinstance(exchange, Exchange)
|
assert isinstance(exchange, Exchange)
|
||||||
assert log_has_re(r"No .* specific subclass found. Using the generic class instead.",
|
assert log_has_re(r"No .* specific subclass found. Using the generic class instead.", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
exchange = ExchangeResolver('kraken', default_conf).exchange
|
exchange = ExchangeResolver('kraken', default_conf).exchange
|
||||||
|
@ -129,7 +125,7 @@ def test_exchange_resolver(default_conf, mocker, caplog):
|
||||||
assert isinstance(exchange, Kraken)
|
assert isinstance(exchange, Kraken)
|
||||||
assert not isinstance(exchange, Binance)
|
assert not isinstance(exchange, Binance)
|
||||||
assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.",
|
assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
exchange = ExchangeResolver('binance', default_conf).exchange
|
exchange = ExchangeResolver('binance', default_conf).exchange
|
||||||
assert isinstance(exchange, Exchange)
|
assert isinstance(exchange, Exchange)
|
||||||
|
@ -137,7 +133,7 @@ def test_exchange_resolver(default_conf, mocker, caplog):
|
||||||
assert not isinstance(exchange, Kraken)
|
assert not isinstance(exchange, Kraken)
|
||||||
|
|
||||||
assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.",
|
assert not log_has_re(r"No .* specific subclass found. Using the generic class instead.",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_order_time_in_force(default_conf, mocker, caplog):
|
def test_validate_order_time_in_force(default_conf, mocker, caplog):
|
||||||
|
@ -249,8 +245,7 @@ def test__load_async_markets(default_conf, mocker, caplog):
|
||||||
exchange._api_async.load_markets = Mock(side_effect=ccxt.BaseError("deadbeef"))
|
exchange._api_async.load_markets = Mock(side_effect=ccxt.BaseError("deadbeef"))
|
||||||
exchange._load_async_markets()
|
exchange._load_async_markets()
|
||||||
|
|
||||||
assert log_has('Could not load async markets. Reason: deadbeef',
|
assert log_has('Could not load async markets. Reason: deadbeef', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test__load_markets(default_conf, mocker, caplog):
|
def test__load_markets(default_conf, mocker, caplog):
|
||||||
|
@ -262,7 +257,7 @@ def test__load_markets(default_conf, mocker, caplog):
|
||||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||||
mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())
|
mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock())
|
||||||
Exchange(default_conf)
|
Exchange(default_conf)
|
||||||
assert log_has('Unable to initialize markets. Reason: SomeError', caplog.record_tuples)
|
assert log_has('Unable to initialize markets. Reason: SomeError', caplog)
|
||||||
|
|
||||||
expected_return = {'ETH/BTC': 'available'}
|
expected_return = {'ETH/BTC': 'available'}
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
|
@ -298,7 +293,7 @@ def test__reload_markets(default_conf, mocker, caplog):
|
||||||
exchange._last_markets_refresh = arrow.utcnow().timestamp - 15 * 60
|
exchange._last_markets_refresh = arrow.utcnow().timestamp - 15 * 60
|
||||||
exchange._reload_markets()
|
exchange._reload_markets()
|
||||||
assert exchange.markets == updated_markets
|
assert exchange.markets == updated_markets
|
||||||
assert log_has('Performing scheduled market reload..', caplog.record_tuples)
|
assert log_has('Performing scheduled market reload..', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test__reload_markets_exception(default_conf, mocker, caplog):
|
def test__reload_markets_exception(default_conf, mocker, caplog):
|
||||||
|
@ -312,7 +307,7 @@ def test__reload_markets_exception(default_conf, mocker, caplog):
|
||||||
# less than 10 minutes have passed, no reload
|
# less than 10 minutes have passed, no reload
|
||||||
exchange._reload_markets()
|
exchange._reload_markets()
|
||||||
assert exchange._last_markets_refresh == 0
|
assert exchange._last_markets_refresh == 0
|
||||||
assert log_has_re(r"Could not reload markets.*", caplog.record_tuples)
|
assert log_has_re(r"Could not reload markets.*", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly
|
def test_validate_pairs(default_conf, mocker): # test exchange.validate_pairs directly
|
||||||
|
@ -357,8 +352,7 @@ def test_validate_pairs_exception(default_conf, mocker, caplog):
|
||||||
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value={}))
|
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value={}))
|
||||||
Exchange(default_conf)
|
Exchange(default_conf)
|
||||||
assert log_has('Unable to validate pairs (assuming they are correct).',
|
assert log_has('Unable to validate pairs (assuming they are correct).', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_validate_pairs_restricted(default_conf, mocker, caplog):
|
def test_validate_pairs_restricted(default_conf, mocker, caplog):
|
||||||
|
@ -374,8 +368,7 @@ def test_validate_pairs_restricted(default_conf, mocker, caplog):
|
||||||
Exchange(default_conf)
|
Exchange(default_conf)
|
||||||
assert log_has(f"Pair XRP/BTC is restricted for some users on this exchange."
|
assert log_has(f"Pair XRP/BTC is restricted for some users on this exchange."
|
||||||
f"Please check if you are impacted by this restriction "
|
f"Please check if you are impacted by this restriction "
|
||||||
f"on the exchange and eventually remove XRP/BTC from your whitelist.",
|
f"on the exchange and eventually remove XRP/BTC from your whitelist.", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_validate_timeframes(default_conf, mocker):
|
def test_validate_timeframes(default_conf, mocker):
|
||||||
|
@ -1060,7 +1053,7 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None:
|
||||||
assert not exchange._klines
|
assert not exchange._klines
|
||||||
exchange.refresh_latest_ohlcv(pairs)
|
exchange.refresh_latest_ohlcv(pairs)
|
||||||
|
|
||||||
assert log_has(f'Refreshing ohlcv data for {len(pairs)} pairs', caplog.record_tuples)
|
assert log_has(f'Refreshing ohlcv data for {len(pairs)} pairs', caplog)
|
||||||
assert exchange._klines
|
assert exchange._klines
|
||||||
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
|
@ -1079,7 +1072,7 @@ def test_refresh_latest_ohlcv(mocker, default_conf, caplog) -> None:
|
||||||
|
|
||||||
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
assert exchange._api_async.fetch_ohlcv.call_count == 2
|
||||||
assert log_has(f"Using cached ohlcv data for pair {pairs[0][0]}, interval {pairs[0][1]} ...",
|
assert log_has(f"Using cached ohlcv data for pair {pairs[0][0]}, interval {pairs[0][1]} ...",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
|
@ -1109,7 +1102,7 @@ async def test__async_get_candle_history(default_conf, mocker, caplog, exchange_
|
||||||
assert res[1] == "5m"
|
assert res[1] == "5m"
|
||||||
assert res[2] == tick
|
assert res[2] == tick
|
||||||
assert exchange._api_async.fetch_ohlcv.call_count == 1
|
assert exchange._api_async.fetch_ohlcv.call_count == 1
|
||||||
assert not log_has(f"Using cached ohlcv data for {pair} ...", caplog.record_tuples)
|
assert not log_has(f"Using cached ohlcv data for {pair} ...", caplog)
|
||||||
|
|
||||||
# exchange = Exchange(default_conf)
|
# exchange = Exchange(default_conf)
|
||||||
await async_ccxt_exception(mocker, default_conf, MagicMock(),
|
await async_ccxt_exception(mocker, default_conf, MagicMock(),
|
||||||
|
@ -1168,8 +1161,8 @@ def test_refresh_latest_ohlcv_inv_result(default_conf, mocker, caplog):
|
||||||
# Test that each is in list at least once as order is not guaranteed
|
# Test that each is in list at least once as order is not guaranteed
|
||||||
assert type(res[0]) is tuple or type(res[1]) is tuple
|
assert type(res[0]) is tuple or type(res[1]) is tuple
|
||||||
assert type(res[0]) is TypeError or type(res[1]) is TypeError
|
assert type(res[0]) is TypeError or type(res[1]) is TypeError
|
||||||
assert log_has("Error loading ETH/BTC. Result was [[]].", caplog.record_tuples)
|
assert log_has("Error loading ETH/BTC. Result was [[]].", caplog)
|
||||||
assert log_has("Async code raised an exception: TypeError", caplog.record_tuples)
|
assert log_has("Async code raised an exception: TypeError", caplog)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
@pytest.mark.parametrize("exchange_name", EXCHANGES)
|
||||||
|
|
|
@ -181,21 +181,18 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples)
|
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog)
|
||||||
|
|
||||||
assert 'live' not in config
|
assert 'live' not in config
|
||||||
assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -l/--live detected ...', caplog)
|
||||||
|
|
||||||
assert 'position_stacking' not in config
|
assert 'position_stacking' not in config
|
||||||
assert not log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert not log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' not in config
|
assert 'refresh_pairs' not in config
|
||||||
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' not in config
|
assert 'timerange' not in config
|
||||||
assert 'export' not in config
|
assert 'export' not in config
|
||||||
|
@ -235,43 +232,31 @@ def test_setup_bt_configuration_with_arguments(mocker, default_conf, caplog) ->
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert config['runmode'] == RunMode.BACKTEST
|
assert config['runmode'] == RunMode.BACKTEST
|
||||||
|
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'live' in config
|
assert 'live' in config
|
||||||
assert log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
assert log_has('Parameter -l/--live detected ...', caplog)
|
||||||
|
|
||||||
assert 'position_stacking' in config
|
assert 'position_stacking' in config
|
||||||
assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'use_max_market_positions' in config
|
assert 'use_max_market_positions' in config
|
||||||
assert log_has('Parameter --disable-max-market-positions detected ...', caplog.record_tuples)
|
assert log_has('Parameter --disable-max-market-positions detected ...', caplog)
|
||||||
assert log_has('max_open_trades set to unlimited ...', caplog.record_tuples)
|
assert log_has('max_open_trades set to unlimited ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' in config
|
assert 'refresh_pairs' in config
|
||||||
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' in config
|
assert 'timerange' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog)
|
||||||
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
assert 'export' in config
|
assert 'export' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --export detected: {} ...'.format(config['export']), caplog)
|
||||||
'Parameter --export detected: {} ...'.format(config['export']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'exportfilename' in config
|
assert 'exportfilename' in config
|
||||||
assert log_has(
|
assert log_has('Storing backtest results to {} ...'.format(config['exportfilename']), caplog)
|
||||||
'Storing backtest results to {} ...'.format(config['exportfilename']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_unlimited_stake_amount(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -303,10 +288,7 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
|
||||||
]
|
]
|
||||||
args = get_args(args)
|
args = get_args(args)
|
||||||
start_backtesting(args)
|
start_backtesting(args)
|
||||||
assert log_has(
|
assert log_has('Starting freqtrade in Backtesting mode', caplog)
|
||||||
'Starting freqtrade in Backtesting mode',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert start_mock.call_count == 1
|
assert start_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -360,7 +342,7 @@ def test_backtesting_init_no_ticker_interval(mocker, default_conf, caplog) -> No
|
||||||
with pytest.raises(OperationalException):
|
with pytest.raises(OperationalException):
|
||||||
Backtesting(default_conf)
|
Backtesting(default_conf)
|
||||||
log_has("Ticker-interval needs to be set in either configuration "
|
log_has("Ticker-interval needs to be set in either configuration "
|
||||||
"or as cli argument `--ticker-interval 5m`", caplog.record_tuples)
|
"or as cli argument `--ticker-interval 5m`", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_tickerdata_to_dataframe_bt(default_conf, mocker) -> None:
|
def test_tickerdata_to_dataframe_bt(default_conf, mocker) -> None:
|
||||||
|
@ -511,7 +493,7 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None:
|
||||||
'up to 2017-11-14T22:59:00+00:00 (0 days)..'
|
'up to 2017-11-14T22:59:00+00:00 (0 days)..'
|
||||||
]
|
]
|
||||||
for line in exists:
|
for line in exists:
|
||||||
assert log_has(line, caplog.record_tuples)
|
assert log_has(line, caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
|
def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -539,7 +521,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
|
||||||
backtesting.start()
|
backtesting.start()
|
||||||
# check the logs, that will contain the backtest result
|
# check the logs, that will contain the backtest result
|
||||||
|
|
||||||
assert log_has('No data found. Terminating.', caplog.record_tuples)
|
assert log_has('No data found. Terminating.', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_backtest(default_conf, fee, mocker) -> None:
|
def test_backtest(default_conf, fee, mocker) -> None:
|
||||||
|
@ -876,7 +858,7 @@ def test_backtest_start_live(default_conf, mocker, caplog):
|
||||||
]
|
]
|
||||||
|
|
||||||
for line in exists:
|
for line in exists:
|
||||||
assert log_has(line, caplog.record_tuples)
|
assert log_has(line, caplog)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.filterwarnings("ignore:DEPRECATED")
|
@pytest.mark.filterwarnings("ignore:DEPRECATED")
|
||||||
|
@ -936,4 +918,4 @@ def test_backtest_start_multi_strat(default_conf, mocker, caplog):
|
||||||
]
|
]
|
||||||
|
|
||||||
for line in exists:
|
for line in exists:
|
||||||
assert log_has(line, caplog.record_tuples)
|
assert log_has(line, caplog)
|
||||||
|
|
|
@ -29,15 +29,12 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples)
|
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' not in config
|
assert 'refresh_pairs' not in config
|
||||||
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' not in config
|
assert 'timerange' not in config
|
||||||
assert 'stoploss_range' not in config
|
assert 'stoploss_range' not in config
|
||||||
|
@ -69,21 +66,15 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert config['runmode'] == RunMode.EDGE
|
assert config['runmode'] == RunMode.EDGE
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' in config
|
assert 'refresh_pairs' in config
|
||||||
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
assert 'timerange' in config
|
assert 'timerange' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog)
|
||||||
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_start(mocker, fee, edge_conf, caplog) -> None:
|
def test_start(mocker, fee, edge_conf, caplog) -> None:
|
||||||
|
@ -100,10 +91,7 @@ def test_start(mocker, fee, edge_conf, caplog) -> None:
|
||||||
]
|
]
|
||||||
args = get_args(args)
|
args = get_args(args)
|
||||||
start_edge(args)
|
start_edge(args)
|
||||||
assert log_has(
|
assert log_has('Starting freqtrade in Edge mode', caplog)
|
||||||
'Starting freqtrade in Edge mode',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert start_mock.call_count == 1
|
assert start_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,21 +79,18 @@ def test_setup_hyperopt_configuration_without_arguments(mocker, default_conf, ca
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog.record_tuples)
|
assert not log_has_re('Parameter -i/--ticker-interval detected .*', caplog)
|
||||||
|
|
||||||
assert 'live' not in config
|
assert 'live' not in config
|
||||||
assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -l/--live detected ...', caplog)
|
||||||
|
|
||||||
assert 'position_stacking' not in config
|
assert 'position_stacking' not in config
|
||||||
assert not log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert not log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' not in config
|
assert 'refresh_pairs' not in config
|
||||||
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' not in config
|
assert 'timerange' not in config
|
||||||
assert 'runmode' in config
|
assert 'runmode' in config
|
||||||
|
@ -130,41 +127,32 @@ def test_setup_hyperopt_configuration_with_arguments(mocker, default_conf, caplo
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert config['runmode'] == RunMode.HYPEROPT
|
assert config['runmode'] == RunMode.HYPEROPT
|
||||||
|
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'position_stacking' in config
|
assert 'position_stacking' in config
|
||||||
assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'use_max_market_positions' in config
|
assert 'use_max_market_positions' in config
|
||||||
assert log_has('Parameter --disable-max-market-positions detected ...', caplog.record_tuples)
|
assert log_has('Parameter --disable-max-market-positions detected ...', caplog)
|
||||||
assert log_has('max_open_trades set to unlimited ...', caplog.record_tuples)
|
assert log_has('max_open_trades set to unlimited ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' in config
|
assert 'refresh_pairs' in config
|
||||||
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' in config
|
assert 'timerange' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog)
|
||||||
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
assert 'epochs' in config
|
assert 'epochs' in config
|
||||||
assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 1000 epochs ...',
|
assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 1000 epochs ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'spaces' in config
|
assert 'spaces' in config
|
||||||
assert log_has(
|
assert log_has('Parameter -s/--spaces detected: {}'.format(config['spaces']), caplog)
|
||||||
'Parameter -s/--spaces detected: {}'.format(config['spaces']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'print_all' in config
|
assert 'print_all' in config
|
||||||
assert log_has('Parameter --print-all detected ...', caplog.record_tuples)
|
assert log_has('Parameter --print-all detected ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -181,9 +169,9 @@ def test_hyperoptresolver(mocker, default_conf, caplog) -> None:
|
||||||
assert not hasattr(x, 'populate_buy_trend')
|
assert not hasattr(x, 'populate_buy_trend')
|
||||||
assert not hasattr(x, 'populate_sell_trend')
|
assert not hasattr(x, 'populate_sell_trend')
|
||||||
assert log_has("Custom Hyperopt does not provide populate_sell_trend. "
|
assert log_has("Custom Hyperopt does not provide populate_sell_trend. "
|
||||||
"Using populate_sell_trend from DefaultStrategy.", caplog.record_tuples)
|
"Using populate_sell_trend from DefaultStrategy.", caplog)
|
||||||
assert log_has("Custom Hyperopt does not provide populate_buy_trend. "
|
assert log_has("Custom Hyperopt does not provide populate_buy_trend. "
|
||||||
"Using populate_buy_trend from DefaultStrategy.", caplog.record_tuples)
|
"Using populate_buy_trend from DefaultStrategy.", caplog)
|
||||||
assert hasattr(x, "ticker_interval")
|
assert hasattr(x, "ticker_interval")
|
||||||
|
|
||||||
|
|
||||||
|
@ -229,10 +217,7 @@ def test_start(mocker, default_conf, caplog) -> None:
|
||||||
import pprint
|
import pprint
|
||||||
pprint.pprint(caplog.record_tuples)
|
pprint.pprint(caplog.record_tuples)
|
||||||
|
|
||||||
assert log_has(
|
assert log_has('Starting freqtrade in Hyperopt mode', caplog)
|
||||||
'Starting freqtrade in Hyperopt mode',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert start_mock.call_count == 1
|
assert start_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -257,7 +242,7 @@ def test_start_no_data(mocker, default_conf, caplog) -> None:
|
||||||
import pprint
|
import pprint
|
||||||
pprint.pprint(caplog.record_tuples)
|
pprint.pprint(caplog.record_tuples)
|
||||||
|
|
||||||
assert log_has('No data found. Terminating.', caplog.record_tuples)
|
assert log_has('No data found. Terminating.', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_start_failure(mocker, default_conf, caplog) -> None:
|
def test_start_failure(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -275,10 +260,7 @@ def test_start_failure(mocker, default_conf, caplog) -> None:
|
||||||
args = get_args(args)
|
args = get_args(args)
|
||||||
with pytest.raises(DependencyException):
|
with pytest.raises(DependencyException):
|
||||||
start_hyperopt(args)
|
start_hyperopt(args)
|
||||||
assert log_has(
|
assert log_has("Please don't use --strategy for hyperopt.", caplog)
|
||||||
"Please don't use --strategy for hyperopt.",
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_start_filelock(mocker, default_conf, caplog) -> None:
|
def test_start_filelock(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -294,10 +276,7 @@ def test_start_filelock(mocker, default_conf, caplog) -> None:
|
||||||
]
|
]
|
||||||
args = get_args(args)
|
args = get_args(args)
|
||||||
start_hyperopt(args)
|
start_hyperopt(args)
|
||||||
assert log_has(
|
assert log_has("Another running instance of freqtrade Hyperopt detected.", caplog)
|
||||||
"Another running instance of freqtrade Hyperopt detected.",
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None:
|
def test_loss_calculation_prefer_correct_trade_count(default_conf, hyperopt_results) -> None:
|
||||||
|
@ -401,10 +380,7 @@ def test_save_trials_saves_trials(mocker, hyperopt, caplog) -> None:
|
||||||
hyperopt.save_trials()
|
hyperopt.save_trials()
|
||||||
|
|
||||||
trials_file = os.path.join('freqtrade', 'tests', 'optimize', 'ut_trials.pickle')
|
trials_file = os.path.join('freqtrade', 'tests', 'optimize', 'ut_trials.pickle')
|
||||||
assert log_has(
|
assert log_has('Saving 1 evaluations to \'{}\''.format(trials_file), caplog)
|
||||||
'Saving 1 evaluations to \'{}\''.format(trials_file),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
mock_dump.assert_called_once()
|
mock_dump.assert_called_once()
|
||||||
|
|
||||||
|
|
||||||
|
@ -413,10 +389,7 @@ def test_read_trials_returns_trials_file(mocker, hyperopt, caplog) -> None:
|
||||||
mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=trials)
|
mock_load = mocker.patch('freqtrade.optimize.hyperopt.load', return_value=trials)
|
||||||
hyperopt_trial = hyperopt.read_trials()
|
hyperopt_trial = hyperopt.read_trials()
|
||||||
trials_file = os.path.join('freqtrade', 'tests', 'optimize', 'ut_trials.pickle')
|
trials_file = os.path.join('freqtrade', 'tests', 'optimize', 'ut_trials.pickle')
|
||||||
assert log_has(
|
assert log_has('Reading Trials from \'{}\''.format(trials_file), caplog)
|
||||||
'Reading Trials from \'{}\''.format(trials_file),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert hyperopt_trial == trials
|
assert hyperopt_trial == trials
|
||||||
mock_load.assert_called_once()
|
mock_load.assert_called_once()
|
||||||
|
|
||||||
|
@ -626,7 +599,7 @@ def test_clean_hyperopt(mocker, default_conf, caplog):
|
||||||
Hyperopt(default_conf)
|
Hyperopt(default_conf)
|
||||||
|
|
||||||
assert unlinkmock.call_count == 2
|
assert unlinkmock.call_count == 2
|
||||||
assert log_has(f"Removing `{TICKERDATA_PICKLE}`.", caplog.record_tuples)
|
assert log_has(f"Removing `{TICKERDATA_PICKLE}`.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_continue_hyperopt(mocker, default_conf, caplog):
|
def test_continue_hyperopt(mocker, default_conf, caplog):
|
||||||
|
@ -643,4 +616,4 @@ def test_continue_hyperopt(mocker, default_conf, caplog):
|
||||||
Hyperopt(default_conf)
|
Hyperopt(default_conf)
|
||||||
|
|
||||||
assert unlinkmock.call_count == 0
|
assert unlinkmock.call_count == 0
|
||||||
assert log_has(f"Continuing on previous hyperopt results.", caplog.record_tuples)
|
assert log_has(f"Continuing on previous hyperopt results.", caplog)
|
||||||
|
|
|
@ -91,7 +91,7 @@ def test_fiat_convert_unsupported_crypto(mocker, caplog):
|
||||||
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._cryptomap', return_value=[])
|
mocker.patch('freqtrade.rpc.fiat_convert.CryptoToFiatConverter._cryptomap', return_value=[])
|
||||||
fiat_convert = CryptoToFiatConverter()
|
fiat_convert = CryptoToFiatConverter()
|
||||||
assert fiat_convert._find_price(crypto_symbol='CRYPTO_123', fiat_symbol='EUR') == 0.0
|
assert fiat_convert._find_price(crypto_symbol='CRYPTO_123', fiat_symbol='EUR') == 0.0
|
||||||
assert log_has('unsupported crypto-symbol CRYPTO_123 - returning 0.0', caplog.record_tuples)
|
assert log_has('unsupported crypto-symbol CRYPTO_123 - returning 0.0', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_fiat_convert_get_price(mocker):
|
def test_fiat_convert_get_price(mocker):
|
||||||
|
@ -190,7 +190,7 @@ def test_fiat_invalid_response(mocker, caplog):
|
||||||
length_cryptomap = len(fiat_convert._cryptomap)
|
length_cryptomap = len(fiat_convert._cryptomap)
|
||||||
assert length_cryptomap == 0
|
assert length_cryptomap == 0
|
||||||
assert log_has('Could not load FIAT Cryptocurrency map for the following problem: TypeError',
|
assert log_has('Could not load FIAT Cryptocurrency map for the following problem: TypeError',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_convert_amount(mocker):
|
def test_convert_amount(mocker):
|
||||||
|
|
|
@ -148,8 +148,8 @@ def test_api_run(default_conf, mocker, caplog):
|
||||||
assert isinstance(server_mock.call_args_list[0][0][2], Flask)
|
assert isinstance(server_mock.call_args_list[0][0][2], Flask)
|
||||||
assert hasattr(apiserver, "srv")
|
assert hasattr(apiserver, "srv")
|
||||||
|
|
||||||
assert log_has("Starting HTTP Server at 127.0.0.1:8080", caplog.record_tuples)
|
assert log_has("Starting HTTP Server at 127.0.0.1:8080", caplog)
|
||||||
assert log_has("Starting Local Rest Server.", caplog.record_tuples)
|
assert log_has("Starting Local Rest Server.", caplog)
|
||||||
|
|
||||||
# Test binding to public
|
# Test binding to public
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
@ -165,22 +165,20 @@ def test_api_run(default_conf, mocker, caplog):
|
||||||
assert server_mock.call_args_list[0][0][0] == "0.0.0.0"
|
assert server_mock.call_args_list[0][0][0] == "0.0.0.0"
|
||||||
assert server_mock.call_args_list[0][0][1] == "8089"
|
assert server_mock.call_args_list[0][0][1] == "8089"
|
||||||
assert isinstance(server_mock.call_args_list[0][0][2], Flask)
|
assert isinstance(server_mock.call_args_list[0][0][2], Flask)
|
||||||
assert log_has("Starting HTTP Server at 0.0.0.0:8089", caplog.record_tuples)
|
assert log_has("Starting HTTP Server at 0.0.0.0:8089", caplog)
|
||||||
assert log_has("Starting Local Rest Server.", caplog.record_tuples)
|
assert log_has("Starting Local Rest Server.", caplog)
|
||||||
assert log_has("SECURITY WARNING - Local Rest Server listening to external connections",
|
assert log_has("SECURITY WARNING - Local Rest Server listening to external connections",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
assert log_has("SECURITY WARNING - This is insecure please set to your loopback,"
|
assert log_has("SECURITY WARNING - This is insecure please set to your loopback,"
|
||||||
"e.g 127.0.0.1 in config.json",
|
"e.g 127.0.0.1 in config.json", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
assert log_has("SECURITY WARNING - No password for local REST Server defined. "
|
assert log_has("SECURITY WARNING - No password for local REST Server defined. "
|
||||||
"Please make sure that this is intentional!",
|
"Please make sure that this is intentional!", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
# Test crashing flask
|
# Test crashing flask
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
mocker.patch('freqtrade.rpc.api_server.make_server', MagicMock(side_effect=Exception))
|
mocker.patch('freqtrade.rpc.api_server.make_server', MagicMock(side_effect=Exception))
|
||||||
apiserver.run()
|
apiserver.run()
|
||||||
assert log_has("Api server failed to start.", caplog.record_tuples)
|
assert log_has("Api server failed to start.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_api_cleanup(default_conf, mocker, caplog):
|
def test_api_cleanup(default_conf, mocker, caplog):
|
||||||
|
@ -199,7 +197,7 @@ def test_api_cleanup(default_conf, mocker, caplog):
|
||||||
|
|
||||||
apiserver.cleanup()
|
apiserver.cleanup()
|
||||||
assert stop_mock.shutdown.call_count == 1
|
assert stop_mock.shutdown.call_count == 1
|
||||||
assert log_has("Stopping API Server", caplog.record_tuples)
|
assert log_has("Stopping API Server", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_api_reloadconf(botclient):
|
def test_api_reloadconf(botclient):
|
||||||
|
|
|
@ -19,7 +19,7 @@ def test_init_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf['telegram']['enabled'] = False
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.telegram ...', caplog.record_tuples)
|
assert not log_has('Enabling rpc.telegram ...', caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ def test_init_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert log_has('Enabling rpc.telegram ...', caplog.record_tuples)
|
assert log_has('Enabling rpc.telegram ...', caplog)
|
||||||
len_modules = len(rpc_manager.registered_modules)
|
len_modules = len(rpc_manager.registered_modules)
|
||||||
assert len_modules == 1
|
assert len_modules == 1
|
||||||
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
@ -43,7 +43,7 @@ def test_cleanup_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
rpc_manager = RPCManager(freqtradebot)
|
rpc_manager = RPCManager(freqtradebot)
|
||||||
rpc_manager.cleanup()
|
rpc_manager.cleanup()
|
||||||
|
|
||||||
assert not log_has('Cleaning up rpc.telegram ...', caplog.record_tuples)
|
assert not log_has('Cleaning up rpc.telegram ...', caplog)
|
||||||
assert telegram_mock.call_count == 0
|
assert telegram_mock.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ def test_cleanup_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
assert 'telegram' in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
|
||||||
rpc_manager.cleanup()
|
rpc_manager.cleanup()
|
||||||
assert log_has('Cleaning up rpc.telegram ...', caplog.record_tuples)
|
assert log_has('Cleaning up rpc.telegram ...', caplog)
|
||||||
assert 'telegram' not in [mod.name for mod in rpc_manager.registered_modules]
|
assert 'telegram' not in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
assert telegram_mock.call_count == 1
|
assert telegram_mock.call_count == 1
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
|
||||||
'status': 'test'
|
'status': 'test'
|
||||||
})
|
})
|
||||||
|
|
||||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog.record_tuples)
|
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||||
assert telegram_mock.call_count == 0
|
assert telegram_mock.call_count == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
|
||||||
'status': 'test'
|
'status': 'test'
|
||||||
})
|
})
|
||||||
|
|
||||||
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog.record_tuples)
|
assert log_has("Sending rpc message: {'type': status, 'status': 'test'}", caplog)
|
||||||
assert telegram_mock.call_count == 1
|
assert telegram_mock.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ def test_init_webhook_disabled(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['webhook'] = {'enabled': False}
|
default_conf['webhook'] = {'enabled': False}
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.webhook ...', caplog.record_tuples)
|
assert not log_has('Enabling rpc.webhook ...', caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
|
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ def test_init_webhook_enabled(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
|
default_conf['webhook'] = {'enabled': True, 'url': "https://DEADBEEF.com"}
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert log_has('Enabling rpc.webhook ...', caplog.record_tuples)
|
assert log_has('Enabling rpc.webhook ...', caplog)
|
||||||
assert len(rpc_manager.registered_modules) == 1
|
assert len(rpc_manager.registered_modules) == 1
|
||||||
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]
|
assert 'webhook' in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ def test_init_apiserver_disabled(mocker, default_conf, caplog) -> None:
|
||||||
default_conf['telegram']['enabled'] = False
|
default_conf['telegram']['enabled'] = False
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert not log_has('Enabling rpc.api_server', caplog.record_tuples)
|
assert not log_has('Enabling rpc.api_server', caplog)
|
||||||
assert rpc_manager.registered_modules == []
|
assert rpc_manager.registered_modules == []
|
||||||
assert run_mock.call_count == 0
|
assert run_mock.call_count == 0
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ def test_init_apiserver_enabled(mocker, default_conf, caplog) -> None:
|
||||||
"listen_port": "8080"}
|
"listen_port": "8080"}
|
||||||
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
rpc_manager = RPCManager(get_patched_freqtradebot(mocker, default_conf))
|
||||||
|
|
||||||
assert log_has('Enabling rpc.api_server', caplog.record_tuples)
|
assert log_has('Enabling rpc.api_server', caplog)
|
||||||
assert len(rpc_manager.registered_modules) == 1
|
assert len(rpc_manager.registered_modules) == 1
|
||||||
assert 'apiserver' in [mod.name for mod in rpc_manager.registered_modules]
|
assert 'apiserver' in [mod.name for mod in rpc_manager.registered_modules]
|
||||||
assert run_mock.call_count == 1
|
assert run_mock.call_count == 1
|
||||||
|
|
|
@ -76,7 +76,7 @@ def test_init(default_conf, mocker, caplog) -> None:
|
||||||
"['performance'], ['daily'], ['count'], ['reload_conf'], " \
|
"['performance'], ['daily'], ['count'], ['reload_conf'], " \
|
||||||
"['stopbuy'], ['whitelist'], ['blacklist'], ['edge'], ['help'], ['version']]"
|
"['stopbuy'], ['whitelist'], ['blacklist'], ['edge'], ['help'], ['version']]"
|
||||||
|
|
||||||
assert log_has(message_str, caplog.record_tuples)
|
assert log_has(message_str, caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_cleanup(default_conf, mocker) -> None:
|
def test_cleanup(default_conf, mocker) -> None:
|
||||||
|
@ -102,18 +102,9 @@ def test_authorized_only(default_conf, mocker, caplog) -> None:
|
||||||
dummy = DummyCls(bot)
|
dummy = DummyCls(bot)
|
||||||
dummy.dummy_handler(bot=MagicMock(), update=update)
|
dummy.dummy_handler(bot=MagicMock(), update=update)
|
||||||
assert dummy.state['called'] is True
|
assert dummy.state['called'] is True
|
||||||
assert log_has(
|
assert log_has('Executing handler: dummy_handler for chat_id: 0', caplog)
|
||||||
'Executing handler: dummy_handler for chat_id: 0',
|
assert not log_has('Rejected unauthorized message from: 0', caplog)
|
||||||
caplog.record_tuples
|
assert not log_has('Exception occurred within Telegram module', caplog)
|
||||||
)
|
|
||||||
assert not log_has(
|
|
||||||
'Rejected unauthorized message from: 0',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert not log_has(
|
|
||||||
'Exception occurred within Telegram module',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_authorized_only_unauthorized(default_conf, mocker, caplog) -> None:
|
def test_authorized_only_unauthorized(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -128,18 +119,9 @@ def test_authorized_only_unauthorized(default_conf, mocker, caplog) -> None:
|
||||||
dummy = DummyCls(bot)
|
dummy = DummyCls(bot)
|
||||||
dummy.dummy_handler(bot=MagicMock(), update=update)
|
dummy.dummy_handler(bot=MagicMock(), update=update)
|
||||||
assert dummy.state['called'] is False
|
assert dummy.state['called'] is False
|
||||||
assert not log_has(
|
assert not log_has('Executing handler: dummy_handler for chat_id: 3735928559', caplog)
|
||||||
'Executing handler: dummy_handler for chat_id: 3735928559',
|
assert log_has('Rejected unauthorized message from: 3735928559', caplog)
|
||||||
caplog.record_tuples
|
assert not log_has('Exception occurred within Telegram module', caplog)
|
||||||
)
|
|
||||||
assert log_has(
|
|
||||||
'Rejected unauthorized message from: 3735928559',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert not log_has(
|
|
||||||
'Exception occurred within Telegram module',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
|
def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -156,18 +138,9 @@ def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
|
||||||
|
|
||||||
dummy.dummy_exception(bot=MagicMock(), update=update)
|
dummy.dummy_exception(bot=MagicMock(), update=update)
|
||||||
assert dummy.state['called'] is False
|
assert dummy.state['called'] is False
|
||||||
assert not log_has(
|
assert not log_has('Executing handler: dummy_handler for chat_id: 0', caplog)
|
||||||
'Executing handler: dummy_handler for chat_id: 0',
|
assert not log_has('Rejected unauthorized message from: 0', caplog)
|
||||||
caplog.record_tuples
|
assert log_has('Exception occurred within Telegram module', caplog)
|
||||||
)
|
|
||||||
assert not log_has(
|
|
||||||
'Rejected unauthorized message from: 0',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert log_has(
|
|
||||||
'Exception occurred within Telegram module',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
|
||||||
|
@ -1440,7 +1413,4 @@ def test__send_msg_network_error(default_conf, mocker, caplog) -> None:
|
||||||
|
|
||||||
# Bot should've tried to send it twice
|
# Bot should've tried to send it twice
|
||||||
assert len(bot.method_calls) == 2
|
assert len(bot.method_calls) == 2
|
||||||
assert log_has(
|
assert log_has('Telegram NetworkError: Oh snap! Trying one more time.', caplog)
|
||||||
'Telegram NetworkError: Oh snap! Trying one more time.',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
|
@ -115,7 +115,7 @@ def test_exception_send_msg(default_conf, mocker, caplog):
|
||||||
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
|
webhook = Webhook(get_patched_freqtradebot(mocker, default_conf))
|
||||||
webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION})
|
webhook.send_msg({'type': RPCMessageType.BUY_NOTIFICATION})
|
||||||
assert log_has(f"Message type {RPCMessageType.BUY_NOTIFICATION} not configured for webhooks",
|
assert log_has(f"Message type {RPCMessageType.BUY_NOTIFICATION} not configured for webhooks",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
default_conf["webhook"] = get_webhook_dict()
|
default_conf["webhook"] = get_webhook_dict()
|
||||||
default_conf["webhook"]["webhookbuy"]["value1"] = "{DEADBEEF:8f}"
|
default_conf["webhook"]["webhookbuy"]["value1"] = "{DEADBEEF:8f}"
|
||||||
|
@ -135,7 +135,7 @@ def test_exception_send_msg(default_conf, mocker, caplog):
|
||||||
}
|
}
|
||||||
webhook.send_msg(msg)
|
webhook.send_msg(msg)
|
||||||
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
|
assert log_has("Problem calling Webhook. Please check your webhook configuration. "
|
||||||
"Exception: 'DEADBEEF'", caplog.record_tuples)
|
"Exception: 'DEADBEEF'", caplog)
|
||||||
|
|
||||||
msg_mock = MagicMock()
|
msg_mock = MagicMock()
|
||||||
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
mocker.patch("freqtrade.rpc.webhook.Webhook._send_msg", msg_mock)
|
||||||
|
@ -164,4 +164,4 @@ def test__send_msg(default_conf, mocker, caplog):
|
||||||
post = MagicMock(side_effect=RequestException)
|
post = MagicMock(side_effect=RequestException)
|
||||||
mocker.patch("freqtrade.rpc.webhook.post", post)
|
mocker.patch("freqtrade.rpc.webhook.post", post)
|
||||||
webhook._send_msg(msg)
|
webhook._send_msg(msg)
|
||||||
assert log_has('Could not call webhook url. Exception: ', caplog.record_tuples)
|
assert log_has('Could not call webhook url. Exception: ', caplog)
|
||||||
|
|
|
@ -49,12 +49,12 @@ def test_returns_latest_sell_signal(mocker, default_conf, ticker_history):
|
||||||
def test_get_signal_empty(default_conf, mocker, caplog):
|
def test_get_signal_empty(default_conf, mocker, caplog):
|
||||||
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
||||||
DataFrame())
|
DataFrame())
|
||||||
assert log_has('Empty ticker history for pair foo', caplog.record_tuples)
|
assert log_has('Empty ticker history for pair foo', caplog)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
assert (False, False) == _STRATEGY.get_signal('bar', default_conf['ticker_interval'],
|
assert (False, False) == _STRATEGY.get_signal('bar', default_conf['ticker_interval'],
|
||||||
[])
|
[])
|
||||||
assert log_has('Empty ticker history for pair bar', caplog.record_tuples)
|
assert log_has('Empty ticker history for pair bar', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_history):
|
def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_history):
|
||||||
|
@ -65,7 +65,7 @@ def test_get_signal_exception_valueerror(default_conf, mocker, caplog, ticker_hi
|
||||||
)
|
)
|
||||||
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
assert (False, False) == _STRATEGY.get_signal('foo', default_conf['ticker_interval'],
|
||||||
ticker_history)
|
ticker_history)
|
||||||
assert log_has('Unable to analyze ticker for pair foo: xyz', caplog.record_tuples)
|
assert log_has('Unable to analyze ticker for pair foo: xyz', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history):
|
def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||||
|
@ -76,7 +76,7 @@ def test_get_signal_empty_dataframe(default_conf, mocker, caplog, ticker_history
|
||||||
)
|
)
|
||||||
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
||||||
ticker_history)
|
ticker_history)
|
||||||
assert log_has('Empty dataframe for pair xyz', caplog.record_tuples)
|
assert log_has('Empty dataframe for pair xyz', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history):
|
def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||||
|
@ -91,10 +91,7 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog, ticker_history):
|
||||||
)
|
)
|
||||||
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
assert (False, False) == _STRATEGY.get_signal('xyz', default_conf['ticker_interval'],
|
||||||
ticker_history)
|
ticker_history)
|
||||||
assert log_has(
|
assert log_has('Outdated history for pair xyz. Last tick is 16 minutes old', caplog)
|
||||||
'Outdated history for pair xyz. Last tick is 16 minutes old',
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_get_signal_handles_exceptions(mocker, default_conf):
|
def test_get_signal_handles_exceptions(mocker, default_conf):
|
||||||
|
@ -237,9 +234,8 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||||
assert buy_mock.call_count == 1
|
assert buy_mock.call_count == 1
|
||||||
assert buy_mock.call_count == 1
|
assert buy_mock.call_count == 1
|
||||||
|
|
||||||
assert log_has('TA Analysis Launched', caplog.record_tuples)
|
assert log_has('TA Analysis Launched', caplog)
|
||||||
assert not log_has('Skipping TA Analysis for already analyzed candle',
|
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'})
|
strategy.analyze_ticker(ticker_history, {'pair': 'ETH/BTC'})
|
||||||
|
@ -247,9 +243,8 @@ def test_analyze_ticker_default(ticker_history, mocker, caplog) -> None:
|
||||||
assert ind_mock.call_count == 2
|
assert ind_mock.call_count == 2
|
||||||
assert buy_mock.call_count == 2
|
assert buy_mock.call_count == 2
|
||||||
assert buy_mock.call_count == 2
|
assert buy_mock.call_count == 2
|
||||||
assert log_has('TA Analysis Launched', caplog.record_tuples)
|
assert log_has('TA Analysis Launched', caplog)
|
||||||
assert not log_has('Skipping TA Analysis for already analyzed candle',
|
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -> None:
|
def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -> None:
|
||||||
|
@ -275,9 +270,8 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -
|
||||||
assert ind_mock.call_count == 1
|
assert ind_mock.call_count == 1
|
||||||
assert buy_mock.call_count == 1
|
assert buy_mock.call_count == 1
|
||||||
assert buy_mock.call_count == 1
|
assert buy_mock.call_count == 1
|
||||||
assert log_has('TA Analysis Launched', caplog.record_tuples)
|
assert log_has('TA Analysis Launched', caplog)
|
||||||
assert not log_has('Skipping TA Analysis for already analyzed candle',
|
assert not log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'})
|
ret = strategy._analyze_ticker_internal(ticker_history, {'pair': 'ETH/BTC'})
|
||||||
|
@ -290,6 +284,5 @@ def test__analyze_ticker_internal_skip_analyze(ticker_history, mocker, caplog) -
|
||||||
assert 'sell' in ret.columns
|
assert 'sell' in ret.columns
|
||||||
assert ret['buy'].sum() == 0
|
assert ret['buy'].sum() == 0
|
||||||
assert ret['sell'].sum() == 0
|
assert ret['sell'].sum() == 0
|
||||||
assert not log_has('TA Analysis Launched', caplog.record_tuples)
|
assert not log_has('TA Analysis Launched', caplog)
|
||||||
assert log_has('Skipping TA Analysis for already analyzed candle',
|
assert log_has('Skipping TA Analysis for already analyzed candle', caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ from freqtrade.resolvers import StrategyResolver
|
||||||
from freqtrade.strategy import import_strategy
|
from freqtrade.strategy import import_strategy
|
||||||
from freqtrade.strategy.default_strategy import DefaultStrategy
|
from freqtrade.strategy.default_strategy import DefaultStrategy
|
||||||
from freqtrade.strategy.interface import IStrategy
|
from freqtrade.strategy.interface import IStrategy
|
||||||
from freqtrade.tests.conftest import log_has_re, log_has
|
from freqtrade.tests.conftest import log_has, log_has_re
|
||||||
|
|
||||||
|
|
||||||
def test_import_strategy(caplog):
|
def test_import_strategy(caplog):
|
||||||
|
@ -35,12 +35,8 @@ def test_import_strategy(caplog):
|
||||||
assert imported_strategy.__module__ == 'freqtrade.strategy'
|
assert imported_strategy.__module__ == 'freqtrade.strategy'
|
||||||
assert imported_strategy.some_method() == 42
|
assert imported_strategy.some_method() == 42
|
||||||
|
|
||||||
assert (
|
assert log_has('Imported strategy freqtrade.strategy.default_strategy.DefaultStrategy '
|
||||||
'freqtrade.strategy',
|
'as freqtrade.strategy.DefaultStrategy', caplog)
|
||||||
logging.DEBUG,
|
|
||||||
'Imported strategy freqtrade.strategy.default_strategy.DefaultStrategy '
|
|
||||||
'as freqtrade.strategy.DefaultStrategy',
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_search_strategy():
|
def test_search_strategy():
|
||||||
|
@ -76,8 +72,7 @@ def test_load_strategy_base64(result, caplog):
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
# Make sure strategy was loaded from base64 (using temp directory)!!
|
# Make sure strategy was loaded from base64 (using temp directory)!!
|
||||||
assert log_has_re(r"Using resolved strategy TestStrategy from '"
|
assert log_has_re(r"Using resolved strategy TestStrategy from '"
|
||||||
+ tempfile.gettempdir() + r"/.*/TestStrategy\.py'\.\.\.",
|
+ tempfile.gettempdir() + r"/.*/TestStrategy\.py'\.\.\.", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_load_strategy_invalid_directory(result, caplog):
|
def test_load_strategy_invalid_directory(result, caplog):
|
||||||
|
@ -85,7 +80,7 @@ def test_load_strategy_invalid_directory(result, caplog):
|
||||||
extra_dir = Path.cwd() / 'some/path'
|
extra_dir = Path.cwd() / 'some/path'
|
||||||
resolver._load_strategy('TestStrategy', config={}, extra_dir=extra_dir)
|
resolver._load_strategy('TestStrategy', config={}, extra_dir=extra_dir)
|
||||||
|
|
||||||
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog.record_tuples)
|
assert log_has_re(r'Path .*' + r'some.*path.*' + r'.* does not exist', caplog)
|
||||||
|
|
||||||
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
assert 'adx' in resolver.strategy.advise_indicators(result, {'pair': 'ETH/BTC'})
|
||||||
|
|
||||||
|
@ -105,7 +100,7 @@ def test_load_staticmethod_importerror(mocker, caplog):
|
||||||
match=r"Impossible to load Strategy 'DefaultStrategy'. "
|
match=r"Impossible to load Strategy 'DefaultStrategy'. "
|
||||||
r"This class does not exist or contains Python code errors."):
|
r"This class does not exist or contains Python code errors."):
|
||||||
StrategyResolver()
|
StrategyResolver()
|
||||||
assert log_has_re(r".*Error: can't pickle staticmethod objects", caplog.record_tuples)
|
assert log_has_re(r".*Error: can't pickle staticmethod objects", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_strategy(result):
|
def test_strategy(result):
|
||||||
|
@ -143,10 +138,7 @@ def test_strategy_override_minimal_roi(caplog):
|
||||||
resolver = StrategyResolver(config)
|
resolver = StrategyResolver(config)
|
||||||
|
|
||||||
assert resolver.strategy.minimal_roi[0] == 0.5
|
assert resolver.strategy.minimal_roi[0] == 0.5
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'minimal_roi' with value in config file: {'0': 0.5}.", caplog)
|
||||||
logging.INFO,
|
|
||||||
"Override strategy 'minimal_roi' with value in config file: {'0': 0.5}."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_stoploss(caplog):
|
def test_strategy_override_stoploss(caplog):
|
||||||
|
@ -158,10 +150,7 @@ def test_strategy_override_stoploss(caplog):
|
||||||
resolver = StrategyResolver(config)
|
resolver = StrategyResolver(config)
|
||||||
|
|
||||||
assert resolver.strategy.stoploss == -0.5
|
assert resolver.strategy.stoploss == -0.5
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'stoploss' with value in config file: -0.5.", caplog)
|
||||||
logging.INFO,
|
|
||||||
"Override strategy 'stoploss' with value in config file: -0.5."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_trailing_stop(caplog):
|
def test_strategy_override_trailing_stop(caplog):
|
||||||
|
@ -174,10 +163,7 @@ def test_strategy_override_trailing_stop(caplog):
|
||||||
|
|
||||||
assert resolver.strategy.trailing_stop
|
assert resolver.strategy.trailing_stop
|
||||||
assert isinstance(resolver.strategy.trailing_stop, bool)
|
assert isinstance(resolver.strategy.trailing_stop, bool)
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'trailing_stop' with value in config file: True.", caplog)
|
||||||
logging.INFO,
|
|
||||||
"Override strategy 'trailing_stop' with value in config file: True."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_trailing_stop_positive(caplog):
|
def test_strategy_override_trailing_stop_positive(caplog):
|
||||||
|
@ -191,16 +177,12 @@ def test_strategy_override_trailing_stop_positive(caplog):
|
||||||
resolver = StrategyResolver(config)
|
resolver = StrategyResolver(config)
|
||||||
|
|
||||||
assert resolver.strategy.trailing_stop_positive == -0.1
|
assert resolver.strategy.trailing_stop_positive == -0.1
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'trailing_stop_positive' with value in config file: -0.1.",
|
||||||
logging.INFO,
|
caplog)
|
||||||
"Override strategy 'trailing_stop_positive' with value in config file: -0.1."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
assert resolver.strategy.trailing_stop_positive_offset == -0.2
|
assert resolver.strategy.trailing_stop_positive_offset == -0.2
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'trailing_stop_positive' with value in config file: -0.1.",
|
||||||
logging.INFO,
|
caplog)
|
||||||
"Override strategy 'trailing_stop_positive' with value in config file: -0.1."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_ticker_interval(caplog):
|
def test_strategy_override_ticker_interval(caplog):
|
||||||
|
@ -215,10 +197,8 @@ def test_strategy_override_ticker_interval(caplog):
|
||||||
|
|
||||||
assert resolver.strategy.ticker_interval == 60
|
assert resolver.strategy.ticker_interval == 60
|
||||||
assert resolver.strategy.stake_currency == 'ETH'
|
assert resolver.strategy.stake_currency == 'ETH'
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'ticker_interval' with value in config file: 60.",
|
||||||
logging.INFO,
|
caplog)
|
||||||
"Override strategy 'ticker_interval' with value in config file: 60."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_process_only_new_candles(caplog):
|
def test_strategy_override_process_only_new_candles(caplog):
|
||||||
|
@ -231,10 +211,8 @@ def test_strategy_override_process_only_new_candles(caplog):
|
||||||
resolver = StrategyResolver(config)
|
resolver = StrategyResolver(config)
|
||||||
|
|
||||||
assert resolver.strategy.process_only_new_candles
|
assert resolver.strategy.process_only_new_candles
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'process_only_new_candles' with value in config file: True.",
|
||||||
logging.INFO,
|
caplog)
|
||||||
"Override strategy 'process_only_new_candles' with value in config file: True."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_order_types(caplog):
|
def test_strategy_override_order_types(caplog):
|
||||||
|
@ -259,7 +237,7 @@ def test_strategy_override_order_types(caplog):
|
||||||
|
|
||||||
assert log_has("Override strategy 'order_types' with value in config file:"
|
assert log_has("Override strategy 'order_types' with value in config file:"
|
||||||
" {'buy': 'market', 'sell': 'limit', 'stoploss': 'limit',"
|
" {'buy': 'market', 'sell': 'limit', 'stoploss': 'limit',"
|
||||||
" 'stoploss_on_exchange': True}.", caplog.record_tuples)
|
" 'stoploss_on_exchange': True}.", caplog)
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
'strategy': 'DefaultStrategy',
|
'strategy': 'DefaultStrategy',
|
||||||
|
@ -290,11 +268,8 @@ def test_strategy_override_order_tif(caplog):
|
||||||
for method in ['buy', 'sell']:
|
for method in ['buy', 'sell']:
|
||||||
assert resolver.strategy.order_time_in_force[method] == order_time_in_force[method]
|
assert resolver.strategy.order_time_in_force[method] == order_time_in_force[method]
|
||||||
|
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'order_time_in_force' with value in config file:"
|
||||||
logging.INFO,
|
" {'buy': 'fok', 'sell': 'gtc'}.", caplog)
|
||||||
"Override strategy 'order_time_in_force' with value in config file:"
|
|
||||||
" {'buy': 'fok', 'sell': 'gtc'}."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
'strategy': 'DefaultStrategy',
|
'strategy': 'DefaultStrategy',
|
||||||
|
@ -329,10 +304,7 @@ def test_strategy_override_use_sell_signal(caplog):
|
||||||
|
|
||||||
assert resolver.strategy.use_sell_signal
|
assert resolver.strategy.use_sell_signal
|
||||||
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
assert isinstance(resolver.strategy.use_sell_signal, bool)
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'use_sell_signal' with value in config file: True.", caplog)
|
||||||
logging.INFO,
|
|
||||||
"Override strategy 'use_sell_signal' with value in config file: True."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
def test_strategy_override_use_sell_profit_only(caplog):
|
def test_strategy_override_use_sell_profit_only(caplog):
|
||||||
|
@ -357,10 +329,7 @@ def test_strategy_override_use_sell_profit_only(caplog):
|
||||||
|
|
||||||
assert resolver.strategy.sell_profit_only
|
assert resolver.strategy.sell_profit_only
|
||||||
assert isinstance(resolver.strategy.sell_profit_only, bool)
|
assert isinstance(resolver.strategy.sell_profit_only, bool)
|
||||||
assert ('freqtrade.resolvers.strategy_resolver',
|
assert log_has("Override strategy 'sell_profit_only' with value in config file: True.", caplog)
|
||||||
logging.INFO,
|
|
||||||
"Override strategy 'sell_profit_only' with value in config file: True."
|
|
||||||
) in caplog.record_tuples
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.filterwarnings("ignore:deprecated")
|
@pytest.mark.filterwarnings("ignore:deprecated")
|
||||||
|
|
|
@ -72,7 +72,7 @@ def test__args_to_config(caplog):
|
||||||
# No warnings ...
|
# No warnings ...
|
||||||
configuration._args_to_config(config, argname="strategy_path", logstring="DeadBeef")
|
configuration._args_to_config(config, argname="strategy_path", logstring="DeadBeef")
|
||||||
assert len(w) == 0
|
assert len(w) == 0
|
||||||
assert log_has("DeadBeef", caplog.record_tuples)
|
assert log_has("DeadBeef", caplog)
|
||||||
assert config['strategy_path'] == "TestTest"
|
assert config['strategy_path'] == "TestTest"
|
||||||
|
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
|
@ -84,7 +84,7 @@ def test__args_to_config(caplog):
|
||||||
assert len(w) == 1
|
assert len(w) == 1
|
||||||
assert issubclass(w[-1].category, DeprecationWarning)
|
assert issubclass(w[-1].category, DeprecationWarning)
|
||||||
assert "DEPRECATED: Going away soon!" in str(w[-1].message)
|
assert "DEPRECATED: Going away soon!" in str(w[-1].message)
|
||||||
assert log_has("DeadBeef", caplog.record_tuples)
|
assert log_has("DeadBeef", caplog)
|
||||||
assert config['strategy_path'] == "TestTest"
|
assert config['strategy_path'] == "TestTest"
|
||||||
|
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ def test_load_config_max_open_trades_zero(default_conf, mocker, caplog) -> None:
|
||||||
|
|
||||||
assert validated_conf['max_open_trades'] == 0
|
assert validated_conf['max_open_trades'] == 0
|
||||||
assert 'internals' in validated_conf
|
assert 'internals' in validated_conf
|
||||||
assert log_has('Validating configuration ...', caplog.record_tuples)
|
assert log_has('Validating configuration ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -130,7 +130,7 @@ def test_load_config_combine_dicts(default_conf, mocker, caplog) -> None:
|
||||||
assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange']['pair_whitelist']
|
assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange']['pair_whitelist']
|
||||||
|
|
||||||
assert 'internals' in validated_conf
|
assert 'internals' in validated_conf
|
||||||
assert log_has('Validating configuration ...', caplog.record_tuples)
|
assert log_has('Validating configuration ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_from_config(default_conf, mocker, caplog) -> None:
|
def test_from_config(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -159,7 +159,7 @@ def test_from_config(default_conf, mocker, caplog) -> None:
|
||||||
assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange']['pair_whitelist']
|
assert validated_conf['exchange']['pair_whitelist'] == conf2['exchange']['pair_whitelist']
|
||||||
assert validated_conf['fiat_display_currency'] == "EUR"
|
assert validated_conf['fiat_display_currency'] == "EUR"
|
||||||
assert 'internals' in validated_conf
|
assert 'internals' in validated_conf
|
||||||
assert log_has('Validating configuration ...', caplog.record_tuples)
|
assert log_has('Validating configuration ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
|
def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -172,7 +172,7 @@ def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) ->
|
||||||
|
|
||||||
assert validated_conf['max_open_trades'] > 999999999
|
assert validated_conf['max_open_trades'] > 999999999
|
||||||
assert validated_conf['max_open_trades'] == float('inf')
|
assert validated_conf['max_open_trades'] == float('inf')
|
||||||
assert log_has('Validating configuration ...', caplog.record_tuples)
|
assert log_has('Validating configuration ...', caplog)
|
||||||
assert "runmode" in validated_conf
|
assert "runmode" in validated_conf
|
||||||
assert validated_conf['runmode'] == RunMode.DRY_RUN
|
assert validated_conf['runmode'] == RunMode.DRY_RUN
|
||||||
|
|
||||||
|
@ -309,8 +309,8 @@ def test_show_info(default_conf, mocker, caplog) -> None:
|
||||||
configuration = Configuration(args)
|
configuration = Configuration(args)
|
||||||
configuration.get_config()
|
configuration.get_config()
|
||||||
|
|
||||||
assert log_has('Using DB: "sqlite:///tmp/testdb"', caplog.record_tuples)
|
assert log_has('Using DB: "sqlite:///tmp/testdb"', caplog)
|
||||||
assert log_has('Dry run is enabled', caplog.record_tuples)
|
assert log_has('Dry run is enabled', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -332,21 +332,18 @@ def test_setup_configuration_without_arguments(mocker, default_conf, caplog) ->
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert not log_has('Parameter -i/--ticker-interval detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -i/--ticker-interval detected ...', caplog)
|
||||||
|
|
||||||
assert 'live' not in config
|
assert 'live' not in config
|
||||||
assert not log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -l/--live detected ...', caplog)
|
||||||
|
|
||||||
assert 'position_stacking' not in config
|
assert 'position_stacking' not in config
|
||||||
assert not log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert not log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs' not in config
|
assert 'refresh_pairs' not in config
|
||||||
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert not log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
|
|
||||||
assert 'timerange' not in config
|
assert 'timerange' not in config
|
||||||
assert 'export' not in config
|
assert 'export' not in config
|
||||||
|
@ -384,37 +381,28 @@ def test_setup_configuration_with_arguments(mocker, default_conf, caplog) -> Non
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'live' in config
|
assert 'live' in config
|
||||||
assert log_has('Parameter -l/--live detected ...', caplog.record_tuples)
|
assert log_has('Parameter -l/--live detected ...', caplog)
|
||||||
|
|
||||||
assert 'position_stacking'in config
|
assert 'position_stacking'in config
|
||||||
assert log_has('Parameter --enable-position-stacking detected ...', caplog.record_tuples)
|
assert log_has('Parameter --enable-position-stacking detected ...', caplog)
|
||||||
|
|
||||||
assert 'use_max_market_positions' in config
|
assert 'use_max_market_positions' in config
|
||||||
assert log_has('Parameter --disable-max-market-positions detected ...', caplog.record_tuples)
|
assert log_has('Parameter --disable-max-market-positions detected ...', caplog)
|
||||||
assert log_has('max_open_trades set to unlimited ...', caplog.record_tuples)
|
assert log_has('max_open_trades set to unlimited ...', caplog)
|
||||||
|
|
||||||
assert 'refresh_pairs'in config
|
assert 'refresh_pairs'in config
|
||||||
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog.record_tuples)
|
assert log_has('Parameter -r/--refresh-pairs-cached detected ...', caplog)
|
||||||
assert 'timerange' in config
|
assert 'timerange' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --timerange detected: {} ...'.format(config['timerange']), caplog)
|
||||||
'Parameter --timerange detected: {} ...'.format(config['timerange']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
assert 'export' in config
|
assert 'export' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --export detected: {} ...'.format(config['export']), caplog)
|
||||||
'Parameter --export detected: {} ...'.format(config['export']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> None:
|
def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -444,16 +432,13 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
|
||||||
assert 'exchange' in config
|
assert 'exchange' in config
|
||||||
assert 'pair_whitelist' in config['exchange']
|
assert 'pair_whitelist' in config['exchange']
|
||||||
assert 'datadir' in config
|
assert 'datadir' in config
|
||||||
assert log_has(
|
assert log_has('Using data directory: {} ...'.format(config['datadir']), caplog)
|
||||||
'Using data directory: {} ...'.format(config['datadir']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
assert 'ticker_interval' in config
|
assert 'ticker_interval' in config
|
||||||
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
assert log_has('Parameter -i/--ticker-interval detected ... Using ticker_interval: 1m ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'strategy_list' in config
|
assert 'strategy_list' in config
|
||||||
assert log_has('Using strategy list of 2 Strategies', caplog.record_tuples)
|
assert log_has('Using strategy list of 2 Strategies', caplog)
|
||||||
|
|
||||||
assert 'position_stacking' not in config
|
assert 'position_stacking' not in config
|
||||||
|
|
||||||
|
@ -462,10 +447,7 @@ def test_setup_configuration_with_stratlist(mocker, default_conf, caplog) -> Non
|
||||||
assert 'timerange' not in config
|
assert 'timerange' not in config
|
||||||
|
|
||||||
assert 'export' in config
|
assert 'export' in config
|
||||||
assert log_has(
|
assert log_has('Parameter --export detected: {} ...'.format(config['export']), caplog)
|
||||||
'Parameter --export detected: {} ...'.format(config['export']),
|
|
||||||
caplog.record_tuples
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -484,11 +466,11 @@ def test_hyperopt_with_arguments(mocker, default_conf, caplog) -> None:
|
||||||
assert 'epochs' in config
|
assert 'epochs' in config
|
||||||
assert int(config['epochs']) == 10
|
assert int(config['epochs']) == 10
|
||||||
assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 10 epochs ...',
|
assert log_has('Parameter --epochs detected ... Will run Hyperopt with for 10 epochs ...',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
assert 'spaces' in config
|
assert 'spaces' in config
|
||||||
assert config['spaces'] == ['all']
|
assert config['spaces'] == ['all']
|
||||||
assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog.record_tuples)
|
assert log_has('Parameter -s/--spaces detected: [\'all\']', caplog)
|
||||||
assert "runmode" in config
|
assert "runmode" in config
|
||||||
assert config['runmode'] == RunMode.HYPEROPT
|
assert config['runmode'] == RunMode.HYPEROPT
|
||||||
|
|
||||||
|
@ -498,38 +480,35 @@ def test_check_exchange(default_conf, caplog) -> None:
|
||||||
default_conf.get('exchange').update({'name': 'BITTREX'})
|
default_conf.get('exchange').update({'name': 'BITTREX'})
|
||||||
assert check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test an officially supported by Freqtrade team exchange
|
# Test an officially supported by Freqtrade team exchange
|
||||||
default_conf.get('exchange').update({'name': 'binance'})
|
default_conf.get('exchange').update({'name': 'binance'})
|
||||||
assert check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
assert log_has_re(r"Exchange .* is officially supported by the Freqtrade development team\.",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test an available exchange, supported by ccxt
|
# Test an available exchange, supported by ccxt
|
||||||
default_conf.get('exchange').update({'name': 'kraken'})
|
default_conf.get('exchange').update({'name': 'kraken'})
|
||||||
assert check_exchange(default_conf)
|
assert check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
||||||
r"by the Freqtrade development team\. .*",
|
r"by the Freqtrade development team\. .*", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test a 'bad' exchange, which known to have serious problems
|
# Test a 'bad' exchange, which known to have serious problems
|
||||||
default_conf.get('exchange').update({'name': 'bitmex'})
|
default_conf.get('exchange').update({'name': 'bitmex'})
|
||||||
assert not check_exchange(default_conf)
|
assert not check_exchange(default_conf)
|
||||||
assert log_has_re(r"Exchange .* is known to not work with the bot yet\. "
|
assert log_has_re(r"Exchange .* is known to not work with the bot yet\. "
|
||||||
r"Use it only for development and testing purposes\.",
|
r"Use it only for development and testing purposes\.", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test a 'bad' exchange with check_for_bad=False
|
# Test a 'bad' exchange with check_for_bad=False
|
||||||
default_conf.get('exchange').update({'name': 'bitmex'})
|
default_conf.get('exchange').update({'name': 'bitmex'})
|
||||||
assert check_exchange(default_conf, False)
|
assert check_exchange(default_conf, False)
|
||||||
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
assert log_has_re(r"Exchange .* is supported by ccxt and .* not officially supported "
|
||||||
r"by the Freqtrade development team\. .*",
|
r"by the Freqtrade development team\. .*", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
|
||||||
# Test an invalid exchange
|
# Test an invalid exchange
|
||||||
|
@ -555,7 +534,7 @@ def test_cli_verbose_with_params(default_conf, mocker, caplog) -> None:
|
||||||
validated_conf = configuration.load_config()
|
validated_conf = configuration.load_config()
|
||||||
|
|
||||||
assert validated_conf.get('verbosity') == 3
|
assert validated_conf.get('verbosity') == 3
|
||||||
assert log_has('Verbosity set to 3', caplog.record_tuples)
|
assert log_has('Verbosity set to 3', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_set_loggers() -> None:
|
def test_set_loggers() -> None:
|
||||||
|
@ -621,7 +600,7 @@ def test_load_config_warn_forcebuy(default_conf, mocker, caplog) -> None:
|
||||||
validated_conf = configuration.load_config()
|
validated_conf = configuration.load_config()
|
||||||
|
|
||||||
assert validated_conf.get('forcebuy_enable')
|
assert validated_conf.get('forcebuy_enable')
|
||||||
assert log_has('`forcebuy` RPC message enabled.', caplog.record_tuples)
|
assert log_has('`forcebuy` RPC message enabled.', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_default_conf(default_conf) -> None:
|
def test_validate_default_conf(default_conf) -> None:
|
||||||
|
@ -634,7 +613,7 @@ def test_create_datadir(mocker, default_conf, caplog) -> None:
|
||||||
|
|
||||||
create_datadir(default_conf, '/foo/bar')
|
create_datadir(default_conf, '/foo/bar')
|
||||||
assert md.call_args[1]['parents'] is True
|
assert md.call_args[1]['parents'] is True
|
||||||
assert log_has('Created data directory: /foo/bar', caplog.record_tuples)
|
assert log_has('Created data directory: /foo/bar', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_validate_tsl(default_conf):
|
def test_validate_tsl(default_conf):
|
||||||
|
|
|
@ -63,7 +63,7 @@ def test_cleanup(mocker, default_conf, caplog) -> None:
|
||||||
mocker.patch('freqtrade.persistence.cleanup', mock_cleanup)
|
mocker.patch('freqtrade.persistence.cleanup', mock_cleanup)
|
||||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||||
freqtrade.cleanup()
|
freqtrade.cleanup()
|
||||||
assert log_has('Cleaning up modules ...', caplog.record_tuples)
|
assert log_has('Cleaning up modules ...', caplog)
|
||||||
assert mock_cleanup.call_count == 1
|
assert mock_cleanup.call_count == 1
|
||||||
|
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ def test_worker_running(mocker, default_conf, caplog) -> None:
|
||||||
|
|
||||||
state = worker._worker(old_state=None)
|
state = worker._worker(old_state=None)
|
||||||
assert state is State.RUNNING
|
assert state is State.RUNNING
|
||||||
assert log_has('Changing state to: RUNNING', caplog.record_tuples)
|
assert log_has('Changing state to: RUNNING', caplog)
|
||||||
assert mock_throttle.call_count == 1
|
assert mock_throttle.call_count == 1
|
||||||
# Check strategy is loaded, and received a dataprovider object
|
# Check strategy is loaded, and received a dataprovider object
|
||||||
assert worker.freqtrade.strategy
|
assert worker.freqtrade.strategy
|
||||||
|
@ -93,7 +93,7 @@ def test_worker_stopped(mocker, default_conf, caplog) -> None:
|
||||||
worker.state = State.STOPPED
|
worker.state = State.STOPPED
|
||||||
state = worker._worker(old_state=State.RUNNING)
|
state = worker._worker(old_state=State.RUNNING)
|
||||||
assert state is State.STOPPED
|
assert state is State.STOPPED
|
||||||
assert log_has('Changing state to: STOPPED', caplog.record_tuples)
|
assert log_has('Changing state to: STOPPED', caplog)
|
||||||
assert mock_throttle.call_count == 0
|
assert mock_throttle.call_count == 0
|
||||||
assert mock_sleep.call_count == 1
|
assert mock_sleep.call_count == 1
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ def test_throttle(mocker, default_conf, caplog) -> None:
|
||||||
|
|
||||||
assert result == 42
|
assert result == 42
|
||||||
assert end - start > 0.1
|
assert end - start > 0.1
|
||||||
assert log_has('Throttling throttled_func for 0.10 seconds', caplog.record_tuples)
|
assert log_has('Throttling throttled_func for 0.10 seconds', caplog)
|
||||||
|
|
||||||
result = worker._throttle(throttled_func, min_secs=-1)
|
result = worker._throttle(throttled_func, min_secs=-1)
|
||||||
assert result == 42
|
assert result == 42
|
||||||
|
@ -147,7 +147,7 @@ def test_order_dict_dry_run(default_conf, mocker, caplog) -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
assert log_has("Disabling stoploss_on_exchange during dry-run.", caplog.record_tuples)
|
assert log_has("Disabling stoploss_on_exchange during dry-run.", caplog)
|
||||||
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
@ -162,7 +162,7 @@ def test_order_dict_dry_run(default_conf, mocker, caplog) -> None:
|
||||||
}
|
}
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples)
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_order_dict_live(default_conf, mocker, caplog) -> None:
|
def test_order_dict_live(default_conf, mocker, caplog) -> None:
|
||||||
|
@ -182,7 +182,7 @@ def test_order_dict_live(default_conf, mocker, caplog) -> None:
|
||||||
}
|
}
|
||||||
|
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples)
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
assert freqtrade.strategy.order_types['stoploss_on_exchange']
|
assert freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
|
@ -197,7 +197,7 @@ def test_order_dict_live(default_conf, mocker, caplog) -> None:
|
||||||
}
|
}
|
||||||
freqtrade = FreqtradeBot(conf)
|
freqtrade = FreqtradeBot(conf)
|
||||||
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
assert not freqtrade.strategy.order_types['stoploss_on_exchange']
|
||||||
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog.record_tuples)
|
assert not log_has_re(".*stoploss_on_exchange .* dry-run", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None:
|
def test_get_trade_stake_amount(default_conf, ticker, mocker) -> None:
|
||||||
|
@ -332,7 +332,7 @@ def test_edge_overrides_stoploss(limit_buy_order, fee, markets, caplog, mocker,
|
||||||
|
|
||||||
# stoploss shoud be hit
|
# stoploss shoud be hit
|
||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
assert log_has('executed sell, reason: SellType.STOP_LOSS', caplog.record_tuples)
|
assert log_has('executed sell, reason: SellType.STOP_LOSS', caplog)
|
||||||
assert trade.sell_reason == SellType.STOP_LOSS.value
|
assert trade.sell_reason == SellType.STOP_LOSS.value
|
||||||
|
|
||||||
|
|
||||||
|
@ -652,8 +652,7 @@ def test_create_trade_no_pairs_let(default_conf, ticker, limit_buy_order, fee,
|
||||||
|
|
||||||
assert freqtrade.create_trade()
|
assert freqtrade.create_trade()
|
||||||
assert not freqtrade.create_trade()
|
assert not freqtrade.create_trade()
|
||||||
assert log_has("No currency pair in whitelist, but checking to sell open trades.",
|
assert log_has("No currency pair in whitelist, but checking to sell open trades.", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee,
|
def test_create_trade_no_pairs_in_whitelist(default_conf, ticker, limit_buy_order, fee,
|
||||||
|
@ -672,7 +671,7 @@ def test_create_trade_no_pairs_in_whitelist(default_conf, ticker, limit_buy_orde
|
||||||
patch_get_signal(freqtrade)
|
patch_get_signal(freqtrade)
|
||||||
|
|
||||||
assert not freqtrade.create_trade()
|
assert not freqtrade.create_trade()
|
||||||
assert log_has("Whitelist is empty.", caplog.record_tuples)
|
assert log_has("Whitelist is empty.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_create_trade_no_signal(default_conf, fee, mocker) -> None:
|
def test_create_trade_no_signal(default_conf, fee, mocker) -> None:
|
||||||
|
@ -727,8 +726,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order,
|
||||||
assert trade.amount == 90.99181073703367
|
assert trade.amount == 90.99181073703367
|
||||||
|
|
||||||
assert log_has(
|
assert log_has(
|
||||||
'Buy signal found: about create a new trade with stake_amount: 0.001 ...',
|
'Buy signal found: about create a new trade with stake_amount: 0.001 ...', caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1095,7 +1093,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
|
||||||
})
|
})
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hit)
|
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hit)
|
||||||
assert freqtrade.handle_stoploss_on_exchange(trade) is True
|
assert freqtrade.handle_stoploss_on_exchange(trade) is True
|
||||||
assert log_has('STOP_LOSS_LIMIT is hit for {}.'.format(trade), caplog.record_tuples)
|
assert log_has('STOP_LOSS_LIMIT is hit for {}.'.format(trade), caplog)
|
||||||
assert trade.stoploss_order_id is None
|
assert trade.stoploss_order_id is None
|
||||||
assert trade.is_open is False
|
assert trade.is_open is False
|
||||||
|
|
||||||
|
@ -1104,7 +1102,7 @@ def test_handle_stoploss_on_exchange(mocker, default_conf, fee, caplog,
|
||||||
side_effect=DependencyException()
|
side_effect=DependencyException()
|
||||||
)
|
)
|
||||||
freqtrade.handle_stoploss_on_exchange(trade)
|
freqtrade.handle_stoploss_on_exchange(trade)
|
||||||
assert log_has('Unable to place a stoploss order on exchange: ', caplog.record_tuples)
|
assert log_has('Unable to place a stoploss order on exchange: ', caplog)
|
||||||
|
|
||||||
# Fifth case: get_order returns InvalidOrder
|
# Fifth case: get_order returns InvalidOrder
|
||||||
# It should try to add stoploss order
|
# It should try to add stoploss order
|
||||||
|
@ -1266,8 +1264,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c
|
||||||
mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException())
|
mocker.patch('freqtrade.exchange.Exchange.cancel_order', side_effect=InvalidOrderException())
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hanging)
|
mocker.patch('freqtrade.exchange.Exchange.get_order', stoploss_order_hanging)
|
||||||
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
|
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
|
||||||
assert log_has_re(r"Could not cancel stoploss order abcd for pair ETH/BTC.*",
|
assert log_has_re(r"Could not cancel stoploss order abcd for pair ETH/BTC.*", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
# Still try to create order
|
# Still try to create order
|
||||||
assert stoploss_limit.call_count == 1
|
assert stoploss_limit.call_count == 1
|
||||||
|
@ -1278,8 +1275,7 @@ def test_handle_stoploss_on_exchange_trailing_error(mocker, default_conf, fee, c
|
||||||
mocker.patch("freqtrade.exchange.Exchange.stoploss_limit", side_effect=DependencyException())
|
mocker.patch("freqtrade.exchange.Exchange.stoploss_limit", side_effect=DependencyException())
|
||||||
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
|
freqtrade.handle_trailing_stoploss_on_exchange(trade, stoploss_order_hanging)
|
||||||
assert cancel_mock.call_count == 1
|
assert cancel_mock.call_count == 1
|
||||||
assert log_has_re(r"Could create trailing stoploss order for pair ETH/BTC\..*",
|
assert log_has_re(r"Could create trailing stoploss order for pair ETH/BTC\..*", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
def test_tsl_on_exchange_compatible_with_edge(mocker, edge_conf, fee, caplog,
|
||||||
|
@ -1410,7 +1406,7 @@ def test_process_maybe_execute_buy_exception(mocker, default_conf, caplog) -> No
|
||||||
MagicMock(side_effect=DependencyException)
|
MagicMock(side_effect=DependencyException)
|
||||||
)
|
)
|
||||||
freqtrade.process_maybe_execute_buy()
|
freqtrade.process_maybe_execute_buy()
|
||||||
log_has('Unable to create trade:', caplog.record_tuples)
|
assert log_has('Unable to create trade: ', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_process_maybe_execute_sell(mocker, default_conf, limit_buy_order, caplog) -> None:
|
def test_process_maybe_execute_sell(mocker, default_conf, limit_buy_order, caplog) -> None:
|
||||||
|
@ -1428,8 +1424,7 @@ def test_process_maybe_execute_sell(mocker, default_conf, limit_buy_order, caplo
|
||||||
assert not freqtrade.process_maybe_execute_sell(trade)
|
assert not freqtrade.process_maybe_execute_sell(trade)
|
||||||
# Test amount not modified by fee-logic
|
# Test amount not modified by fee-logic
|
||||||
assert not log_has(
|
assert not log_has(
|
||||||
'Applying fee to amount for Trade {} from 90.99181073 to 90.81'.format(trade),
|
'Applying fee to amount for Trade {} from 90.99181073 to 90.81'.format(trade), caplog
|
||||||
caplog.record_tuples
|
|
||||||
)
|
)
|
||||||
|
|
||||||
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81)
|
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount', return_value=90.81)
|
||||||
|
@ -1452,7 +1447,7 @@ def test_process_maybe_execute_sell_exception(mocker, default_conf,
|
||||||
side_effect=DependencyException()
|
side_effect=DependencyException()
|
||||||
)
|
)
|
||||||
freqtrade.process_maybe_execute_sell(trade)
|
freqtrade.process_maybe_execute_sell(trade)
|
||||||
assert log_has('Unable to sell trade: ', caplog.record_tuples)
|
assert log_has('Unable to sell trade: ', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> None:
|
def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> None:
|
||||||
|
@ -1471,7 +1466,7 @@ def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> No
|
||||||
trade.open_fee = 0.001
|
trade.open_fee = 0.001
|
||||||
freqtrade.update_trade_state(trade)
|
freqtrade.update_trade_state(trade)
|
||||||
# Test amount not modified by fee-logic
|
# Test amount not modified by fee-logic
|
||||||
assert not log_has_re(r'Applying fee to .*', caplog.record_tuples)
|
assert not log_has_re(r'Applying fee to .*', caplog)
|
||||||
assert trade.open_order_id is None
|
assert trade.open_order_id is None
|
||||||
assert trade.amount == limit_buy_order['amount']
|
assert trade.amount == limit_buy_order['amount']
|
||||||
|
|
||||||
|
@ -1488,7 +1483,7 @@ def test_update_trade_state(mocker, default_conf, limit_buy_order, caplog) -> No
|
||||||
# Assert we call handle_trade() if trade is feasible for execution
|
# Assert we call handle_trade() if trade is feasible for execution
|
||||||
freqtrade.update_trade_state(trade)
|
freqtrade.update_trade_state(trade)
|
||||||
|
|
||||||
assert log_has_re('Found open order for.*', caplog.record_tuples)
|
assert log_has_re('Found open order for.*', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_update_trade_state_withorderdict(default_conf, trades_for_order, limit_buy_order, mocker):
|
def test_update_trade_state_withorderdict(default_conf, trades_for_order, limit_buy_order, mocker):
|
||||||
|
@ -1527,7 +1522,7 @@ def test_update_trade_state_exception(mocker, default_conf,
|
||||||
side_effect=OperationalException()
|
side_effect=OperationalException()
|
||||||
)
|
)
|
||||||
freqtrade.update_trade_state(trade)
|
freqtrade.update_trade_state(trade)
|
||||||
assert log_has('Could not update trade amount: ', caplog.record_tuples)
|
assert log_has('Could not update trade amount: ', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None:
|
def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -1543,7 +1538,7 @@ def test_update_trade_state_orderexception(mocker, default_conf, caplog) -> None
|
||||||
grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock())
|
grm_mock = mocker.patch("freqtrade.freqtradebot.FreqtradeBot.get_real_amount", MagicMock())
|
||||||
freqtrade.update_trade_state(trade)
|
freqtrade.update_trade_state(trade)
|
||||||
assert grm_mock.call_count == 0
|
assert grm_mock.call_count == 0
|
||||||
assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog.record_tuples)
|
assert log_has(f'Unable to fetch order {trade.open_order_id}: ', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker):
|
def test_update_trade_state_sell(default_conf, trades_for_order, limit_sell_order, mocker):
|
||||||
|
@ -1702,7 +1697,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
|
||||||
# if ROI is reached we must sell
|
# if ROI is reached we must sell
|
||||||
patch_get_signal(freqtrade, value=(False, True))
|
patch_get_signal(freqtrade, value=(False, True))
|
||||||
assert freqtrade.handle_trade(trade)
|
assert freqtrade.handle_trade(trade)
|
||||||
assert log_has('Required profit reached. Selling..', caplog.record_tuples)
|
assert log_has('Required profit reached. Selling..', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_handle_trade_experimental(
|
def test_handle_trade_experimental(
|
||||||
|
@ -1732,7 +1727,7 @@ def test_handle_trade_experimental(
|
||||||
|
|
||||||
patch_get_signal(freqtrade, value=(False, True))
|
patch_get_signal(freqtrade, value=(False, True))
|
||||||
assert freqtrade.handle_trade(trade)
|
assert freqtrade.handle_trade(trade)
|
||||||
assert log_has('Sell signal received. Selling..', caplog.record_tuples)
|
assert log_has('Sell signal received. Selling..', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order,
|
def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order,
|
||||||
|
@ -1838,7 +1833,7 @@ def test_check_handle_cancelled_buy(default_conf, ticker, limit_buy_order_old,
|
||||||
trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all()
|
trades = Trade.query.filter(Trade.open_order_id.is_(trade_buy.open_order_id)).all()
|
||||||
nb_trades = len(trades)
|
nb_trades = len(trades)
|
||||||
assert nb_trades == 0
|
assert nb_trades == 0
|
||||||
assert log_has_re("Buy order canceled on Exchange for Trade.*", caplog.record_tuples)
|
assert log_has_re("Buy order canceled on Exchange for Trade.*", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_order_old,
|
def test_check_handle_timedout_buy_exception(default_conf, ticker, limit_buy_order_old,
|
||||||
|
@ -1951,7 +1946,7 @@ def test_check_handle_cancelled_sell(default_conf, ticker, limit_sell_order_old,
|
||||||
assert cancel_order_mock.call_count == 0
|
assert cancel_order_mock.call_count == 0
|
||||||
assert rpc_mock.call_count == 1
|
assert rpc_mock.call_count == 1
|
||||||
assert trade_sell.is_open is True
|
assert trade_sell.is_open is True
|
||||||
assert log_has_re("Sell order canceled on exchange for Trade.*", caplog.record_tuples)
|
assert log_has_re("Sell order canceled on exchange for Trade.*", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old_partial,
|
def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old_partial,
|
||||||
|
@ -2029,7 +2024,7 @@ def test_check_handle_timedout_exception(default_conf, ticker, mocker, caplog) -
|
||||||
freqtrade.check_handle_timedout()
|
freqtrade.check_handle_timedout()
|
||||||
assert log_has_re(r'Cannot query order for Trade\(id=1, pair=ETH/BTC, amount=90.99181073, '
|
assert log_has_re(r'Cannot query order for Trade\(id=1, pair=ETH/BTC, amount=90.99181073, '
|
||||||
r'open_rate=0.00001099, open_since=10 hours ago\) due to Traceback \(most '
|
r'open_rate=0.00001099, open_since=10 hours ago\) due to Traceback \(most '
|
||||||
r'recent call last\):\n.*', caplog.record_tuples)
|
r'recent call last\):\n.*', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_handle_timedout_limit_buy(mocker, default_conf) -> None:
|
def test_handle_timedout_limit_buy(mocker, default_conf) -> None:
|
||||||
|
@ -2253,7 +2248,7 @@ def test_execute_sell_sloe_cancel_exception(mocker, default_conf, ticker, fee,
|
||||||
freqtrade.execute_sell(trade=trade, limit=1234,
|
freqtrade.execute_sell(trade=trade, limit=1234,
|
||||||
sell_reason=SellType.STOP_LOSS)
|
sell_reason=SellType.STOP_LOSS)
|
||||||
assert sellmock.call_count == 1
|
assert sellmock.call_count == 1
|
||||||
assert log_has('Could not cancel stoploss order abcd', caplog.record_tuples)
|
assert log_has('Could not cancel stoploss order abcd', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_execute_sell_with_stoploss_on_exchange(default_conf,
|
def test_execute_sell_with_stoploss_on_exchange(default_conf,
|
||||||
|
@ -2679,7 +2674,7 @@ def test_trailing_stop_loss(default_conf, limit_buy_order, fee, markets, caplog,
|
||||||
assert freqtrade.handle_trade(trade) is True
|
assert freqtrade.handle_trade(trade) is True
|
||||||
assert log_has(
|
assert log_has(
|
||||||
f'HIT STOP: current price at 0.000012, stop loss is 0.000015, '
|
f'HIT STOP: current price at 0.000012, stop loss is 0.000015, '
|
||||||
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog.record_tuples)
|
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog)
|
||||||
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
||||||
|
|
||||||
|
|
||||||
|
@ -2721,9 +2716,8 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
|
||||||
}))
|
}))
|
||||||
# stop-loss not reached, adjusted stoploss
|
# stop-loss not reached, adjusted stoploss
|
||||||
assert freqtrade.handle_trade(trade) is False
|
assert freqtrade.handle_trade(trade) is False
|
||||||
assert log_has(f'using positive stop loss: 0.01 offset: 0 profit: 0.2666%',
|
assert log_has(f'using positive stop loss: 0.01 offset: 0 profit: 0.2666%', caplog)
|
||||||
caplog.record_tuples)
|
assert log_has(f'adjusted stop loss', caplog)
|
||||||
assert log_has(f'adjusted stop loss', caplog.record_tuples)
|
|
||||||
assert trade.stop_loss == 0.0000138501
|
assert trade.stop_loss == 0.0000138501
|
||||||
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
|
||||||
|
@ -2737,7 +2731,7 @@ def test_trailing_stop_loss_positive(default_conf, limit_buy_order, fee, markets
|
||||||
assert log_has(
|
assert log_has(
|
||||||
f'HIT STOP: current price at {buy_price + 0.000002:.6f}, '
|
f'HIT STOP: current price at {buy_price + 0.000002:.6f}, '
|
||||||
f'stop loss is {trade.stop_loss:.6f}, '
|
f'stop loss is {trade.stop_loss:.6f}, '
|
||||||
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog.record_tuples)
|
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
||||||
|
@ -2780,9 +2774,8 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
||||||
}))
|
}))
|
||||||
# stop-loss not reached, adjusted stoploss
|
# stop-loss not reached, adjusted stoploss
|
||||||
assert freqtrade.handle_trade(trade) is False
|
assert freqtrade.handle_trade(trade) is False
|
||||||
assert log_has(f'using positive stop loss: 0.01 offset: 0.011 profit: 0.2666%',
|
assert log_has(f'using positive stop loss: 0.01 offset: 0.011 profit: 0.2666%', caplog)
|
||||||
caplog.record_tuples)
|
assert log_has(f'adjusted stop loss', caplog)
|
||||||
assert log_has(f'adjusted stop loss', caplog.record_tuples)
|
|
||||||
assert trade.stop_loss == 0.0000138501
|
assert trade.stop_loss == 0.0000138501
|
||||||
|
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
|
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
|
||||||
|
@ -2796,7 +2789,7 @@ def test_trailing_stop_loss_offset(default_conf, limit_buy_order, fee,
|
||||||
assert log_has(
|
assert log_has(
|
||||||
f'HIT STOP: current price at {buy_price + 0.000002:.6f}, '
|
f'HIT STOP: current price at {buy_price + 0.000002:.6f}, '
|
||||||
f'stop loss is {trade.stop_loss:.6f}, '
|
f'stop loss is {trade.stop_loss:.6f}, '
|
||||||
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog.record_tuples)
|
f'initial stop loss was at 0.000010, trade opened at 0.000011', caplog)
|
||||||
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
assert trade.sell_reason == SellType.TRAILING_STOP_LOSS.value
|
||||||
|
|
||||||
|
|
||||||
|
@ -2847,7 +2840,7 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
|
||||||
# stop-loss should not be adjusted as offset is not reached yet
|
# stop-loss should not be adjusted as offset is not reached yet
|
||||||
assert freqtrade.handle_trade(trade) is False
|
assert freqtrade.handle_trade(trade) is False
|
||||||
|
|
||||||
assert not log_has(f'adjusted stop loss', caplog.record_tuples)
|
assert not log_has(f'adjusted stop loss', caplog)
|
||||||
assert trade.stop_loss == 0.0000098910
|
assert trade.stop_loss == 0.0000098910
|
||||||
|
|
||||||
# price rises above the offset (rises 12% when the offset is 5.5%)
|
# price rises above the offset (rises 12% when the offset is 5.5%)
|
||||||
|
@ -2859,9 +2852,8 @@ def test_tsl_only_offset_reached(default_conf, limit_buy_order, fee,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
assert freqtrade.handle_trade(trade) is False
|
assert freqtrade.handle_trade(trade) is False
|
||||||
assert log_has(f'using positive stop loss: 0.05 offset: 0.055 profit: 0.1218%',
|
assert log_has(f'using positive stop loss: 0.05 offset: 0.055 profit: 0.1218%', caplog)
|
||||||
caplog.record_tuples)
|
assert log_has(f'adjusted stop loss', caplog)
|
||||||
assert log_has(f'adjusted stop loss', caplog.record_tuples)
|
|
||||||
assert trade.stop_loss == 0.0000117705
|
assert trade.stop_loss == 0.0000117705
|
||||||
|
|
||||||
|
|
||||||
|
@ -2920,7 +2912,7 @@ def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, ca
|
||||||
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001)
|
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001)
|
||||||
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
||||||
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades',
|
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker):
|
def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker):
|
||||||
|
@ -2943,7 +2935,7 @@ def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker):
|
||||||
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount
|
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount
|
||||||
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
||||||
'open_rate=0.24544100, open_since=closed) failed: myTrade-Dict empty found',
|
'open_rate=0.24544100, open_since=closed) failed: myTrade-Dict empty found',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_real_amount_stake(default_conf, trades_for_order, buy_order_fee, mocker):
|
def test_get_real_amount_stake(default_conf, trades_for_order, buy_order_fee, mocker):
|
||||||
|
@ -3032,7 +3024,7 @@ def test_get_real_amount_multi(default_conf, trades_for_order2, buy_order_fee, c
|
||||||
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001)
|
assert freqtrade.get_real_amount(trade, buy_order_fee) == amount - (amount * 0.001)
|
||||||
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
||||||
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades',
|
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.992) from Trades',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee, caplog, mocker):
|
def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee, caplog, mocker):
|
||||||
|
@ -3058,7 +3050,7 @@ def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee
|
||||||
assert freqtrade.get_real_amount(trade, limit_buy_order) == amount - 0.004
|
assert freqtrade.get_real_amount(trade, limit_buy_order) == amount - 0.004
|
||||||
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
assert log_has('Applying fee on amount for Trade(id=None, pair=LTC/ETH, amount=8.00000000, '
|
||||||
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.996) from Order',
|
'open_rate=0.24544100, open_since=closed) (from 8.0 to 7.996) from Order',
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order_fee, mocker):
|
def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order_fee, mocker):
|
||||||
|
|
|
@ -60,8 +60,8 @@ def test_main_fatal_exception(mocker, default_conf, caplog) -> None:
|
||||||
# Test Main + the KeyboardInterrupt exception
|
# Test Main + the KeyboardInterrupt exception
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
main(args)
|
main(args)
|
||||||
assert log_has('Using config: config.json.example ...', caplog.record_tuples)
|
assert log_has('Using config: config.json.example ...', caplog)
|
||||||
assert log_has('Fatal exception!', caplog.record_tuples)
|
assert log_has('Fatal exception!', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
|
def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -77,8 +77,8 @@ def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
|
||||||
# Test Main + the KeyboardInterrupt exception
|
# Test Main + the KeyboardInterrupt exception
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
main(args)
|
main(args)
|
||||||
assert log_has('Using config: config.json.example ...', caplog.record_tuples)
|
assert log_has('Using config: config.json.example ...', caplog)
|
||||||
assert log_has('SIGINT received, aborting ...', caplog.record_tuples)
|
assert log_has('SIGINT received, aborting ...', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_main_operational_exception(mocker, default_conf, caplog) -> None:
|
def test_main_operational_exception(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -97,8 +97,8 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None:
|
||||||
# Test Main + the KeyboardInterrupt exception
|
# Test Main + the KeyboardInterrupt exception
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
main(args)
|
main(args)
|
||||||
assert log_has('Using config: config.json.example ...', caplog.record_tuples)
|
assert log_has('Using config: config.json.example ...', caplog)
|
||||||
assert log_has('Oh snap!', caplog.record_tuples)
|
assert log_has('Oh snap!', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_main_reload_conf(mocker, default_conf, caplog) -> None:
|
def test_main_reload_conf(mocker, default_conf, caplog) -> None:
|
||||||
|
@ -121,7 +121,7 @@ def test_main_reload_conf(mocker, default_conf, caplog) -> None:
|
||||||
with pytest.raises(SystemExit):
|
with pytest.raises(SystemExit):
|
||||||
main(['-c', 'config.json.example'])
|
main(['-c', 'config.json.example'])
|
||||||
|
|
||||||
assert log_has('Using config: config.json.example ...', caplog.record_tuples)
|
assert log_has('Using config: config.json.example ...', caplog)
|
||||||
assert worker_mock.call_count == 4
|
assert worker_mock.call_count == 4
|
||||||
assert reconfigure_mock.call_count == 1
|
assert reconfigure_mock.call_count == 1
|
||||||
assert isinstance(worker.freqtrade, FreqtradeBot)
|
assert isinstance(worker.freqtrade, FreqtradeBot)
|
||||||
|
|
|
@ -151,7 +151,7 @@ def test_update_with_bittrex(limit_buy_order, limit_sell_order, fee, caplog):
|
||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
assert log_has("LIMIT_BUY has been fulfilled for Trade(id=2, "
|
assert log_has("LIMIT_BUY has been fulfilled for Trade(id=2, "
|
||||||
"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=closed).",
|
"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=closed).",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
trade.open_order_id = 'something'
|
trade.open_order_id = 'something'
|
||||||
|
@ -162,7 +162,7 @@ def test_update_with_bittrex(limit_buy_order, limit_sell_order, fee, caplog):
|
||||||
assert trade.close_date is not None
|
assert trade.close_date is not None
|
||||||
assert log_has("LIMIT_SELL has been fulfilled for Trade(id=2, "
|
assert log_has("LIMIT_SELL has been fulfilled for Trade(id=2, "
|
||||||
"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=closed).",
|
"pair=ETH/BTC, amount=90.99181073, open_rate=0.00001099, open_since=closed).",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
|
@ -184,7 +184,7 @@ def test_update_market_order(market_buy_order, market_sell_order, fee, caplog):
|
||||||
assert trade.close_date is None
|
assert trade.close_date is None
|
||||||
assert log_has("MARKET_BUY has been fulfilled for Trade(id=1, "
|
assert log_has("MARKET_BUY has been fulfilled for Trade(id=1, "
|
||||||
"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=closed).",
|
"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=closed).",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
caplog.clear()
|
caplog.clear()
|
||||||
trade.open_order_id = 'something'
|
trade.open_order_id = 'something'
|
||||||
|
@ -195,7 +195,7 @@ def test_update_market_order(market_buy_order, market_sell_order, fee, caplog):
|
||||||
assert trade.close_date is not None
|
assert trade.close_date is not None
|
||||||
assert log_has("MARKET_SELL has been fulfilled for Trade(id=1, "
|
assert log_has("MARKET_SELL has been fulfilled for Trade(id=1, "
|
||||||
"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=closed).",
|
"pair=ETH/BTC, amount=91.99181073, open_rate=0.00004099, open_since=closed).",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("init_persistence")
|
@pytest.mark.usefixtures("init_persistence")
|
||||||
|
@ -558,10 +558,9 @@ def test_migrate_new(mocker, default_conf, fee, caplog):
|
||||||
assert trade.ticker_interval is None
|
assert trade.ticker_interval is None
|
||||||
assert trade.stoploss_order_id is None
|
assert trade.stoploss_order_id is None
|
||||||
assert trade.stoploss_last_update is None
|
assert trade.stoploss_last_update is None
|
||||||
assert log_has("trying trades_bak1", caplog.record_tuples)
|
assert log_has("trying trades_bak1", caplog)
|
||||||
assert log_has("trying trades_bak2", caplog.record_tuples)
|
assert log_has("trying trades_bak2", caplog)
|
||||||
assert log_has("Running database migration - backup available as trades_bak2",
|
assert log_has("Running database migration - backup available as trades_bak2", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_migrate_mid_state(mocker, default_conf, fee, caplog):
|
def test_migrate_mid_state(mocker, default_conf, fee, caplog):
|
||||||
|
@ -621,9 +620,8 @@ def test_migrate_mid_state(mocker, default_conf, fee, caplog):
|
||||||
assert trade.max_rate == 0.0
|
assert trade.max_rate == 0.0
|
||||||
assert trade.stop_loss == 0.0
|
assert trade.stop_loss == 0.0
|
||||||
assert trade.initial_stop_loss == 0.0
|
assert trade.initial_stop_loss == 0.0
|
||||||
assert log_has("trying trades_bak0", caplog.record_tuples)
|
assert log_has("trying trades_bak0", caplog)
|
||||||
assert log_has("Running database migration - backup available as trades_bak0",
|
assert log_has("Running database migration - backup available as trades_bak0", caplog)
|
||||||
caplog.record_tuples)
|
|
||||||
|
|
||||||
|
|
||||||
def test_adjust_stop_loss(fee):
|
def test_adjust_stop_loss(fee):
|
||||||
|
|
|
@ -87,7 +87,7 @@ def test_add_indicators(default_conf, caplog):
|
||||||
# No indicator found
|
# No indicator found
|
||||||
fig3 = add_indicators(fig=deepcopy(fig), row=3, indicators=['no_indicator'], data=data)
|
fig3 = add_indicators(fig=deepcopy(fig), row=3, indicators=['no_indicator'], data=data)
|
||||||
assert fig == fig3
|
assert fig == fig3
|
||||||
assert log_has_re(r'Indicator "no_indicator" ignored\..*', caplog.record_tuples)
|
assert log_has_re(r'Indicator "no_indicator" ignored\..*', caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_plot_trades(caplog):
|
def test_plot_trades(caplog):
|
||||||
|
@ -95,7 +95,7 @@ def test_plot_trades(caplog):
|
||||||
# nothing happens when no trades are available
|
# nothing happens when no trades are available
|
||||||
fig = plot_trades(fig1, None)
|
fig = plot_trades(fig1, None)
|
||||||
assert fig == fig1
|
assert fig == fig1
|
||||||
assert log_has("No trades found.", caplog.record_tuples)
|
assert log_has("No trades found.", caplog)
|
||||||
pair = "ADA/BTC"
|
pair = "ADA/BTC"
|
||||||
filename = history.make_testdata_path(None) / "backtest-result_test.json"
|
filename = history.make_testdata_path(None) / "backtest-result_test.json"
|
||||||
trades = load_backtest_data(filename)
|
trades = load_backtest_data(filename)
|
||||||
|
@ -150,8 +150,8 @@ def test_generate_candlestick_graph_no_signals_no_trades(default_conf, mocker, c
|
||||||
assert row_mock.call_count == 2
|
assert row_mock.call_count == 2
|
||||||
assert trades_mock.call_count == 1
|
assert trades_mock.call_count == 1
|
||||||
|
|
||||||
assert log_has("No buy-signals found.", caplog.record_tuples)
|
assert log_has("No buy-signals found.", caplog)
|
||||||
assert log_has("No sell-signals found.", caplog.record_tuples)
|
assert log_has("No sell-signals found.", caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_generate_candlestick_graph_no_trades(default_conf, mocker):
|
def test_generate_candlestick_graph_no_trades(default_conf, mocker):
|
||||||
|
@ -216,7 +216,7 @@ def test_generate_plot_file(mocker, caplog):
|
||||||
assert (plot_mock.call_args_list[0][1]['filename']
|
assert (plot_mock.call_args_list[0][1]['filename']
|
||||||
== "user_data/plots/freqtrade-plot-UNITTEST_BTC-5m.html")
|
== "user_data/plots/freqtrade-plot-UNITTEST_BTC-5m.html")
|
||||||
assert log_has("Stored plot as user_data/plots/freqtrade-plot-UNITTEST_BTC-5m.html",
|
assert log_has("Stored plot as user_data/plots/freqtrade-plot-UNITTEST_BTC-5m.html",
|
||||||
caplog.record_tuples)
|
caplog)
|
||||||
|
|
||||||
|
|
||||||
def test_add_profit():
|
def test_add_profit():
|
||||||
|
|
Loading…
Reference in New Issue
Block a user