Merge with develop

This commit is contained in:
Anton
2018-06-23 16:50:27 +03:00
36 changed files with 1336 additions and 987 deletions

View File

@@ -13,6 +13,7 @@ from telegram import Chat, Message, Update
from freqtrade.analyze import Analyze
from freqtrade import constants
from freqtrade.exchange import Exchange
from freqtrade.freqtradebot import FreqtradeBot
logging.getLogger('').setLevel(logging.INFO)
@@ -26,6 +27,20 @@ def log_has(line, logs):
False)
def patch_exchange(mocker, api_mock=None) -> None:
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
if api_mock:
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
else:
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock())
def get_patched_exchange(mocker, config, api_mock=None) -> Exchange:
patch_exchange(mocker, api_mock)
exchange = Exchange(config)
return exchange
# Functions for recurrent object patching
def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
"""
@@ -39,7 +54,7 @@ def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
mocker.patch('freqtrade.freqtradebot.Analyze', MagicMock())
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
patch_exchange(mocker, None)
mocker.patch('freqtrade.freqtradebot.RPCManager._init', MagicMock())
mocker.patch('freqtrade.freqtradebot.RPCManager.send_msg', MagicMock())
mocker.patch('freqtrade.freqtradebot.Analyze.get_signal', MagicMock())

View File

@@ -3,33 +3,20 @@
import logging
from copy import deepcopy
from random import randint
from datetime import datetime
from unittest.mock import MagicMock, PropertyMock
import ccxt
import pytest
import freqtrade.exchange as exchange
from freqtrade import OperationalException, DependencyException, TemporaryError
from freqtrade.exchange import (init, validate_pairs, buy, sell, get_balance, get_balances,
get_ticker, get_ticker_history, cancel_order, get_name, get_fee,
get_id, get_pair_detail_url, get_amount_lots)
from freqtrade.tests.conftest import log_has
API_INIT = False
def maybe_init_api(conf, mocker, force=False):
global API_INIT
if force or not API_INIT:
mocker.patch('freqtrade.exchange.validate_pairs',
side_effect=lambda s: True)
init(config=conf)
API_INIT = True
from freqtrade.exchange import Exchange, API_RETRY_COUNT
from freqtrade.tests.conftest import log_has, get_patched_exchange
def test_init(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
maybe_init_api(default_conf, mocker, True)
get_patched_exchange(mocker, default_conf)
assert log_has('Instance is running with dry_run enabled', caplog.record_tuples)
@@ -39,7 +26,7 @@ def test_init_exception(default_conf):
with pytest.raises(
OperationalException,
match='Exchange {} is not supported'.format(default_conf['exchange']['name'])):
init(config=default_conf)
Exchange(default_conf)
def test_validate_pairs(default_conf, mocker):
@@ -50,18 +37,17 @@ def test_validate_pairs(default_conf, mocker):
id_mock = PropertyMock(return_value='test_exchange')
type(api_mock).id = id_mock
mocker.patch('freqtrade.exchange._API', api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
validate_pairs(default_conf['exchange']['pair_whitelist'])
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
Exchange(default_conf)
def test_validate_pairs_not_available(default_conf, mocker):
api_mock = MagicMock()
api_mock.load_markets = MagicMock(return_value={})
mocker.patch('freqtrade.exchange._API', api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
with pytest.raises(OperationalException, match=r'not available'):
validate_pairs(default_conf['exchange']['pair_whitelist'])
Exchange(default_conf)
def test_validate_pairs_not_compatible(default_conf, mocker):
@@ -71,25 +57,27 @@ def test_validate_pairs_not_compatible(default_conf, mocker):
})
conf = deepcopy(default_conf)
conf['stake_currency'] = 'ETH'
mocker.patch('freqtrade.exchange._API', api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', conf)
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
with pytest.raises(OperationalException, match=r'not compatible'):
validate_pairs(conf['exchange']['pair_whitelist'])
Exchange(conf)
def test_validate_pairs_exception(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
api_mock = MagicMock()
api_mock.name = 'Binance'
mocker.patch('freqtrade.exchange._API', api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value='Binance'))
api_mock.load_markets = MagicMock(return_value={})
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock)
with pytest.raises(OperationalException, match=r'Pair ETH/BTC is not available at Binance'):
validate_pairs(default_conf['exchange']['pair_whitelist'])
Exchange(default_conf)
api_mock.load_markets = MagicMock(side_effect=ccxt.BaseError())
validate_pairs(default_conf['exchange']['pair_whitelist'])
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
Exchange(default_conf)
assert log_has('Unable to validate pairs (assuming they are correct). Reason: ',
caplog.record_tuples)
@@ -99,22 +87,21 @@ def test_validate_pairs_stake_exception(default_conf, mocker, caplog):
conf = deepcopy(default_conf)
conf['stake_currency'] = 'ETH'
api_mock = MagicMock()
api_mock.name = 'binance'
mocker.patch('freqtrade.exchange._API', api_mock)
mocker.patch.dict('freqtrade.exchange._CONF', conf)
api_mock.name = MagicMock(return_value='binance')
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', api_mock)
with pytest.raises(
OperationalException,
match=r'Pair ETH/BTC not compatible with stake_currency: ETH'
):
validate_pairs(default_conf['exchange']['pair_whitelist'])
Exchange(conf)
def test_buy_dry_run(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
exchange = get_patched_exchange(mocker, default_conf)
order = buy(pair='ETH/BTC', rate=200, amount=1)
order = exchange.buy(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order
assert 'dry_run_buy_' in order['id']
@@ -128,12 +115,10 @@ def test_buy_prod(default_conf, mocker):
'foo': 'bar'
}
})
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
order = buy(pair='ETH/BTC', rate=200, amount=1)
order = exchange.buy(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order
assert 'info' in order
assert order['id'] == order_id
@@ -141,30 +126,30 @@ def test_buy_prod(default_conf, mocker):
# test exception handling
with pytest.raises(DependencyException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InsufficientFunds)
mocker.patch('freqtrade.exchange._API', api_mock)
buy(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(DependencyException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock)
buy(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(TemporaryError):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
buy(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.buy(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(OperationalException):
api_mock.create_limit_buy_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
buy(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.buy(pair='ETH/BTC', rate=200, amount=1)
def test_sell_dry_run(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
exchange = get_patched_exchange(mocker, default_conf)
order = sell(pair='ETH/BTC', rate=200, amount=1)
order = exchange.sell(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order
assert 'dry_run_sell_' in order['id']
@@ -178,12 +163,11 @@ def test_sell_prod(default_conf, mocker):
'foo': 'bar'
}
})
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
order = sell(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
order = exchange.sell(pair='ETH/BTC', rate=200, amount=1)
assert 'id' in order
assert 'info' in order
assert order['id'] == order_id
@@ -191,53 +175,52 @@ def test_sell_prod(default_conf, mocker):
# test exception handling
with pytest.raises(DependencyException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InsufficientFunds)
mocker.patch('freqtrade.exchange._API', api_mock)
sell(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(DependencyException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock)
sell(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(TemporaryError):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
sell(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.sell(pair='ETH/BTC', rate=200, amount=1)
with pytest.raises(OperationalException):
api_mock.create_limit_sell_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
sell(pair='ETH/BTC', rate=200, amount=1)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.sell(pair='ETH/BTC', rate=200, amount=1)
def test_get_balance_dry_run(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert get_balance(currency='BTC') == 999.9
exchange = get_patched_exchange(mocker, default_conf)
assert exchange.get_balance(currency='BTC') == 999.9
def test_get_balance_prod(default_conf, mocker):
api_mock = MagicMock()
api_mock.fetch_balance = MagicMock(return_value={'BTC': {'free': 123.4}})
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert get_balance(currency='BTC') == 123.4
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_balance(currency='BTC') == 123.4
with pytest.raises(OperationalException):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
get_balance(currency='BTC')
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_balance(currency='BTC')
def test_get_balances_dry_run(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert get_balances() == {}
exchange = get_patched_exchange(mocker, default_conf)
assert exchange.get_balances() == {}
def test_get_balances_prod(default_conf, mocker):
@@ -253,33 +236,73 @@ def test_get_balances_prod(default_conf, mocker):
'2ST': balance_item,
'3ST': balance_item
})
mocker.patch('freqtrade.exchange._API', api_mock)
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert len(get_balances()) == 3
assert get_balances()['1ST']['free'] == 10.0
assert get_balances()['1ST']['total'] == 10.0
assert get_balances()['1ST']['used'] == 0.0
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert len(exchange.get_balances()) == 3
assert exchange.get_balances()['1ST']['free'] == 10.0
assert exchange.get_balances()['1ST']['total'] == 10.0
assert exchange.get_balances()['1ST']['used'] == 0.0
with pytest.raises(TemporaryError):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
get_balances()
assert api_mock.fetch_balance.call_count == exchange.API_RETRY_COUNT + 1
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_balances()
assert api_mock.fetch_balance.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException):
api_mock.fetch_balance = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
get_balances()
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_balances()
assert api_mock.fetch_balance.call_count == 1
# This test is somewhat redundant with
# test_exchange_bittrex.py::test_exchange_bittrex_get_ticker
def test_get_tickers(default_conf, mocker):
api_mock = MagicMock()
tick = {'ETH/BTC': {
'symbol': 'ETH/BTC',
'bid': 0.5,
'ask': 1,
'last': 42,
}, 'BCH/BTC': {
'symbol': 'BCH/BTC',
'bid': 0.6,
'ask': 0.5,
'last': 41,
}
}
api_mock.fetch_tickers = MagicMock(return_value=tick)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker
tickers = exchange.get_tickers()
assert 'ETH/BTC' in tickers
assert 'BCH/BTC' in tickers
assert tickers['ETH/BTC']['bid'] == 0.5
assert tickers['ETH/BTC']['ask'] == 1
assert tickers['BCH/BTC']['bid'] == 0.6
assert tickers['BCH/BTC']['ask'] == 0.5
with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_tickers = MagicMock(side_effect=ccxt.NetworkError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_tickers()
with pytest.raises(OperationalException):
api_mock.fetch_tickers = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_tickers()
with pytest.raises(OperationalException):
api_mock.fetch_tickers = MagicMock(side_effect=ccxt.NotSupported)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_tickers()
api_mock.fetch_tickers = MagicMock(return_value={})
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_tickers()
def test_get_ticker(default_conf, mocker):
maybe_init_api(default_conf, mocker)
api_mock = MagicMock()
tick = {
'symbol': 'ETH/BTC',
@@ -288,10 +311,9 @@ def test_get_ticker(default_conf, mocker):
'last': 0.0001,
}
api_mock.fetch_ticker = MagicMock(return_value=tick)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker
ticker = get_ticker(pair='ETH/BTC')
ticker = exchange.get_ticker(pair='ETH/BTC')
assert ticker['bid'] == 0.00001098
assert ticker['ask'] == 0.00001099
@@ -304,38 +326,38 @@ def test_get_ticker(default_conf, mocker):
'last': 42,
}
api_mock.fetch_ticker = MagicMock(return_value=tick)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# if not caching the result we should get the same ticker
# if not fetching a new result we should get the cached ticker
ticker = get_ticker(pair='ETH/BTC')
ticker = exchange.get_ticker(pair='ETH/BTC')
assert api_mock.fetch_ticker.call_count == 1
assert ticker['bid'] == 0.5
assert ticker['ask'] == 1
assert 'ETH/BTC' in exchange._CACHED_TICKER
assert exchange._CACHED_TICKER['ETH/BTC']['bid'] == 0.5
assert exchange._CACHED_TICKER['ETH/BTC']['ask'] == 1
assert 'ETH/BTC' in exchange._cached_ticker
assert exchange._cached_ticker['ETH/BTC']['bid'] == 0.5
assert exchange._cached_ticker['ETH/BTC']['ask'] == 1
# Test caching
api_mock.fetch_ticker = MagicMock()
get_ticker(pair='ETH/BTC', refresh=False)
exchange.get_ticker(pair='ETH/BTC', refresh=False)
assert api_mock.fetch_ticker.call_count == 0
with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_ticker(pair='ETH/BTC', refresh=True)
with pytest.raises(OperationalException):
api_mock.fetch_ticker = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_ticker(pair='ETH/BTC', refresh=True)
api_mock.fetch_ticker = MagicMock(return_value={})
mocker.patch('freqtrade.exchange._API', api_mock)
get_ticker(pair='ETH/BTC', refresh=True)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_ticker(pair='ETH/BTC', refresh=True)
def make_fetch_ohlcv_mock(data):
@@ -361,10 +383,10 @@ def test_get_ticker_history(default_conf, mocker):
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# retrieve original ticker
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686200000
assert ticks[0][1] == 1
assert ticks[0][2] == 2
@@ -384,9 +406,9 @@ def test_get_ticker_history(default_conf, mocker):
]
]
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(new_tick))
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1511686210000
assert ticks[0][1] == 6
assert ticks[0][2] == 7
@@ -396,15 +418,15 @@ def test_get_ticker_history(default_conf, mocker):
with pytest.raises(TemporaryError): # test retrier
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# new symbol to get around cache
get_ticker_history('ABCD/BTC', default_conf['ticker_interval'])
exchange.get_ticker_history('ABCD/BTC', default_conf['ticker_interval'])
with pytest.raises(OperationalException):
api_mock.fetch_ohlcv = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# new symbol to get around cache
get_ticker_history('EFGH/BTC', default_conf['ticker_interval'])
exchange.get_ticker_history('EFGH/BTC', default_conf['ticker_interval'])
def test_get_ticker_history_sort(default_conf, mocker):
@@ -426,10 +448,11 @@ def test_get_ticker_history_sort(default_conf, mocker):
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# Test the ticker history sort
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1527830400000
assert ticks[0][1] == 0.07649
assert ticks[0][2] == 0.07651
@@ -460,10 +483,9 @@ def test_get_ticker_history_sort(default_conf, mocker):
]
type(api_mock).has = PropertyMock(return_value={'fetchOHLCV': True})
api_mock.fetch_ohlcv = MagicMock(side_effect=make_fetch_ohlcv_mock(tick))
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
# Test the ticker history sort
ticks = get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
ticks = exchange.get_ticker_history('ETH/BTC', default_conf['ticker_interval'])
assert ticks[0][0] == 1527827700000
assert ticks[0][1] == 0.07659999
assert ticks[0][2] == 0.0766
@@ -481,117 +503,194 @@ def test_get_ticker_history_sort(default_conf, mocker):
def test_cancel_order_dry_run(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
assert cancel_order(order_id='123', pair='TKN/BTC') is None
exchange = get_patched_exchange(mocker, default_conf)
assert exchange.cancel_order(order_id='123', pair='TKN/BTC') is None
# Ensure that if not dry_run, we should call API
def test_cancel_order(default_conf, mocker):
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
api_mock = MagicMock()
api_mock.cancel_order = MagicMock(return_value=123)
mocker.patch('freqtrade.exchange._API', api_mock)
assert cancel_order(order_id='_', pair='TKN/BTC') == 123
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.cancel_order(order_id='_', pair='TKN/BTC') == 123
with pytest.raises(TemporaryError):
api_mock.cancel_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == exchange.API_RETRY_COUNT + 1
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(DependencyException):
api_mock.cancel_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock)
cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == exchange.API_RETRY_COUNT + 1
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException):
api_mock.cancel_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
cancel_order(order_id='_', pair='TKN/BTC')
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.cancel_order(order_id='_', pair='TKN/BTC')
assert api_mock.cancel_order.call_count == 1
def test_get_order(default_conf, mocker):
default_conf['dry_run'] = True
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
order = MagicMock()
order.myid = 123
exchange._DRY_RUN_OPEN_ORDERS['X'] = order
exchange = get_patched_exchange(mocker, default_conf)
exchange._dry_run_open_orders['X'] = order
print(exchange.get_order('X', 'TKN/BTC'))
assert exchange.get_order('X', 'TKN/BTC').myid == 123
default_conf['dry_run'] = False
mocker.patch.dict('freqtrade.exchange._CONF', default_conf)
api_mock = MagicMock()
api_mock.fetch_order = MagicMock(return_value=456)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_order('X', 'TKN/BTC') == 456
with pytest.raises(TemporaryError):
api_mock.fetch_order = MagicMock(side_effect=ccxt.NetworkError)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == exchange.API_RETRY_COUNT + 1
assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(DependencyException):
api_mock.fetch_order = MagicMock(side_effect=ccxt.InvalidOrder)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == exchange.API_RETRY_COUNT + 1
assert api_mock.fetch_order.call_count == API_RETRY_COUNT + 1
with pytest.raises(OperationalException):
api_mock.fetch_order = MagicMock(side_effect=ccxt.BaseError)
mocker.patch('freqtrade.exchange._API', api_mock)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_order(order_id='_', pair='TKN/BTC')
assert api_mock.fetch_order.call_count == 1
def test_get_name(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs',
def test_name(default_conf, mocker):
mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance'
init(default_conf)
exchange = Exchange(default_conf)
assert get_name() == 'Binance'
assert exchange.name == 'Binance'
def test_get_id(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs',
def test_id(default_conf, mocker):
mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance'
init(default_conf)
assert get_id() == 'binance'
exchange = Exchange(default_conf)
assert exchange.id == 'binance'
def test_get_pair_detail_url(default_conf, mocker):
mocker.patch('freqtrade.exchange.validate_pairs',
def test_get_pair_detail_url(default_conf, mocker, caplog):
mocker.patch('freqtrade.exchange.Exchange.validate_pairs',
side_effect=lambda s: True)
default_conf['exchange']['name'] = 'binance'
init(default_conf)
exchange = Exchange(default_conf)
url = get_pair_detail_url('TKN/ETH')
url = exchange.get_pair_detail_url('TKN/ETH')
assert 'TKN' in url
assert 'ETH' in url
url = get_pair_detail_url('LOOONG/BTC')
url = exchange.get_pair_detail_url('LOOONG/BTC')
assert 'LOOONG' in url
assert 'BTC' in url
default_conf['exchange']['name'] = 'bittrex'
init(default_conf)
exchange = Exchange(default_conf)
url = get_pair_detail_url('TKN/ETH')
url = exchange.get_pair_detail_url('TKN/ETH')
assert 'TKN' in url
assert 'ETH' in url
url = get_pair_detail_url('LOOONG/BTC')
url = exchange.get_pair_detail_url('LOOONG/BTC')
assert 'LOOONG' in url
assert 'BTC' in url
default_conf['exchange']['name'] = 'poloniex'
exchange = Exchange(default_conf)
url = exchange.get_pair_detail_url('LOOONG/BTC')
assert '' == url
assert log_has('Could not get exchange url for Poloniex', caplog.record_tuples)
def test_get_trades_for_order(default_conf, mocker):
order_id = 'ABCD-ABCD'
since = datetime(2018, 5, 5)
default_conf["dry_run"] = False
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
api_mock = MagicMock()
api_mock.fetch_my_trades = MagicMock(return_value=[{'id': 'TTR67E-3PFBD-76IISV',
'order': 'ABCD-ABCD',
'info': {'pair': 'XLTCZBTC',
'time': 1519860024.4388,
'type': 'buy',
'ordertype': 'limit',
'price': '20.00000',
'cost': '38.62000',
'fee': '0.06179',
'vol': '5',
'id': 'ABCD-ABCD'},
'timestamp': 1519860024438,
'datetime': '2018-02-28T23:20:24.438Z',
'symbol': 'LTC/BTC',
'type': 'limit',
'side': 'buy',
'price': 165.0,
'amount': 0.2340606,
'fee': {'cost': 0.06179, 'currency': 'BTC'}
}])
exchange = get_patched_exchange(mocker, default_conf, api_mock)
orders = exchange.get_trades_for_order(order_id, 'LTC/BTC', since)
assert len(orders) == 1
assert orders[0]['price'] == 165
# test Exceptions
with pytest.raises(OperationalException):
api_mock = MagicMock()
api_mock.fetch_my_trades = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_trades_for_order(order_id, 'LTC/BTC', since)
with pytest.raises(TemporaryError):
api_mock = MagicMock()
api_mock.fetch_my_trades = MagicMock(side_effect=ccxt.NetworkError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_trades_for_order(order_id, 'LTC/BTC', since)
assert api_mock.fetch_my_trades.call_count == API_RETRY_COUNT + 1
def test_get_markets(default_conf, mocker, markets):
api_mock = MagicMock()
api_mock.fetch_markets = markets
exchange = get_patched_exchange(mocker, default_conf, api_mock)
ret = exchange.get_markets()
assert isinstance(ret, list)
assert len(ret) == 6
assert ret[0]["id"] == "ethbtc"
assert ret[0]["symbol"] == "ETH/BTC"
# test Exceptions
with pytest.raises(OperationalException):
api_mock = MagicMock()
api_mock.fetch_markets = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_markets()
with pytest.raises(TemporaryError):
api_mock = MagicMock()
api_mock.fetch_markets = MagicMock(side_effect=ccxt.NetworkError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_markets()
assert api_mock.fetch_markets.call_count == API_RETRY_COUNT + 1
def test_get_fee(default_conf, mocker):
api_mock = MagicMock()
@@ -601,12 +700,32 @@ def test_get_fee(default_conf, mocker):
'rate': 0.025,
'cost': 0.05
})
mocker.patch('freqtrade.exchange._API', api_mock)
assert get_fee() == 0.025
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_fee() == 0.025
# test Exceptions
with pytest.raises(OperationalException):
api_mock = MagicMock()
api_mock.calculate_fee = MagicMock(side_effect=ccxt.BaseError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_fee()
with pytest.raises(TemporaryError):
api_mock = MagicMock()
api_mock.calculate_fee = MagicMock(side_effect=ccxt.NetworkError)
exchange = get_patched_exchange(mocker, default_conf, api_mock)
exchange.get_fee()
assert api_mock.calculate_fee.call_count == API_RETRY_COUNT + 1
def test_get_amount_lots(default_conf, mocker):
api_mock = MagicMock()
api_mock.amount_to_lots = MagicMock(return_value=1.0)
mocker.patch('freqtrade.exchange._API', api_mock)
assert get_amount_lots('LTC/BTC', 1.54) == 1
api_mock.markets = None
marketmock = MagicMock()
api_mock.load_markets = marketmock
exchange = get_patched_exchange(mocker, default_conf, api_mock)
assert exchange.get_amount_lots('LTC/BTC', 1.54) == 1
assert marketmock.call_count == 1

View File

@@ -16,7 +16,7 @@ from freqtrade import optimize, constants, DependencyException
from freqtrade.analyze import Analyze
from freqtrade.arguments import Arguments, TimeRange
from freqtrade.optimize.backtesting import Backtesting, start, setup_configuration
from freqtrade.tests.conftest import log_has
from freqtrade.tests.conftest import log_has, patch_exchange
def get_args(args) -> List[str]:
@@ -84,7 +84,7 @@ def load_data_test(what):
def simple_backtest(config, contour, num_results, mocker) -> None:
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
backtesting = Backtesting(config)
data = load_data_test(contour)
@@ -102,7 +102,8 @@ def simple_backtest(config, contour, num_results, mocker) -> None:
assert len(results) == num_results
def mocked_load_data(datadir, pairs=[], ticker_interval='0m', refresh_pairs=False, timerange=None):
def mocked_load_data(datadir, pairs=[], ticker_interval='0m', refresh_pairs=False,
timerange=None, exchange=None):
tickerdata = optimize.load_tickerdata_file(datadir, 'UNITTEST/BTC', '1m', timerange=timerange)
pairdata = {'UNITTEST/BTC': tickerdata}
return pairdata
@@ -119,7 +120,7 @@ def _load_pair_as_ticks(pair, tickfreq):
def _make_backtest_conf(mocker, conf=None, pair='UNITTEST/BTC', record=None):
data = optimize.load_data(None, ticker_interval='8m', pairs=[pair])
data = trim_dictlist(data, -201)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
backtesting = Backtesting(conf)
return {
'stake_amount': conf['stake_amount'],
@@ -295,8 +296,8 @@ def test_start(mocker, fee, default_conf, caplog) -> None:
Test start() function
"""
start_mock = MagicMock()
mocker.patch('freqtrade.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
patch_exchange(mocker)
mocker.patch('freqtrade.optimize.backtesting.Backtesting.start', start_mock)
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
read_data=json.dumps(default_conf)
@@ -319,7 +320,8 @@ def test_backtesting_init(mocker, default_conf) -> None:
"""
Test Backtesting._init() method
"""
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
backtesting = Backtesting(default_conf)
assert backtesting.config == default_conf
assert isinstance(backtesting.analyze, Analyze)
@@ -327,13 +329,15 @@ def test_backtesting_init(mocker, default_conf) -> None:
assert callable(backtesting.tickerdata_to_dataframe)
assert callable(backtesting.populate_buy_trend)
assert callable(backtesting.populate_sell_trend)
get_fee.assert_called()
assert backtesting.fee == 0.5
def test_tickerdata_to_dataframe(default_conf, mocker) -> None:
"""
Test Backtesting.tickerdata_to_dataframe() method
"""
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
timerange = TimeRange(None, 'line', 0, -100)
tick = optimize.load_tickerdata_file(None, 'UNITTEST/BTC', '1m', timerange=timerange)
tickerlist = {'UNITTEST/BTC': tick}
@@ -352,7 +356,7 @@ def test_get_timeframe(default_conf, mocker) -> None:
"""
Test Backtesting.get_timeframe() method
"""
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
data = backtesting.tickerdata_to_dataframe(
@@ -371,7 +375,7 @@ def test_generate_text_table(default_conf, mocker):
"""
Test Backtesting.generate_text_table() method
"""
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
results = pd.DataFrame(
@@ -408,8 +412,8 @@ def test_backtesting_start(default_conf, mocker, caplog) -> None:
mocker.patch('freqtrade.freqtradebot.Analyze', MagicMock())
mocker.patch('freqtrade.optimize.load_data', mocked_load_data)
mocker.patch('freqtrade.exchange.get_ticker_history')
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history')
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.optimize.backtesting.Backtesting',
backtest=MagicMock(),
@@ -449,8 +453,8 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog) -> None:
mocker.patch('freqtrade.freqtradebot.Analyze', MagicMock())
mocker.patch('freqtrade.optimize.load_data', MagicMock(return_value={}))
mocker.patch('freqtrade.exchange.get_ticker_history')
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history')
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.optimize.backtesting.Backtesting',
backtest=MagicMock(),
@@ -477,8 +481,8 @@ def test_backtest(default_conf, fee, mocker) -> None:
"""
Test Backtesting.backtest() method
"""
mocker.patch('freqtrade.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
data = optimize.load_data(None, ticker_interval='5m', pairs=['UNITTEST/BTC'])
@@ -499,8 +503,8 @@ def test_backtest_1min_ticker_interval(default_conf, fee, mocker) -> None:
"""
Test Backtesting.backtest() method with 1 min ticker
"""
mocker.patch('freqtrade.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
# Run a backtesting for an exiting 5min ticker_interval
@@ -522,7 +526,7 @@ def test_processed(default_conf, mocker) -> None:
"""
Test Backtesting.backtest() method with offline data
"""
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
patch_exchange(mocker)
backtesting = Backtesting(default_conf)
dict_of_tickerrows = load_data_test('raise')
@@ -536,7 +540,7 @@ def test_processed(default_conf, mocker) -> None:
def test_backtest_pricecontours(default_conf, fee, mocker) -> None:
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
tests = [['raise', 18], ['lower', 0], ['sine', 16]]
for [contour, numres] in tests:
simple_backtest(default_conf, contour, numres, mocker)
@@ -544,8 +548,8 @@ def test_backtest_pricecontours(default_conf, fee, mocker) -> None:
# Test backtest using offline data (testdata directory)
def test_backtest_ticks(default_conf, fee, mocker):
mocker.patch('freqtrade.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
patch_exchange(mocker)
ticks = [1, 5]
fun = Backtesting(default_conf).populate_buy_trend
for _ in ticks:
@@ -564,7 +568,6 @@ def test_backtest_clash_buy_sell(mocker, default_conf):
sell_value = 1
return _trend(dataframe, buy_value, sell_value)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
backtest_conf = _make_backtest_conf(mocker, conf=default_conf)
backtesting = Backtesting(default_conf)
backtesting.populate_buy_trend = fun # Override
@@ -580,7 +583,6 @@ def test_backtest_only_sell(mocker, default_conf):
sell_value = 1
return _trend(dataframe, buy_value, sell_value)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
backtest_conf = _make_backtest_conf(mocker, conf=default_conf)
backtesting = Backtesting(default_conf)
backtesting.populate_buy_trend = fun # Override
@@ -590,8 +592,7 @@ def test_backtest_only_sell(mocker, default_conf):
def test_backtest_alternate_buy_sell(default_conf, fee, mocker):
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
backtest_conf = _make_backtest_conf(mocker, conf=default_conf, pair='UNITTEST/BTC')
backtesting = Backtesting(default_conf)
backtesting.populate_buy_trend = _trend_alternate # Override
@@ -606,8 +607,8 @@ def test_backtest_alternate_buy_sell(default_conf, fee, mocker):
def test_backtest_record(default_conf, fee, mocker):
names = []
records = []
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
patch_exchange(mocker)
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
mocker.patch(
'freqtrade.optimize.backtesting.file_dump_json',
new=lambda n, r: (names.append(n), records.append(r))
@@ -655,9 +656,9 @@ def test_backtest_record(default_conf, fee, mocker):
def test_backtest_start_live(default_conf, mocker, caplog):
conf = deepcopy(default_conf)
conf['exchange']['pair_whitelist'] = ['UNITTEST/BTC']
mocker.patch('freqtrade.exchange.get_ticker_history',
new=lambda n, i: _load_pair_as_ticks(n, i))
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history',
new=lambda s, n, i: _load_pair_as_ticks(n, i))
patch_exchange(mocker)
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest', MagicMock())
mocker.patch('freqtrade.optimize.backtesting.Backtesting._generate_text_table', MagicMock())
mocker.patch('freqtrade.configuration.open', mocker.mock_open(

View File

@@ -10,7 +10,7 @@ import pytest
from freqtrade.optimize.__init__ import load_tickerdata_file
from freqtrade.optimize.hyperopt import Hyperopt, start
from freqtrade.strategy.resolver import StrategyResolver
from freqtrade.tests.conftest import log_has
from freqtrade.tests.conftest import log_has, patch_exchange
from freqtrade.tests.optimize.test_backtesting import get_args
# Avoid to reinit the same object again and again
@@ -22,8 +22,7 @@ _HYPEROPT = None
def init_hyperopt(default_conf, mocker):
global _HYPEROPT_INITIALIZED, _HYPEROPT
if not _HYPEROPT_INITIALIZED:
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
_HYPEROPT = Hyperopt(default_conf)
_HYPEROPT_INITIALIZED = True
@@ -61,8 +60,12 @@ def test_start(mocker, default_conf, caplog) -> None:
Test start() function
"""
start_mock = MagicMock()
mocker.patch(
'freqtrade.configuration.Configuration._load_config_file',
lambda *args, **kwargs: default_conf
)
mocker.patch('freqtrade.optimize.hyperopt.Hyperopt.start', start_mock)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
args = [
'--config', 'config.json',
@@ -178,7 +181,7 @@ def test_fmin_best_results(mocker, init_hyperopt, default_conf, caplog) -> None:
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value=fmin_result)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
StrategyResolver({'strategy': 'DefaultStrategy'})
hyperopt = Hyperopt(conf)
@@ -222,7 +225,7 @@ def test_fmin_throw_value_error(mocker, init_hyperopt, default_conf, caplog) ->
conf.update({'epochs': 1})
conf.update({'timerange': None})
conf.update({'spaces': 'all'})
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
StrategyResolver({'strategy': 'DefaultStrategy'})
hyperopt = Hyperopt(conf)
@@ -263,7 +266,7 @@ def test_resuming_previous_hyperopt_results_succeeds(mocker, init_hyperopt, defa
mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results)
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
StrategyResolver({'strategy': 'DefaultStrategy'})
hyperopt = Hyperopt(conf)
@@ -334,7 +337,7 @@ def test_start_calls_fmin(mocker, init_hyperopt, default_conf) -> None:
trials = create_trials(mocker)
mocker.patch('freqtrade.optimize.hyperopt.sorted', return_value=trials.results)
mocker.patch('freqtrade.optimize.hyperopt.load_data', MagicMock())
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
mock_fmin = mocker.patch('freqtrade.optimize.hyperopt.fmin', return_value={})
conf = deepcopy(default_conf)
@@ -499,7 +502,7 @@ def test_generate_optimizer(mocker, init_hyperopt, default_conf) -> None:
'freqtrade.optimize.hyperopt.Hyperopt.backtest',
MagicMock(return_value=backtest_result)
)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock())
patch_exchange(mocker)
optimizer_param = {
'adx': {'enabled': False},

View File

@@ -12,7 +12,7 @@ from freqtrade.optimize.__init__ import make_testdata_path, download_pairs, \
download_backtesting_testdata, load_tickerdata_file, trim_tickerlist, \
load_cached_data_for_updating
from freqtrade.arguments import TimeRange
from freqtrade.tests.conftest import log_has
from freqtrade.tests.conftest import log_has, get_patched_exchange
# Change this if modifying UNITTEST/BTC testdatafile
_BTC_UNITTEST_LENGTH = 13681
@@ -49,12 +49,11 @@ def _clean_test_file(file: str) -> None:
os.rename(file_swp, file)
def test_load_data_30min_ticker(ticker_history, mocker, caplog) -> None:
def test_load_data_30min_ticker(ticker_history, mocker, caplog, default_conf) -> None:
"""
Test load_data() with 30 min ticker
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
file = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'UNITTEST_BTC-30m.json')
_backup_file(file, copy_file=True)
optimize.load_data(None, pairs=['UNITTEST/BTC'], ticker_interval='30m')
@@ -63,11 +62,11 @@ def test_load_data_30min_ticker(ticker_history, mocker, caplog) -> None:
_clean_test_file(file)
def test_load_data_5min_ticker(ticker_history, mocker, caplog) -> None:
def test_load_data_5min_ticker(ticker_history, mocker, caplog, default_conf) -> None:
"""
Test load_data() with 5 min ticker
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
file = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'UNITTEST_BTC-5m.json')
_backup_file(file, copy_file=True)
@@ -81,7 +80,7 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog) -> None:
"""
Test load_data() with 1 min ticker
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
file = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'UNITTEST_BTC-1m.json')
_backup_file(file, copy_file=True)
@@ -91,12 +90,12 @@ def test_load_data_1min_ticker(ticker_history, mocker, caplog) -> None:
_clean_test_file(file)
def test_load_data_with_new_pair_1min(ticker_history, mocker, caplog) -> None:
def test_load_data_with_new_pair_1min(ticker_history, mocker, caplog, default_conf) -> None:
"""
Test load_data() with 1 min ticker
"""
mocker.patch('freqtrade.optimize.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
exchange = get_patched_exchange(mocker, default_conf)
file = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-1m.json')
_backup_file(file)
@@ -114,6 +113,7 @@ def test_load_data_with_new_pair_1min(ticker_history, mocker, caplog) -> None:
optimize.load_data(None,
ticker_interval='1m',
refresh_pairs=True,
exchange=exchange,
pairs=['MEME/BTC'])
assert os.path.isfile(file) is True
assert log_has('Download the pair: "MEME/BTC", Interval: 1m', caplog.record_tuples)
@@ -124,9 +124,9 @@ def test_testdata_path() -> None:
assert os.path.join('freqtrade', 'tests', 'testdata') in make_testdata_path(None)
def test_download_pairs(ticker_history, mocker) -> None:
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
def test_download_pairs(ticker_history, mocker, default_conf) -> None:
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
exchange = get_patched_exchange(mocker, default_conf)
file1_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-1m.json')
file1_5 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-5m.json')
file2_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'CFI_BTC-1m.json')
@@ -140,7 +140,8 @@ def test_download_pairs(ticker_history, mocker) -> None:
assert os.path.isfile(file1_1) is False
assert os.path.isfile(file2_1) is False
assert download_pairs(None, pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='1m') is True
assert download_pairs(None, exchange,
pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='1m') is True
assert os.path.isfile(file1_1) is True
assert os.path.isfile(file2_1) is True
@@ -152,7 +153,8 @@ def test_download_pairs(ticker_history, mocker) -> None:
assert os.path.isfile(file1_5) is False
assert os.path.isfile(file2_5) is False
assert download_pairs(None, pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='5m') is True
assert download_pairs(None, exchange,
pairs=['MEME/BTC', 'CFI/BTC'], ticker_interval='5m') is True
assert os.path.isfile(file1_5) is True
assert os.path.isfile(file2_5) is True
@@ -265,30 +267,32 @@ def test_load_cached_data_for_updating(mocker) -> None:
assert start_ts is None
def test_download_pairs_exception(ticker_history, mocker, caplog) -> None:
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
def test_download_pairs_exception(ticker_history, mocker, caplog, default_conf) -> None:
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
mocker.patch('freqtrade.optimize.__init__.download_backtesting_testdata',
side_effect=BaseException('File Error'))
exchange = get_patched_exchange(mocker, default_conf)
file1_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-1m.json')
file1_5 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-5m.json')
_backup_file(file1_1)
_backup_file(file1_5)
download_pairs(None, pairs=['MEME/BTC'], ticker_interval='1m')
download_pairs(None, exchange, pairs=['MEME/BTC'], ticker_interval='1m')
# clean files freshly downloaded
_clean_test_file(file1_1)
_clean_test_file(file1_5)
assert log_has('Failed to download the pair: "MEME/BTC", Interval: 1m', caplog.record_tuples)
def test_download_backtesting_testdata(ticker_history, mocker) -> None:
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=ticker_history)
def test_download_backtesting_testdata(ticker_history, mocker, default_conf) -> None:
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=ticker_history)
exchange = get_patched_exchange(mocker, default_conf)
# Download a 1 min ticker file
file1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'XEL_BTC-1m.json')
_backup_file(file1)
download_backtesting_testdata(None, pair="XEL/BTC", tick_interval='1m')
download_backtesting_testdata(None, exchange, pair="XEL/BTC", tick_interval='1m')
assert os.path.isfile(file1) is True
_clean_test_file(file1)
@@ -296,21 +300,21 @@ def test_download_backtesting_testdata(ticker_history, mocker) -> None:
file2 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'STORJ_BTC-5m.json')
_backup_file(file2)
download_backtesting_testdata(None, pair="STORJ/BTC", tick_interval='5m')
download_backtesting_testdata(None, exchange, pair="STORJ/BTC", tick_interval='5m')
assert os.path.isfile(file2) is True
_clean_test_file(file2)
def test_download_backtesting_testdata2(mocker) -> None:
def test_download_backtesting_testdata2(mocker, default_conf) -> None:
tick = [
[1509836520000, 0.00162008, 0.00162008, 0.00162008, 0.00162008, 108.14853839],
[1509836580000, 0.00161, 0.00161, 0.00161, 0.00161, 82.390199]
]
json_dump_mock = mocker.patch('freqtrade.misc.file_dump_json', return_value=None)
mocker.patch('freqtrade.optimize.__init__.get_ticker_history', return_value=tick)
download_backtesting_testdata(None, pair="UNITTEST/BTC", tick_interval='1m')
download_backtesting_testdata(None, pair="UNITTEST/BTC", tick_interval='3m')
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=tick)
exchange = get_patched_exchange(mocker, default_conf)
download_backtesting_testdata(None, exchange, pair="UNITTEST/BTC", tick_interval='1m')
download_backtesting_testdata(None, exchange, pair="UNITTEST/BTC", tick_interval='3m')
assert json_dump_mock.call_count == 2
@@ -326,8 +330,10 @@ def test_load_tickerdata_file() -> None:
def test_init(default_conf, mocker) -> None:
exchange = get_patched_exchange(mocker, default_conf)
assert {} == optimize.load_data(
'',
exchange=exchange,
pairs=[],
refresh_pairs=True,
ticker_interval=default_conf['ticker_interval']

View File

@@ -33,7 +33,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, markets, mocker) -> None:
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -80,7 +80,7 @@ def test_rpc_status_table(default_conf, ticker, fee, markets, mocker) -> None:
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -114,7 +114,7 @@ def test_rpc_daily_profit(default_conf, update, ticker, fee,
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -170,7 +170,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -194,7 +194,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
# Update the ticker with a market going up
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_up
)
@@ -209,7 +209,7 @@ def test_rpc_trade_statistics(default_conf, ticker, ticker_sell_up, fee,
# Update the ticker with a market going up
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_up
)
@@ -247,7 +247,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -267,7 +267,7 @@ def test_rpc_trade_statistics_closed(mocker, default_conf, ticker, fee, markets,
trade.update(limit_buy_order)
# Update the ticker with a market going up
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_up,
get_fee=fee
@@ -319,7 +319,7 @@ def test_rpc_balance_handle(default_conf, mocker):
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_balances=MagicMock(return_value=mock_balance)
)
@@ -347,7 +347,7 @@ def test_rpc_start(mocker, default_conf) -> None:
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock()
)
@@ -373,7 +373,7 @@ def test_rpc_stop(mocker, default_conf) -> None:
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock()
)
@@ -401,7 +401,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
cancel_order_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
cancel_order=cancel_order_mock,
@@ -447,7 +447,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
trade = Trade.query.filter(Trade.id == '1').first()
filled_amount = trade.amount / 2
mocker.patch(
'freqtrade.freqtradebot.exchange.get_order',
'freqtrade.exchange.Exchange.get_order',
return_value={
'status': 'open',
'type': 'limit',
@@ -466,7 +466,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
amount = trade.amount
# make an limit-buy open trade, if there is no 'filled', don't sell it
mocker.patch(
'freqtrade.freqtradebot.exchange.get_order',
'freqtrade.exchange.Exchange.get_order',
return_value={
'status': 'open',
'type': 'limit',
@@ -482,7 +482,7 @@ def test_rpc_forcesell(default_conf, ticker, fee, mocker, markets) -> None:
freqtradebot.create_trade()
# make an limit-sell open trade
mocker.patch(
'freqtrade.freqtradebot.exchange.get_order',
'freqtrade.exchange.Exchange.get_order',
return_value={
'status': 'open',
'type': 'limit',
@@ -503,7 +503,7 @@ def test_performance_handle(default_conf, ticker, limit_buy_order, fee,
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_balances=MagicMock(return_value=ticker),
get_ticker=ticker,
@@ -542,7 +542,7 @@ def test_rpc_count(mocker, default_conf, ticker, fee, markets) -> None:
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_balances=MagicMock(return_value=ticker),
get_ticker=ticker,

View File

@@ -20,7 +20,7 @@ from freqtrade.persistence import Trade
from freqtrade.rpc.telegram import Telegram
from freqtrade.rpc.telegram import authorized_only
from freqtrade.state import State
from freqtrade.tests.conftest import get_patched_freqtradebot, log_has
from freqtrade.tests.conftest import get_patched_freqtradebot, patch_exchange, log_has
from freqtrade.tests.test_freqtradebot import patch_get_signal, patch_coinmarketcap
@@ -100,7 +100,7 @@ def test_authorized_only(default_conf, mocker, caplog) -> None:
"""
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
patch_exchange(mocker, None)
chat = Chat(0, 0)
update = Update(randint(1, 100))
@@ -131,8 +131,7 @@ def test_authorized_only_unauthorized(default_conf, mocker, caplog) -> None:
"""
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
patch_exchange(mocker, None)
chat = Chat(0xdeadbeef, 0)
update = Update(randint(1, 100))
update.message = Message(randint(1, 100), 0, datetime.utcnow(), chat)
@@ -162,7 +161,7 @@ def test_authorized_only_exception(default_conf, mocker, caplog) -> None:
"""
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
patch_exchange(mocker)
update = Update(randint(1, 100))
update.message = Message(randint(1, 100), 0, datetime.utcnow(), Chat(0, 0))
@@ -198,7 +197,7 @@ def test_status(default_conf, update, mocker, fee, ticker, markets) -> None:
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_pair_detail_url=MagicMock(),
@@ -239,7 +238,7 @@ def test_status_handle(default_conf, update, ticker, fee, markets, mocker) -> No
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -286,7 +285,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, markets, mocker)
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
@@ -344,7 +343,7 @@ def test_daily_handle(default_conf, update, ticker, limit_buy_order, fee,
return_value=15000.0
)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -414,7 +413,7 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker
)
@@ -454,7 +453,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -489,7 +488,7 @@ def test_profit_handle(default_conf, update, ticker, ticker_sell_up, fee,
msg_mock.reset_mock()
# Update the ticker with a market going up
mocker.patch('freqtrade.freqtradebot.exchange.get_ticker', ticker_sell_up)
mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up)
trade.update(limit_sell_order)
trade.close_date = datetime.utcnow()
@@ -554,9 +553,8 @@ def test_telegram_balance_handle(default_conf, update, mocker) -> None:
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.get_balances', return_value=mock_balance)
mocker.patch('freqtrade.freqtradebot.exchange.get_ticker', side_effect=mock_ticker)
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=mock_balance)
mocker.patch('freqtrade.exchange.Exchange.get_ticker', side_effect=mock_ticker)
msg_mock = MagicMock()
mocker.patch.multiple(
@@ -565,7 +563,7 @@ def test_telegram_balance_handle(default_conf, update, mocker) -> None:
_send_msg=msg_mock
)
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
telegram._balance(bot=MagicMock(), update=update)
@@ -584,9 +582,7 @@ def test_zero_balance_handle(default_conf, update, mocker) -> None:
Test _balance() method when the Exchange platform returns nothing
"""
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker, value={'price_usd': 15000.0})
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.get_balances', return_value={})
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value={})
msg_mock = MagicMock()
mocker.patch.multiple(
@@ -595,7 +591,7 @@ def test_zero_balance_handle(default_conf, update, mocker) -> None:
_send_msg=msg_mock
)
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
telegram._balance(bot=MagicMock(), update=update)
@@ -608,17 +604,14 @@ def test_start_handle(default_conf, update, mocker) -> None:
"""
Test _start() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
freqtradebot.state = State.STOPPED
@@ -632,17 +625,14 @@ def test_start_handle_already_running(default_conf, update, mocker) -> None:
"""
Test _start() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
freqtradebot.state = State.RUNNING
@@ -658,16 +648,14 @@ def test_stop_handle(default_conf, update, mocker) -> None:
Test _stop() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
freqtradebot.state = State.RUNNING
@@ -683,16 +671,14 @@ def test_stop_handle_already_stopped(default_conf, update, mocker) -> None:
Test _stop() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
freqtradebot.state = State.STOPPED
@@ -706,16 +692,14 @@ def test_stop_handle_already_stopped(default_conf, update, mocker) -> None:
def test_reload_conf_handle(default_conf, update, mocker) -> None:
""" Test _reload_conf() method """
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
freqtradebot.state = State.RUNNING
@@ -737,7 +721,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -754,7 +738,7 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
assert trade
# Increase the price and sell it
mocker.patch('freqtrade.freqtradebot.exchange.get_ticker', ticker_sell_up)
mocker.patch('freqtrade.exchange.Exchange.get_ticker', ticker_sell_up)
update.message.text = '/forcesell 1'
telegram._forcesell(bot=MagicMock(), update=update)
@@ -779,7 +763,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -794,7 +778,7 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
# Decrease the price and sell it
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_down
)
@@ -823,9 +807,9 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
rpc_mock = mocker.patch('freqtrade.rpc.telegram.Telegram.send_msg', MagicMock())
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
mocker.patch('freqtrade.exchange.get_pair_detail_url', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.get_pair_detail_url', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -863,7 +847,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
telegram = Telegram(freqtradebot)
@@ -906,7 +890,7 @@ def test_performance_handle(default_conf, update, ticker, fee,
_send_msg=msg_mock
)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -947,7 +931,7 @@ def test_performance_handle_invalid(default_conf, update, mocker) -> None:
_init=MagicMock(),
_send_msg=msg_mock
)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
freqtradebot = FreqtradeBot(default_conf)
telegram = Telegram(freqtradebot)
@@ -971,13 +955,13 @@ def test_count_handle(default_conf, update, ticker, fee, markets, mocker) -> Non
_send_msg=msg_mock
)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': 'mocked_order_id'}),
get_markets=markets
)
mocker.patch('freqtrade.optimize.backtesting.exchange.get_fee', fee)
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
freqtradebot = FreqtradeBot(default_conf)
telegram = Telegram(freqtradebot)
@@ -1007,14 +991,14 @@ def test_help_handle(default_conf, update, mocker) -> None:
Test _help() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
telegram._help(bot=MagicMock(), update=update)
@@ -1027,14 +1011,13 @@ def test_version_handle(default_conf, update, mocker) -> None:
Test _version() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
msg_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.rpc.telegram.Telegram',
_init=MagicMock(),
_send_msg=msg_mock
)
freqtradebot = FreqtradeBot(default_conf)
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
telegram = Telegram(freqtradebot)
telegram._version(bot=MagicMock(), update=update)
@@ -1047,11 +1030,10 @@ def test_send_msg(default_conf, mocker) -> None:
Test send_msg() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
conf = deepcopy(default_conf)
bot = MagicMock()
freqtradebot = FreqtradeBot(conf)
freqtradebot = get_patched_freqtradebot(mocker, conf)
telegram = Telegram(freqtradebot)
telegram._config['telegram']['enabled'] = True
@@ -1064,12 +1046,11 @@ def test_send_msg_network_error(default_conf, mocker, caplog) -> None:
Test send_msg() method
"""
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
conf = deepcopy(default_conf)
bot = MagicMock()
bot.send_message = MagicMock(side_effect=NetworkError('Oh snap'))
freqtradebot = FreqtradeBot(conf)
freqtradebot = get_patched_freqtradebot(mocker, conf)
telegram = Telegram(freqtradebot)
telegram._config['telegram']['enabled'] = True

View File

@@ -1,14 +1,39 @@
# pragma pylint: disable=missing-docstring, protected-access, C0103
import logging
import os
import pytest
from freqtrade.strategy import import_strategy
from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import IStrategy
from freqtrade.strategy.resolver import StrategyResolver
def test_import_strategy(caplog):
caplog.set_level(logging.DEBUG)
strategy = DefaultStrategy()
strategy.some_method = lambda *args, **kwargs: 42
assert strategy.__module__ == 'freqtrade.strategy.default_strategy'
assert strategy.some_method() == 42
imported_strategy = import_strategy(strategy)
assert dir(strategy) == dir(imported_strategy)
assert imported_strategy.__module__ == 'freqtrade.strategy'
assert imported_strategy.some_method() == 42
assert (
'freqtrade.strategy',
logging.DEBUG,
'Imported strategy freqtrade.strategy.default_strategy.DefaultStrategy '
'as freqtrade.strategy.DefaultStrategy',
) in caplog.record_tuples
def test_search_strategy():
default_location = os.path.join(os.path.dirname(
os.path.realpath(__file__)), '..', '..', 'strategy'
@@ -20,8 +45,7 @@ def test_search_strategy():
def test_load_strategy(result):
resolver = StrategyResolver()
resolver._load_strategy('TestStrategy')
resolver = StrategyResolver({'strategy': 'TestStrategy'})
assert hasattr(resolver.strategy, 'populate_indicators')
assert 'adx' in resolver.strategy.populate_indicators(result)

View File

@@ -32,7 +32,7 @@ def test_refresh_market_pair_not_in_whitelist(mocker, markets):
freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
mocker.patch('freqtrade.exchange.Exchange.get_markets', markets)
refreshedwhitelist = freqtradebot._refresh_whitelist(
conf['exchange']['pair_whitelist'] + ['XXX/BTC']
)
@@ -46,7 +46,7 @@ def test_refresh_whitelist(mocker, markets):
conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
mocker.patch('freqtrade.exchange.Exchange.get_markets', markets)
refreshedwhitelist = freqtradebot._refresh_whitelist(conf['exchange']['pair_whitelist'])
# List ordered by BaseVolume
@@ -59,7 +59,7 @@ def test_refresh_whitelist_dynamic(mocker, markets, tickers):
conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
get_markets=markets,
get_tickers=tickers,
exchange_has=MagicMock(return_value=True)
@@ -78,7 +78,7 @@ def test_refresh_whitelist_dynamic(mocker, markets, tickers):
def test_refresh_whitelist_dynamic_empty(mocker, markets_empty):
conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets_empty)
mocker.patch('freqtrade.exchange.Exchange.get_markets', markets_empty)
# argument: use the whitelist dynamically by exchange-volume
whitelist = []

View File

@@ -14,7 +14,7 @@ from pandas import DataFrame
from freqtrade.analyze import Analyze, SignalType
from freqtrade.optimize.__init__ import load_tickerdata_file
from freqtrade.arguments import TimeRange
from freqtrade.tests.conftest import log_has
from freqtrade.tests.conftest import log_has, get_patched_exchange
# Avoid to reinit the same object again and again
_ANALYZE = Analyze({'strategy': 'DefaultStrategy'})
@@ -66,16 +66,16 @@ def test_populates_sell_trend(result):
assert 'sell' in dataframe.columns
def test_returns_latest_buy_signal(mocker):
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=MagicMock())
def test_returns_latest_buy_signal(mocker, default_conf):
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=MagicMock())
exchange = get_patched_exchange(mocker, default_conf)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
analyze_ticker=MagicMock(
return_value=DataFrame([{'buy': 1, 'sell': 0, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (True, False)
assert _ANALYZE.get_signal(exchange, 'ETH/BTC', '5m') == (True, False)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
@@ -83,11 +83,12 @@ def test_returns_latest_buy_signal(mocker):
return_value=DataFrame([{'buy': 0, 'sell': 1, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, True)
assert _ANALYZE.get_signal(exchange, 'ETH/BTC', '5m') == (False, True)
def test_returns_latest_sell_signal(mocker):
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=MagicMock())
def test_returns_latest_sell_signal(mocker, default_conf):
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=MagicMock())
exchange = get_patched_exchange(mocker, default_conf)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
analyze_ticker=MagicMock(
@@ -95,7 +96,7 @@ def test_returns_latest_sell_signal(mocker):
)
)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, True)
assert _ANALYZE.get_signal(exchange, 'ETH/BTC', '5m') == (False, True)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
@@ -103,45 +104,49 @@ def test_returns_latest_sell_signal(mocker):
return_value=DataFrame([{'sell': 0, 'buy': 1, 'date': arrow.utcnow()}])
)
)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (True, False)
assert _ANALYZE.get_signal(exchange, 'ETH/BTC', '5m') == (True, False)
def test_get_signal_empty(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=None)
assert (False, False) == _ANALYZE.get_signal('foo', default_conf['ticker_interval'])
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=None)
exchange = get_patched_exchange(mocker, default_conf)
assert (False, False) == _ANALYZE.get_signal(exchange, 'foo', default_conf['ticker_interval'])
assert log_has('Empty ticker history for pair foo', caplog.record_tuples)
def test_get_signal_exception_valueerror(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=1)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=1)
exchange = get_patched_exchange(mocker, default_conf)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
analyze_ticker=MagicMock(
side_effect=ValueError('xyz')
)
)
assert (False, False) == _ANALYZE.get_signal('foo', default_conf['ticker_interval'])
assert (False, False) == _ANALYZE.get_signal(exchange, 'foo', default_conf['ticker_interval'])
assert log_has('Unable to analyze ticker for pair foo: xyz', caplog.record_tuples)
def test_get_signal_empty_dataframe(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=1)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=1)
exchange = get_patched_exchange(mocker, default_conf)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
analyze_ticker=MagicMock(
return_value=DataFrame([])
)
)
assert (False, False) == _ANALYZE.get_signal('xyz', default_conf['ticker_interval'])
assert (False, False) == _ANALYZE.get_signal(exchange, 'xyz', default_conf['ticker_interval'])
assert log_has('Empty dataframe for pair xyz', caplog.record_tuples)
def test_get_signal_old_dataframe(default_conf, mocker, caplog):
caplog.set_level(logging.INFO)
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=1)
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=1)
exchange = get_patched_exchange(mocker, default_conf)
# FIX: The get_signal function has hardcoded 10, which we must inturn hardcode
oldtime = arrow.utcnow() - datetime.timedelta(minutes=11)
ticks = DataFrame([{'buy': 1, 'date': oldtime}])
@@ -151,15 +156,16 @@ def test_get_signal_old_dataframe(default_conf, mocker, caplog):
return_value=DataFrame(ticks)
)
)
assert (False, False) == _ANALYZE.get_signal('xyz', default_conf['ticker_interval'])
assert (False, False) == _ANALYZE.get_signal(exchange, 'xyz', default_conf['ticker_interval'])
assert log_has(
'Outdated history for pair xyz. Last tick is 11 minutes old',
caplog.record_tuples
)
def test_get_signal_handles_exceptions(mocker):
mocker.patch('freqtrade.analyze.get_ticker_history', return_value=MagicMock())
def test_get_signal_handles_exceptions(mocker, default_conf):
mocker.patch('freqtrade.exchange.Exchange.get_ticker_history', return_value=MagicMock())
exchange = get_patched_exchange(mocker, default_conf)
mocker.patch.multiple(
'freqtrade.analyze.Analyze',
analyze_ticker=MagicMock(
@@ -167,7 +173,7 @@ def test_get_signal_handles_exceptions(mocker):
)
)
assert _ANALYZE.get_signal('ETH/BTC', '5m') == (False, False)
assert _ANALYZE.get_signal(exchange, 'ETH/BTC', '5m') == (False, False)
def test_parse_ticker_dataframe(ticker_history):

View File

@@ -13,6 +13,7 @@ from jsonschema import ValidationError
from freqtrade.arguments import Arguments
from freqtrade.configuration import Configuration
from freqtrade.constants import DEFAULT_DB_PROD_URL, DEFAULT_DB_DRYRUN_URL
from freqtrade.tests.conftest import log_has
from freqtrade import OperationalException
@@ -152,6 +153,43 @@ def test_load_config_with_params(default_conf, mocker) -> None:
assert validated_conf.get('strategy_path') == '/some/path'
assert validated_conf.get('db_url') == 'sqlite:///someurl'
conf = default_conf.copy()
conf["dry_run"] = False
del conf["db_url"]
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
read_data=json.dumps(conf)
))
arglist = [
'--dynamic-whitelist', '10',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
args = Arguments(arglist, '').get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
assert validated_conf.get('db_url') == DEFAULT_DB_PROD_URL
# Test dry=run with ProdURL
conf = default_conf.copy()
conf["dry_run"] = True
conf["db_url"] = DEFAULT_DB_PROD_URL
mocker.patch('freqtrade.configuration.open', mocker.mock_open(
read_data=json.dumps(conf)
))
arglist = [
'--dynamic-whitelist', '10',
'--strategy', 'TestStrategy',
'--strategy-path', '/some/path'
]
args = Arguments(arglist, '').get_parsed_arg()
configuration = Configuration(args)
validated_conf = configuration.load_config()
assert validated_conf.get('db_url') == DEFAULT_DB_DRYRUN_URL
def test_load_custom_strategy(default_conf, mocker) -> None:
"""

View File

@@ -40,7 +40,8 @@ def test_pair_convertion_object():
assert pair_convertion.price == 30000.123
def test_fiat_convert_is_supported():
def test_fiat_convert_is_supported(mocker):
patch_coinmarketcap(mocker)
fiat_convert = CryptoToFiatConverter()
assert fiat_convert._is_supported_fiat(fiat='USD') is True
assert fiat_convert._is_supported_fiat(fiat='usd') is True
@@ -48,7 +49,9 @@ def test_fiat_convert_is_supported():
assert fiat_convert._is_supported_fiat(fiat='ABC') is False
def test_fiat_convert_add_pair():
def test_fiat_convert_add_pair(mocker):
patch_coinmarketcap(mocker)
fiat_convert = CryptoToFiatConverter()
pair_len = len(fiat_convert._pairs)
@@ -70,11 +73,8 @@ def test_fiat_convert_add_pair():
def test_fiat_convert_find_price(mocker):
api_mock = MagicMock(return_value={
'price_usd': 12345.0,
'price_eur': 13000.2
})
mocker.patch('freqtrade.fiat_convert.Market.ticker', api_mock)
patch_coinmarketcap(mocker)
fiat_convert = CryptoToFiatConverter()
with pytest.raises(ValueError, match=r'The fiat ABC is not supported.'):
@@ -92,17 +92,15 @@ def test_fiat_convert_find_price(mocker):
def test_fiat_convert_unsupported_crypto(mocker, caplog):
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._cryptomap', return_value=[])
patch_coinmarketcap(mocker)
fiat_convert = CryptoToFiatConverter()
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)
def test_fiat_convert_get_price(mocker):
api_mock = MagicMock(return_value={
'price_usd': 28000.0,
'price_eur': 15000.0
})
mocker.patch('freqtrade.fiat_convert.Market.ticker', api_mock)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=28000.0)
fiat_convert = CryptoToFiatConverter()
@@ -172,8 +170,9 @@ def test_fiat_init_network_exception(mocker):
assert length_cryptomap == 0
def test_fiat_convert_without_network():
def test_fiat_convert_without_network(mocker):
# Because CryptoToFiatConverter is a Singleton we reset the value of _coinmarketcap
patch_coinmarketcap(mocker)
fiat_convert = CryptoToFiatConverter()
@@ -186,6 +185,7 @@ def test_fiat_convert_without_network():
def test_convert_amount(mocker):
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter.get_price', return_value=12345.0)
fiat_convert = CryptoToFiatConverter()

View File

@@ -18,7 +18,7 @@ from freqtrade import constants, DependencyException, OperationalException, Temp
from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.persistence import Trade
from freqtrade.state import State
from freqtrade.tests.conftest import log_has, patch_coinmarketcap
from freqtrade.tests.conftest import log_has, patch_coinmarketcap, patch_exchange
# Functions for recurrent object patching
@@ -32,7 +32,7 @@ def get_patched_freqtradebot(mocker, config) -> FreqtradeBot:
mocker.patch('freqtrade.freqtradebot.Analyze', MagicMock())
mocker.patch('freqtrade.freqtradebot.RPCManager', MagicMock())
mocker.patch('freqtrade.freqtradebot.persistence.init', MagicMock())
mocker.patch('freqtrade.freqtradebot.exchange.init', MagicMock())
patch_exchange(mocker)
patch_coinmarketcap(mocker)
return FreqtradeBot(config)
@@ -47,7 +47,7 @@ def patch_get_signal(mocker, value=(True, False)) -> None:
"""
mocker.patch(
'freqtrade.freqtradebot.Analyze.get_signal',
side_effect=lambda s, t: value
side_effect=lambda e, s, t: value
)
@@ -187,9 +187,9 @@ def test_gen_pair_whitelist(mocker, default_conf, tickers) -> None:
Test _gen_pair_whitelist() method
"""
freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_tickers', tickers)
mocker.patch('freqtrade.freqtradebot.exchange.exchange_has', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
# mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
# Test to retrieved BTC sorted on quoteVolume (default)
whitelist = freqtrade._gen_pair_whitelist(base_currency='BTC')
@@ -223,7 +223,7 @@ def test_get_trade_stake_amount(default_conf, ticker, limit_buy_order, fee, mock
patch_RPCManager(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 2)
)
@@ -244,7 +244,7 @@ def test_get_trade_stake_amount_no_stake_amount(default_conf,
"""
patch_RPCManager(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_balance=MagicMock(return_value=default_conf['stake_amount'] * 0.5)
)
@@ -269,7 +269,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -313,13 +313,13 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
"""
patch_RPCManager(mocker)
mocker.patch('freqtrade.freqtradebot.exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())
mocker.patch('freqtrade.freqtradebot.Analyze.get_stoploss', MagicMock(return_value=-0.05))
freqtrade = FreqtradeBot(default_conf)
# no pair found
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC'
}])
@@ -329,7 +329,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# no 'limits' section
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC'
}])
@@ -339,7 +339,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# empty 'limits' section
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {}
@@ -350,7 +350,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# empty 'cost'/'amount' section
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {
@@ -364,7 +364,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# min cost is set
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {
@@ -378,7 +378,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# min amount is set
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {
@@ -392,7 +392,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# min amount and cost are set (cost is minimal)
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {
@@ -406,7 +406,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None:
# min amount and cost are set (amount is minial)
mocker.patch(
'freqtrade.freqtradebot.exchange.get_markets',
'freqtrade.exchange.Exchange.get_markets',
MagicMock(return_value=[{
'symbol': 'ETH/BTC',
'limits': {
@@ -427,7 +427,7 @@ def test_create_trade(default_conf, ticker, limit_buy_order, fee, markets, mocke
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -465,7 +465,7 @@ def test_create_trade_no_stake_amount(default_conf, ticker, limit_buy_order,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -489,7 +489,7 @@ def test_create_trade_minimal_amount(default_conf, ticker, limit_buy_order,
patch_coinmarketcap(mocker)
buy_mock = MagicMock(return_value={'id': limit_buy_order['id']})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=buy_mock,
@@ -516,7 +516,7 @@ def test_create_trade_too_small_stake_amount(default_conf, ticker, limit_buy_ord
patch_coinmarketcap(mocker)
buy_mock = MagicMock(return_value={'id': limit_buy_order['id']})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=buy_mock,
@@ -541,7 +541,7 @@ def test_create_trade_limit_reached(default_conf, ticker, limit_buy_order,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -567,7 +567,7 @@ def test_create_trade_no_pairs(default_conf, ticker, limit_buy_order, fee, marke
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -595,7 +595,7 @@ def test_create_trade_no_pairs_after_blacklist(default_conf, ticker,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -625,7 +625,7 @@ def test_create_trade_no_signal(default_conf, fee, mocker) -> None:
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker_history=MagicMock(return_value=20),
get_balance=MagicMock(return_value=20),
@@ -650,7 +650,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_markets=markets,
@@ -691,7 +691,7 @@ def test_process_exchange_failures(default_conf, ticker, markets, mocker) -> Non
patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_markets=markets,
@@ -713,7 +713,7 @@ def test_process_operational_exception(default_conf, ticker, markets, mocker) ->
msg_mock = patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_markets=markets,
@@ -737,7 +737,7 @@ def test_process_trade_handling(
patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_markets=markets,
@@ -758,29 +758,32 @@ def test_process_trade_handling(
assert result is False
def test_balance_fully_ask_side(mocker) -> None:
def test_balance_fully_ask_side(mocker, default_conf) -> None:
"""
Test get_target_bid() method
"""
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 0.0}})
default_conf['bid_strategy']['ask_last_balance'] = 0.0
freqtrade = get_patched_freqtradebot(mocker, default_conf)
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 20
def test_balance_fully_last_side(mocker) -> None:
def test_balance_fully_last_side(mocker, default_conf) -> None:
"""
Test get_target_bid() method
"""
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 1.0}})
default_conf['bid_strategy']['ask_last_balance'] = 1.0
freqtrade = get_patched_freqtradebot(mocker, default_conf)
assert freqtrade.get_target_bid({'ask': 20, 'last': 10}) == 10
def test_balance_bigger_last_ask(mocker) -> None:
def test_balance_bigger_last_ask(mocker, default_conf) -> None:
"""
Test get_target_bid() method
"""
freqtrade = get_patched_freqtradebot(mocker, {'bid_strategy': {'ask_last_balance': 1.0}})
default_conf['bid_strategy']['ask_last_balance'] = 1.0
freqtrade = get_patched_freqtradebot(mocker, default_conf)
assert freqtrade.get_target_bid({'ask': 5, 'last': 10}) == 5
@@ -819,8 +822,8 @@ def test_process_maybe_execute_sell(mocker, default_conf, limit_buy_order, caplo
freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.handle_trade', MagicMock(return_value=True))
mocker.patch('freqtrade.freqtradebot.exchange.get_order', return_value=limit_buy_order)
mocker.patch('freqtrade.freqtradebot.exchange.get_trades_for_order', return_value=[])
mocker.patch('freqtrade.exchange.Exchange.get_order', return_value=limit_buy_order)
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
mocker.patch('freqtrade.freqtradebot.FreqtradeBot.get_real_amount',
return_value=limit_buy_order['amount'])
@@ -853,7 +856,7 @@ def test_process_maybe_execute_sell_exception(mocker, default_conf,
Test the exceptions in process_maybe_execute_sell()
"""
freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_order', return_value=limit_buy_order)
mocker.patch('freqtrade.exchange.Exchange.get_order', return_value=limit_buy_order)
trade = MagicMock()
trade.open_order_id = '123'
@@ -884,7 +887,7 @@ def test_handle_trade(default_conf, limit_buy_order, limit_sell_order,
patch_get_signal(mocker)
patch_RPCManager(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00001172,
@@ -935,7 +938,7 @@ def test_handle_overlpapping_signals(default_conf, ticker, limit_buy_order,
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -995,7 +998,7 @@ def test_handle_trade_roi(default_conf, ticker, limit_buy_order,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -1033,7 +1036,7 @@ def test_handle_trade_experimental(
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -1065,7 +1068,7 @@ def test_close_trade(default_conf, ticker, limit_buy_order, limit_sell_order,
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
@@ -1096,7 +1099,7 @@ def test_check_handle_timedout_buy(default_conf, ticker, limit_buy_order_old, fe
cancel_order_mock = MagicMock()
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_order=MagicMock(return_value=limit_buy_order_old),
@@ -1137,7 +1140,7 @@ def test_check_handle_timedout_sell(default_conf, ticker, limit_sell_order_old,
patch_coinmarketcap(mocker)
cancel_order_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_order=MagicMock(return_value=limit_sell_order_old),
@@ -1177,7 +1180,7 @@ def test_check_handle_timedout_partial(default_conf, ticker, limit_buy_order_old
patch_coinmarketcap(mocker)
cancel_order_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_order=MagicMock(return_value=limit_buy_order_old_partial),
@@ -1225,7 +1228,7 @@ def test_check_handle_timedout_exception(default_conf, ticker, mocker, caplog) -
handle_timedout_limit_sell=MagicMock(),
)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_order=MagicMock(side_effect=requests.exceptions.RequestException('Oh snap')),
@@ -1265,7 +1268,7 @@ def test_handle_timedout_limit_buy(mocker, default_conf) -> None:
patch_coinmarketcap(mocker)
cancel_order_mock = MagicMock()
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
cancel_order=cancel_order_mock
)
@@ -1291,7 +1294,7 @@ def test_handle_timedout_limit_sell(mocker, default_conf) -> None:
cancel_order_mock = MagicMock()
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
cancel_order=cancel_order_mock
)
@@ -1317,7 +1320,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc
rpc_mock = patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -1334,7 +1337,7 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc
# Increase the price and sell it
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_up
)
@@ -1360,7 +1363,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets,
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.fiat_convert.CryptoToFiatConverter._find_price', return_value=15000.0)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -1376,7 +1379,7 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets,
# Decrease the price and sell it
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_down
)
@@ -1401,7 +1404,7 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
rpc_mock = patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -1417,7 +1420,7 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
# Increase the price and sell it
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_up
)
@@ -1443,7 +1446,7 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
rpc_mock = patch_RPCManager(mocker)
patch_coinmarketcap(mocker, value={'price_usd': 12345.0})
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee,
@@ -1459,7 +1462,7 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
# Decrease the price and sell it
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=ticker_sell_down
)
@@ -1484,7 +1487,7 @@ def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00002172,
@@ -1519,7 +1522,7 @@ def test_sell_profit_only_disable_profit(default_conf, limit_buy_order,
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00002172,
@@ -1551,9 +1554,9 @@ def test_sell_profit_only_enable_loss(default_conf, limit_buy_order, fee, market
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
mocker.patch('freqtrade.freqtradebot.Analyze.stop_loss_reached', return_value=False)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00000172,
@@ -1587,16 +1590,15 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=False)
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00000172,
'ask': 0.00000173,
'last': 0.00000172
'bid': 0.0000172,
'ask': 0.0000173,
'last': 0.0000172
}),
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
get_fee=fee,
get_markets=markets
)
conf = deepcopy(default_conf)
@@ -1614,17 +1616,96 @@ def test_sell_profit_only_disable_loss(default_conf, limit_buy_order, fee, marke
assert freqtrade.handle_trade(trade) is True
def test_ignore_roi_if_buy_signal(default_conf, limit_buy_order, fee, mocker) -> None:
"""
Test sell_profit_only feature when enabled and we have a loss
"""
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=True)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.0000172,
'ask': 0.0000173,
'last': 0.0000172
}),
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
get_fee=fee,
)
conf = deepcopy(default_conf)
conf['experimental'] = {
'ignore_roi_if_buy_signal': True
}
freqtrade = FreqtradeBot(conf)
freqtrade.create_trade()
trade = Trade.query.first()
trade.update(limit_buy_order)
patch_get_signal(mocker, value=(True, True))
assert freqtrade.handle_trade(trade) is False
# Test if buy-signal is absent (should sell due to roi = true)
patch_get_signal(mocker, value=(False, True))
assert freqtrade.handle_trade(trade) is True
def test_disable_ignore_roi_if_buy_signal(default_conf, limit_buy_order,
fee, markets, mocker) -> None:
"""
Test sell_profit_only feature when enabled and we have a loss
"""
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.freqtradebot.Analyze.min_roi_reached', return_value=True)
mocker.patch.multiple(
'freqtrade.exchange.Exchange',
validate_pairs=MagicMock(),
get_ticker=MagicMock(return_value={
'bid': 0.00000172,
'ask': 0.00000173,
'last': 0.00000172
}),
buy=MagicMock(return_value={'id': limit_buy_order['id']}),
get_fee=fee,
get_markets=markets
)
conf = deepcopy(default_conf)
conf['experimental'] = {
'ignore_roi_if_buy_signal': False
}
freqtrade = FreqtradeBot(conf)
freqtrade.create_trade()
trade = Trade.query.first()
trade.update(limit_buy_order)
# Sell due to min_roi_reached
patch_get_signal(mocker, value=(True, True))
assert freqtrade.handle_trade(trade) is True
# Test if buy-signal is absent
patch_get_signal(mocker, value=(False, True))
assert freqtrade.handle_trade(trade) is True
def test_get_real_amount_quote(default_conf, trades_for_order, buy_order_fee, caplog, mocker):
"""
Test get_real_amount - fee in quote currency
"""
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=trades_for_order)
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
amount = sum(x['amount'] for x in trades_for_order)
trade = Trade(
pair='LTC/ETH',
@@ -1646,12 +1727,12 @@ def test_get_real_amount_no_trade(default_conf, buy_order_fee, caplog, mocker):
Test get_real_amount - fee in quote currency
"""
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=[])
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
amount = buy_order_fee['amount']
trade = Trade(
pair='LTC/ETH',
@@ -1677,8 +1758,8 @@ def test_get_real_amount_stake(default_conf, trades_for_order, buy_order_fee, mo
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=trades_for_order)
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
amount = sum(x['amount'] for x in trades_for_order)
trade = Trade(
pair='LTC/ETH',
@@ -1703,8 +1784,8 @@ def test_get_real_amount_BNB(default_conf, trades_for_order, buy_order_fee, mock
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=trades_for_order)
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
amount = sum(x['amount'] for x in trades_for_order)
trade = Trade(
pair='LTC/ETH',
@@ -1726,8 +1807,8 @@ def test_get_real_amount_multi(default_conf, trades_for_order2, buy_order_fee, c
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=trades_for_order2)
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order2)
amount = float(sum(x['amount'] for x in trades_for_order2))
trade = Trade(
pair='LTC/ETH',
@@ -1754,8 +1835,9 @@ def test_get_real_amount_fromorder(default_conf, trades_for_order, buy_order_fee
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=[trades_for_order])
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order',
return_value=[trades_for_order])
amount = float(sum(x['amount'] for x in trades_for_order))
trade = Trade(
pair='LTC/ETH',
@@ -1782,8 +1864,8 @@ def test_get_real_amount_invalid_order(default_conf, trades_for_order, buy_order
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=[])
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=[])
amount = float(sum(x['amount'] for x in trades_for_order))
trade = Trade(
pair='LTC/ETH',
@@ -1807,8 +1889,8 @@ def test_get_real_amount_invalid(default_conf, trades_for_order, buy_order_fee,
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.get_trades_for_order', return_value=trades_for_order)
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.get_trades_for_order', return_value=trades_for_order)
amount = sum(x['amount'] for x in trades_for_order)
trade = Trade(
pair='LTC/ETH',
@@ -1829,7 +1911,7 @@ def test_get_real_amount_open_trade(default_conf, mocker):
patch_get_signal(mocker)
patch_RPCManager(mocker)
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.exchange.validate_pairs', MagicMock(return_value=True))
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock(return_value=True))
amount = 12345
trade = Trade(
pair='LTC/ETH',

View File

@@ -13,7 +13,7 @@ from freqtrade.arguments import Arguments
from freqtrade.freqtradebot import FreqtradeBot
from freqtrade.main import main, set_loggers, reconfigure
from freqtrade.state import State
from freqtrade.tests.conftest import log_has
from freqtrade.tests.conftest import log_has, patch_exchange
def test_parse_args_backtesting(mocker) -> None:
@@ -70,6 +70,7 @@ def test_main_fatal_exception(mocker, default_conf, caplog) -> None:
Test main() function
In this test we are skipping the while True loop by throwing an exception.
"""
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.FreqtradeBot',
_init_modules=MagicMock(),
@@ -97,6 +98,7 @@ def test_main_keyboard_interrupt(mocker, default_conf, caplog) -> None:
Test main() function
In this test we are skipping the while True loop by throwing an exception.
"""
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.FreqtradeBot',
_init_modules=MagicMock(),
@@ -124,6 +126,7 @@ def test_main_operational_exception(mocker, default_conf, caplog) -> None:
Test main() function
In this test we are skipping the while True loop by throwing an exception.
"""
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.FreqtradeBot',
_init_modules=MagicMock(),
@@ -151,6 +154,7 @@ def test_main_reload_conf(mocker, default_conf, caplog) -> None:
Test main() function
In this test we are skipping the while True loop by throwing an exception.
"""
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.FreqtradeBot',
_init_modules=MagicMock(),
@@ -178,6 +182,7 @@ def test_main_reload_conf(mocker, default_conf, caplog) -> None:
def test_reconfigure(mocker, default_conf) -> None:
""" Test recreate() function """
patch_exchange(mocker)
mocker.patch.multiple(
'freqtrade.freqtradebot.FreqtradeBot',
_init_modules=MagicMock(),

View File

@@ -14,9 +14,7 @@ def init_persistence(default_conf):
init(default_conf)
def test_init_create_session(default_conf, mocker):
mocker.patch.dict('freqtrade.persistence._CONF', default_conf)
def test_init_create_session(default_conf):
# Check if init create a session
init(default_conf)
assert hasattr(Trade, 'session')
@@ -29,20 +27,17 @@ def test_init_custom_db_url(default_conf, mocker):
# Update path to a value other than default, but still in-memory
conf.update({'db_url': 'sqlite:///tmp/freqtrade2_test.sqlite'})
create_engine_mock = mocker.patch('freqtrade.persistence.create_engine', MagicMock())
mocker.patch.dict('freqtrade.persistence._CONF', conf)
init(conf)
assert create_engine_mock.call_count == 1
assert create_engine_mock.mock_calls[0][1][0] == 'sqlite:///tmp/freqtrade2_test.sqlite'
def test_init_invalid_db_url(default_conf, mocker):
def test_init_invalid_db_url(default_conf):
conf = deepcopy(default_conf)
# Update path to a value other than default, but still in-memory
conf.update({'db_url': 'unknown:///some.url'})
mocker.patch.dict('freqtrade.persistence._CONF', conf)
with pytest.raises(OperationalException, match=r'.*no valid database URL*'):
init(conf)
@@ -53,7 +48,6 @@ def test_init_prod_db(default_conf, mocker):
conf.update({'db_url': constants.DEFAULT_DB_PROD_URL})
create_engine_mock = mocker.patch('freqtrade.persistence.create_engine', MagicMock())
mocker.patch.dict('freqtrade.persistence._CONF', conf)
init(conf)
assert create_engine_mock.call_count == 1
@@ -66,7 +60,6 @@ def test_init_dryrun_db(default_conf, mocker):
conf.update({'db_url': constants.DEFAULT_DB_DRYRUN_URL})
create_engine_mock = mocker.patch('freqtrade.persistence.create_engine', MagicMock())
mocker.patch.dict('freqtrade.persistence._CONF', conf)
init(conf)
assert create_engine_mock.call_count == 1