Replace 'get_wallet_health' and 'get_markets_summaries'

Both are now covered by 'get_markets'
This commit is contained in:
enenn 2018-03-25 21:51:41 +02:00
parent eac3c4b72c
commit 0b71f7186c
4 changed files with 100 additions and 125 deletions

View File

@ -192,42 +192,44 @@ class FreqtradeBot(object):
:param key: sort key (defaults to 'BaseVolume') :param key: sort key (defaults to 'BaseVolume')
:return: List of pairs :return: List of pairs
""" """
summaries = sorted( pairs = sorted(
(v for s, v in exchange.get_market_summaries().items() if v['symbol'].endswith(base_currency)), [s['symbol'] for s in exchange.get_markets() if s['quote'] == base_currency],
key=lambda v: v.get('info').get(key) or 0.0,
reverse=True reverse=True
) )
return [s['symbol'] for s in summaries] return pairs
def _refresh_whitelist(self, whitelist: List[str]) -> List[str]: def _refresh_whitelist(self, whitelist: List[str]) -> List[str]:
""" """
Check wallet health and remove pair from whitelist if necessary Check available markets and remove pair from whitelist if necessary
:param whitelist: the sorted list (based on BaseVolume) of pairs the user might want to :param whitelist: the sorted list (based on BaseVolume) of pairs the user might want to
trade trade
:return: the list of pairs the user wants to trade without the one unavailable or :return: the list of pairs the user wants to trade without the one unavailable or
black_listed black_listed
""" """
sanitized_whitelist = whitelist sanitized_whitelist = whitelist
health = exchange.get_wallet_health() markets = exchange.get_markets()
markets = [m for m in markets if m['quote'] == self.config['stake_currency']]
known_pairs = set() known_pairs = set()
for symbol, status in health.items(): for market in markets:
pair = f"{status['base']}/{self.config['stake_currency']}" pair = market['symbol']
# pair is not int the generated dynamic market, or in the blacklist ... ignore it # pair is not int the generated dynamic market, or in the blacklist ... ignore it
if pair not in whitelist or pair in self.config['exchange'].get('pair_blacklist', []): if pair not in whitelist or pair in self.config['exchange'].get('pair_blacklist', []):
continue continue
# else the pair is valid # else the pair is valid
known_pairs.add(pair) known_pairs.add(pair)
# Market is not active # Market is not active
if not status['active']: if not market['active']:
sanitized_whitelist.remove(pair) sanitized_whitelist.remove(pair)
self.logger.info( self.logger.info(
'Ignoring %s from whitelist (reason: %s).', 'Ignoring %s from whitelist. Market is not active.',
pair, status.get('Notice') or 'wallet is not active' pair
) )
# We need to remove pairs that are unknown # We need to remove pairs that are unknown
final_list = [x for x in sanitized_whitelist if x in known_pairs] final_list = [x for x in sanitized_whitelist if x in known_pairs]
return final_list return final_list
def get_target_bid(self, ticker: Dict[str, float]) -> float: def get_target_bid(self, ticker: Dict[str, float]) -> float:

View File

@ -127,32 +127,80 @@ def ticker_sell_down():
@pytest.fixture @pytest.fixture
def health(): def markets():
return MagicMock(return_value={ return MagicMock(return_value=[
"ETH/BTC": { {
'id': 'ethbtc',
'symbol': 'ETH/BTC',
'base': 'ETH', 'base': 'ETH',
'quote': 'BTC',
'active': True, 'active': True,
'LastChecked': '2017-11-13T20:15:00.00', 'precision': {
'Notice': None 'price': 8,
'amount': 8,
'cost': 8,
}, },
"TRST/BTC": { 'lot': 0.00000001,
'base': 'TRST', 'limits': {
'amount': {
'min': 0.01,
'max': 1000,
},
'price': 500000,
'cost': 500000,
},
'info': '',
},
{
'id': 'tknbtc',
'symbol': 'TKN/BTC',
'base': 'TKN',
'quote': 'BTC',
'active': True, 'active': True,
'LastChecked': '2017-11-13T20:15:00.00', 'precision': {
'Notice': None 'price': 8,
'amount': 8,
'cost': 8,
}, },
"SWT/BTC": { 'lot': 0.00000001,
'base': 'SWT', 'limits': {
'amount': {
'min': 0.01,
'max': 1000,
},
'price': 500000,
'cost': 500000,
},
'info': '',
},
{
'id': 'blkbtc',
'symbol': 'BLK/BTC',
'base': 'BLK',
'quote': 'BTC',
'active': True, 'active': True,
'LastChecked': '2017-11-13T20:15:00.00', 'precision': {
'Notice': None 'price': 8,
'amount': 8,
'cost': 8,
}, },
"BCC/BTC": { 'lot': 0.00000001,
'base': 'BCC', 'limits': {
'active': False, 'amount': {
'LastChecked': '2017-11-13T20:15:00.00', 'min': 0.01,
'Notice': None 'max': 1000,
}}) },
'price': 500000,
'cost': 500000,
},
'info': '',
}
])
@pytest.fixture
def markets_empty():
return MagicMock(return_value=[])
@pytest.fixture @pytest.fixture
@ -334,3 +382,4 @@ def result():
# that inserts a trade of some type and open-status # that inserts a trade of some type and open-status
# return the open-order-id # return the open-order-id
# See tests in rpc/main that could use this # See tests in rpc/main that could use this

View File

@ -26,81 +26,12 @@ def whitelist_conf():
return config return config
def get_market_summaries(): def test_refresh_market_pair_not_in_whitelist(mocker, markets):
return {
'TKN/BTC': {
'symbol': 'TKN/BTC',
'info': {
'High': 0.00000919,
'Low': 0.00000820,
'Volume': 74339.61396015,
'Last': 0.00000820,
'BaseVolume': 1664,
'TimeStamp': '2014-07-09T07:19:30.15',
'Bid': 0.00000820,
'Ask': 0.00000831,
'OpenBuyOrders': 15,
'OpenSellOrders': 15,
'PrevDay': 0.00000821,
'Created': '2014-03-20T06:00:00',
'DisplayMarketName': ''
}
},
'ETH/BTC': {
'symbol': 'ETH/BTC',
'info': {
'High': 0.00000072,
'Low': 0.00000001,
'Volume': 166340678.42280999,
'Last': 0.00000005,
'BaseVolume': 42,
'TimeStamp': '2014-07-09T07:21:40.51',
'Bid': 0.00000004,
'Ask': 0.00000005,
'OpenBuyOrders': 18,
'OpenSellOrders': 18,
'PrevDay': 0.00000002,
'Created': '2014-05-30T07:57:49.637',
'DisplayMarketName': ''
}
},
'BLK/BTC': {
'symbol': 'BLK/BTC',
'info': {
'High': 0.00000072,
'Low': 0.00000001,
'Volume': 166340678.42280999,
'Last': 0.00000005,
'BaseVolume': 3,
'TimeStamp': '2014-07-09T07:21:40.51',
'Bid': 0.00000004,
'Ask': 0.00000005,
'OpenBuyOrders': 18,
'OpenSellOrders': 18,
'PrevDay': 0.00000002,
'Created': '2014-05-30T07:57:49.637',
'DisplayMarketName': ''
}}
}
def get_health():
return {
'ETH/BTC': {'base': 'ETH', 'active': True},
'TKN/BTC': {'base': 'TKN', 'active': True},
'BLK/BTC': {'base': 'BLK', 'active': True}}
def get_health_empty():
return {}
def test_refresh_market_pair_not_in_whitelist(mocker):
conf = whitelist_conf() conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf) freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_wallet_health', get_health) mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
refreshedwhitelist = freqtradebot._refresh_whitelist( refreshedwhitelist = freqtradebot._refresh_whitelist(
conf['exchange']['pair_whitelist'] + ['XXX/BTC'] conf['exchange']['pair_whitelist'] + ['XXX/BTC']
) )
@ -110,11 +41,11 @@ def test_refresh_market_pair_not_in_whitelist(mocker):
assert whitelist == refreshedwhitelist assert whitelist == refreshedwhitelist
def test_refresh_whitelist(mocker): def test_refresh_whitelist(mocker, markets):
conf = whitelist_conf() conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf) freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_wallet_health', get_health) mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
refreshedwhitelist = freqtradebot._refresh_whitelist(conf['exchange']['pair_whitelist']) refreshedwhitelist = freqtradebot._refresh_whitelist(conf['exchange']['pair_whitelist'])
# List ordered by BaseVolume # List ordered by BaseVolume
@ -123,14 +54,10 @@ def test_refresh_whitelist(mocker):
assert whitelist == refreshedwhitelist assert whitelist == refreshedwhitelist
def test_refresh_whitelist_dynamic(mocker): def test_refresh_whitelist_dynamic(mocker, markets):
conf = whitelist_conf() conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf) freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch.multiple( mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
'freqtrade.freqtradebot.exchange',
get_wallet_health=get_health,
get_market_summaries=get_market_summaries
)
# argument: use the whitelist dynamically by exchange-volume # argument: use the whitelist dynamically by exchange-volume
whitelist = ['TKN/BTC', 'ETH/BTC'] whitelist = ['TKN/BTC', 'ETH/BTC']
@ -142,10 +69,10 @@ def test_refresh_whitelist_dynamic(mocker):
assert whitelist == refreshedwhitelist assert whitelist == refreshedwhitelist
def test_refresh_whitelist_dynamic_empty(mocker): def test_refresh_whitelist_dynamic_empty(mocker, markets_empty):
conf = whitelist_conf() conf = whitelist_conf()
freqtradebot = tt.get_patched_freqtradebot(mocker, conf) freqtradebot = tt.get_patched_freqtradebot(mocker, conf)
mocker.patch('freqtrade.freqtradebot.exchange.get_wallet_health', get_health_empty) mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets_empty)
# argument: use the whitelist dynamically by exchange-volume # argument: use the whitelist dynamically by exchange-volume
whitelist = [] whitelist = []

View File

@ -201,15 +201,12 @@ def test_throttle_with_assets(mocker, default_conf) -> None:
assert result == -1 assert result == -1
def test_gen_pair_whitelist(mocker, default_conf, get_market_summaries_data) -> None: def test_gen_pair_whitelist(mocker, default_conf, markets) -> None:
""" """
Test _gen_pair_whitelist() method Test _gen_pair_whitelist() method
""" """
freqtrade = get_patched_freqtradebot(mocker, default_conf) freqtrade = get_patched_freqtradebot(mocker, default_conf)
mocker.patch( mocker.patch('freqtrade.freqtradebot.exchange.get_markets', markets)
'freqtrade.freqtradebot.exchange.get_market_summaries',
return_value=get_market_summaries_data
)
# Test to retrieved BTC sorted on BaseVolume # Test to retrieved BTC sorted on BaseVolume
whitelist = freqtrade._gen_pair_whitelist(base_currency='BTC') whitelist = freqtrade._gen_pair_whitelist(base_currency='BTC')
@ -392,7 +389,7 @@ def test_create_trade_no_signal(default_conf, mocker) -> None:
def test_process_trade_creation(default_conf, ticker, limit_buy_order, def test_process_trade_creation(default_conf, ticker, limit_buy_order,
health, mocker, caplog) -> None: markets, mocker, caplog) -> None:
""" """
Test the trade creation in _process() method Test the trade creation in _process() method
""" """
@ -403,7 +400,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order,
'freqtrade.freqtradebot.exchange', 'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(), validate_pairs=MagicMock(),
get_ticker=ticker, get_ticker=ticker,
get_wallet_health=health, get_markets=markets,
buy=MagicMock(return_value='mocked_limit_buy'), buy=MagicMock(return_value='mocked_limit_buy'),
get_order=MagicMock(return_value=limit_buy_order) get_order=MagicMock(return_value=limit_buy_order)
) )
@ -432,7 +429,7 @@ def test_process_trade_creation(default_conf, ticker, limit_buy_order,
) )
def test_process_exchange_failures(default_conf, ticker, health, mocker) -> None: def test_process_exchange_failures(default_conf, ticker, markets, mocker) -> None:
""" """
Test _process() method when a RequestException happens Test _process() method when a RequestException happens
""" """
@ -443,7 +440,7 @@ def test_process_exchange_failures(default_conf, ticker, health, mocker) -> None
'freqtrade.freqtradebot.exchange', 'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(), validate_pairs=MagicMock(),
get_ticker=ticker, get_ticker=ticker,
get_wallet_health=health, get_markets=markets,
buy=MagicMock(side_effect=requests.exceptions.RequestException) buy=MagicMock(side_effect=requests.exceptions.RequestException)
) )
sleep_mock = mocker.patch('time.sleep', side_effect=lambda _: None) sleep_mock = mocker.patch('time.sleep', side_effect=lambda _: None)
@ -454,7 +451,7 @@ def test_process_exchange_failures(default_conf, ticker, health, mocker) -> None
assert sleep_mock.has_calls() assert sleep_mock.has_calls()
def test_process_operational_exception(default_conf, ticker, health, mocker) -> None: def test_process_operational_exception(default_conf, ticker, markets, mocker) -> None:
""" """
Test _process() method when an OperationalException happens Test _process() method when an OperationalException happens
""" """
@ -465,7 +462,7 @@ def test_process_operational_exception(default_conf, ticker, health, mocker) ->
'freqtrade.freqtradebot.exchange', 'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(), validate_pairs=MagicMock(),
get_ticker=ticker, get_ticker=ticker,
get_wallet_health=health, get_markets=markets,
buy=MagicMock(side_effect=OperationalException) buy=MagicMock(side_effect=OperationalException)
) )
freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://')) freqtrade = FreqtradeBot(default_conf, create_engine('sqlite://'))
@ -477,7 +474,7 @@ def test_process_operational_exception(default_conf, ticker, health, mocker) ->
assert 'OperationalException' in msg_mock.call_args_list[-1][0][0] assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]
def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, mocker) -> None: def test_process_trade_handling(default_conf, ticker, limit_buy_order, markets, mocker) -> None:
""" """
Test _process() Test _process()
""" """
@ -488,7 +485,7 @@ def test_process_trade_handling(default_conf, ticker, limit_buy_order, health, m
'freqtrade.freqtradebot.exchange', 'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(), validate_pairs=MagicMock(),
get_ticker=ticker, get_ticker=ticker,
get_wallet_health=health, get_markets=markets,
buy=MagicMock(return_value='mocked_limit_buy'), buy=MagicMock(return_value='mocked_limit_buy'),
get_order=MagicMock(return_value=limit_buy_order) get_order=MagicMock(return_value=limit_buy_order)
) )