add test and fix exchange_resolver
This commit is contained in:
parent
eed1c2344d
commit
481cf02db9
1
.gitignore
vendored
1
.gitignore
vendored
@ -81,6 +81,7 @@ target/
|
|||||||
|
|
||||||
# Jupyter Notebook
|
# Jupyter Notebook
|
||||||
.ipynb_checkpoints
|
.ipynb_checkpoints
|
||||||
|
*.ipynb
|
||||||
|
|
||||||
# pyenv
|
# pyenv
|
||||||
.python-version
|
.python-version
|
||||||
|
@ -56,7 +56,7 @@ class FreqtradeBot(object):
|
|||||||
|
|
||||||
self.rpc: RPCManager = RPCManager(self)
|
self.rpc: RPCManager = RPCManager(self)
|
||||||
|
|
||||||
exchange_name = self.config.get('exchange', {}).get('name', 'bittrex')
|
exchange_name = self.config.get('exchange', {}).get('name', 'bittrex').title()
|
||||||
try:
|
try:
|
||||||
self.exchange = ExchangeResolver(exchange_name, self.config).exchange
|
self.exchange = ExchangeResolver(exchange_name, self.config).exchange
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -32,23 +32,17 @@ class ExchangeResolver(IResolver):
|
|||||||
:param extra_dir: additional directory to search for the given exchange
|
:param extra_dir: additional directory to search for the given exchange
|
||||||
:return: Exchange instance or None
|
:return: Exchange instance or None
|
||||||
"""
|
"""
|
||||||
current_path = Path(__file__).parent.parent.joinpath('exchange').resolve()
|
abs_path = Path(__file__).parent.parent.joinpath('exchange').resolve()
|
||||||
|
|
||||||
abs_paths = [
|
|
||||||
current_path.parent.parent.joinpath('user_data/exchange'),
|
|
||||||
current_path,
|
|
||||||
]
|
|
||||||
|
|
||||||
for _path in abs_paths:
|
|
||||||
try:
|
try:
|
||||||
exchange = self._search_object(directory=_path, object_type=Exchange,
|
exchange = self._search_object(directory=abs_path, object_type=Exchange,
|
||||||
object_name=exchange_name,
|
object_name=exchange_name,
|
||||||
kwargs=kwargs)
|
kwargs=kwargs)
|
||||||
if exchange:
|
if exchange:
|
||||||
logger.info('Using resolved exchange %s from \'%s\'', exchange_name, _path)
|
logger.info('Using resolved exchange %s from \'%s\'', exchange_name, abs_path)
|
||||||
return exchange
|
return exchange
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
logger.warning('Path "%s" does not exist', _path.relative_to(Path.cwd()))
|
logger.warning('Path "%s" does not exist', abs_path.relative_to(Path.cwd()))
|
||||||
|
|
||||||
raise ImportError(
|
raise ImportError(
|
||||||
"Impossible to load Exchange '{}'. This class does not exist"
|
"Impossible to load Exchange '{}'. This class does not exist"
|
||||||
|
@ -16,6 +16,7 @@ from freqtrade.data.converter import parse_ticker_dataframe
|
|||||||
from freqtrade.exchange import Exchange
|
from freqtrade.exchange import Exchange
|
||||||
from freqtrade.edge import Edge, PairInfo
|
from freqtrade.edge import Edge, PairInfo
|
||||||
from freqtrade.freqtradebot import FreqtradeBot
|
from freqtrade.freqtradebot import FreqtradeBot
|
||||||
|
from freqtrade.resolvers import ExchangeResolver
|
||||||
|
|
||||||
logging.getLogger('').setLevel(logging.INFO)
|
logging.getLogger('').setLevel(logging.INFO)
|
||||||
|
|
||||||
@ -49,6 +50,10 @@ def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
|
|||||||
|
|
||||||
def get_patched_exchange(mocker, config, api_mock=None, id='bittrex') -> Exchange:
|
def get_patched_exchange(mocker, config, api_mock=None, id='bittrex') -> Exchange:
|
||||||
patch_exchange(mocker, api_mock, id)
|
patch_exchange(mocker, api_mock, id)
|
||||||
|
config["exchange"]["name"] = id
|
||||||
|
try:
|
||||||
|
exchange = ExchangeResolver(id.title(), config).exchange
|
||||||
|
except ImportError:
|
||||||
exchange = Exchange(config)
|
exchange = Exchange(config)
|
||||||
return exchange
|
return exchange
|
||||||
|
|
||||||
|
@ -531,6 +531,38 @@ def test_buy_considers_time_in_force(default_conf, mocker):
|
|||||||
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc'}
|
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc'}
|
||||||
|
|
||||||
|
|
||||||
|
def test_buy_kraken_trading_agreement(default_conf, mocker):
|
||||||
|
api_mock = MagicMock()
|
||||||
|
order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6))
|
||||||
|
order_type = 'market'
|
||||||
|
time_in_force = 'ioc'
|
||||||
|
api_mock.create_order = MagicMock(return_value={
|
||||||
|
'id': order_id,
|
||||||
|
'info': {
|
||||||
|
'foo': 'bar'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
default_conf['dry_run'] = False
|
||||||
|
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y)
|
||||||
|
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||||
|
|
||||||
|
order = exchange.buy(pair='ETH/BTC', ordertype=order_type,
|
||||||
|
amount=1, rate=200, time_in_force=time_in_force)
|
||||||
|
|
||||||
|
assert 'id' in order
|
||||||
|
assert 'info' in order
|
||||||
|
assert order['id'] == order_id
|
||||||
|
assert api_mock.create_order.call_args[0][0] == 'ETH/BTC'
|
||||||
|
assert api_mock.create_order.call_args[0][1] == order_type
|
||||||
|
assert api_mock.create_order.call_args[0][2] == 'buy'
|
||||||
|
assert api_mock.create_order.call_args[0][3] == 1
|
||||||
|
assert api_mock.create_order.call_args[0][4] is None
|
||||||
|
assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc',
|
||||||
|
'trading_agreement': 'agree'}
|
||||||
|
|
||||||
|
|
||||||
def test_sell_dry_run(default_conf, mocker):
|
def test_sell_dry_run(default_conf, mocker):
|
||||||
default_conf['dry_run'] = True
|
default_conf['dry_run'] = True
|
||||||
exchange = get_patched_exchange(mocker, default_conf)
|
exchange = get_patched_exchange(mocker, default_conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user