[1/3] Add support for multiple exchanges with ccxt (objectified version) (#585)

* remove obsolete helper functions and make _state a public member.

* remove function assertions

* revert worker() changes

* Update pytest from 3.4.2 to 3.5.0

* Adapt exchange functions to ccxt API
Remove get_market_summaries and get_wallet_health, add exception handling

* Add NetworkException

* Change pair format in constants.py

* Add tests for exchange functions that comply with ccxt

* Remove bittrex tests

* Remove Bittrex and Interface classes

* Add retrier decorator

* Remove cache from get_ticker

* Remove unused and duplicate imports

* Add keyword arguments for get_fee

* Implement 'get_pair_detail_url'

* Change get_ticker_history format to ccxt format

* Fix exchange urls dict, don't need to initialize exchanges

* Add "Using Exchange ..." logging line
This commit is contained in:
enenn
2018-04-06 09:57:08 +02:00
committed by Samuel Husso
parent f3847a3a9a
commit 1f75636e56
12 changed files with 586 additions and 486 deletions

View File

@@ -41,12 +41,12 @@ def test_rpc_trade_status(default_conf, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
rpc = RPC(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
(error, result) = rpc.rpc_trade_status()
assert error
assert 'trader is not running' in result
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
(error, result) = rpc.rpc_trade_status()
assert error
assert 'no active trade' in result
@@ -89,12 +89,12 @@ def test_rpc_status_table(default_conf, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
rpc = RPC(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
(error, result) = rpc.rpc_status_table()
assert error
assert '*Status:* `trader is not running`' in result
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
(error, result) = rpc.rpc_status_table()
assert error
assert '*Status:* `no active order`' in result
@@ -344,17 +344,17 @@ def test_rpc_start(mocker, default_conf) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
rpc = RPC(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
(error, result) = rpc.rpc_start()
assert not error
assert '`Starting trader ...`' in result
assert freqtradebot.get_state() == State.RUNNING
assert freqtradebot.state == State.RUNNING
(error, result) = rpc.rpc_start()
assert error
assert '*Status:* `already running`' in result
assert freqtradebot.get_state() == State.RUNNING
assert freqtradebot.state == State.RUNNING
def test_rpc_stop(mocker, default_conf) -> None:
@@ -372,17 +372,17 @@ def test_rpc_stop(mocker, default_conf) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
rpc = RPC(freqtradebot)
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
(error, result) = rpc.rpc_stop()
assert not error
assert '`Stopping trader ...`' in result
assert freqtradebot.get_state() == State.STOPPED
assert freqtradebot.state == State.STOPPED
(error, result) = rpc.rpc_stop()
assert error
assert '*Status:* `already stopped`' in result
assert freqtradebot.get_state() == State.STOPPED
assert freqtradebot.state == State.STOPPED
def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
@@ -410,12 +410,12 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
rpc = RPC(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
(error, res) = rpc.rpc_forcesell(None)
assert error
assert res == '`trader is not running`'
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
(error, res) = rpc.rpc_forcesell(None)
assert error
assert res == 'Invalid argument.'
@@ -433,7 +433,7 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
assert not error
assert res == ''
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
(error, res) = rpc.rpc_forcesell(None)
assert error
assert res == '`trader is not running`'
@@ -442,7 +442,7 @@ def test_rpc_forcesell(default_conf, ticker, mocker) -> None:
assert error
assert res == '`trader is not running`'
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
assert cancel_order_mock.call_count == 0
# make an limit-buy open trade
mocker.patch(

View File

@@ -302,13 +302,13 @@ def test_status_handle(default_conf, update, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
telegram._status(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'trader is not running' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
telegram._status(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'no active trade' in msg_mock.call_args_list[0][0][0]
@@ -348,13 +348,13 @@ def test_status_table_handle(default_conf, update, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
telegram._status_table(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'trader is not running' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
telegram._status_table(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'no active order' in msg_mock.call_args_list[0][0][0]
@@ -472,7 +472,7 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
# Try invalid data
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
update.message.text = '/daily -2'
telegram._daily(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
@@ -480,7 +480,7 @@ def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
# Try invalid data
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
update.message.text = '/daily today'
telegram._daily(bot=MagicMock(), update=update)
assert str('Daily Profit over the last 7 days') in msg_mock.call_args_list[0][0][0]
@@ -667,10 +667,10 @@ def test_start_handle(default_conf, update, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.STOPPED)
assert freqtradebot.get_state() == State.STOPPED
freqtradebot.state = State.STOPPED
assert freqtradebot.state == State.STOPPED
telegram._start(bot=MagicMock(), update=update)
assert freqtradebot.get_state() == State.RUNNING
assert freqtradebot.state == State.RUNNING
assert msg_mock.call_count == 0
@@ -691,10 +691,10 @@ def test_start_handle_already_running(default_conf, update, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.RUNNING)
assert freqtradebot.get_state() == State.RUNNING
freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING
telegram._start(bot=MagicMock(), update=update)
assert freqtradebot.get_state() == State.RUNNING
assert freqtradebot.state == State.RUNNING
assert msg_mock.call_count == 1
assert 'already running' in msg_mock.call_args_list[0][0][0]
@@ -716,10 +716,10 @@ def test_stop_handle(default_conf, update, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.RUNNING)
assert freqtradebot.get_state() == State.RUNNING
freqtradebot.state = State.RUNNING
assert freqtradebot.state == State.RUNNING
telegram._stop(bot=MagicMock(), update=update)
assert freqtradebot.get_state() == State.STOPPED
assert freqtradebot.state == State.STOPPED
assert msg_mock.call_count == 1
assert 'Stopping trader' in msg_mock.call_args_list[0][0][0]
@@ -741,10 +741,10 @@ def test_stop_handle_already_stopped(default_conf, update, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.STOPPED)
assert freqtradebot.get_state() == State.STOPPED
freqtradebot.state = State.STOPPED
assert freqtradebot.state == State.STOPPED
telegram._stop(bot=MagicMock(), update=update)
assert freqtradebot.get_state() == State.STOPPED
assert freqtradebot.state == State.STOPPED
assert msg_mock.call_count == 1
assert 'already stopped' in msg_mock.call_args_list[0][0][0]
@@ -884,7 +884,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot)
# Trader is not running
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
update.message.text = '/forcesell 1'
telegram._forcesell(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
@@ -892,7 +892,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
# No argument
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
update.message.text = '/forcesell'
telegram._forcesell(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
@@ -900,7 +900,7 @@ def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:
# Invalid argument
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
update.message.text = '/forcesell 123456'
telegram._forcesell(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
@@ -965,7 +965,7 @@ def test_performance_handle_invalid(default_conf, update, mocker) -> None:
telegram = Telegram(freqtradebot)
# Trader is not running
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
telegram._performance(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'not running' in msg_mock.call_args_list[0][0][0]
@@ -992,12 +992,12 @@ def test_count_handle(default_conf, update, ticker, mocker) -> None:
freqtradebot = FreqtradeBot(default_conf, create_engine('sqlite://'))
telegram = Telegram(freqtradebot)
freqtradebot.update_state(State.STOPPED)
freqtradebot.state = State.STOPPED
telegram._count(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1
assert 'not running' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock()
freqtradebot.update_state(State.RUNNING)
freqtradebot.state = State.RUNNING
# Create some test data
freqtradebot.create_trade()