From 1de248fe38af6bc2c4a88183bee53fc48bcce0ef Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 1 Aug 2020 17:49:59 +0200 Subject: [PATCH] add list_available_pairs endpoint --- freqtrade/rpc/api_server.py | 39 ++++++++++++++++++++++++++++++++- tests/conftest.py | 1 + tests/rpc/test_rpc_apiserver.py | 26 ++++++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py index 61081157b..51610bd98 100644 --- a/freqtrade/rpc/api_server.py +++ b/freqtrade/rpc/api_server.py @@ -222,6 +222,8 @@ class ApiServer(RPC): view_func=self._plot_config, methods=['GET']) self.app.add_url_rule(f'{BASE_URI}/strategies', 'strategies', view_func=self._list_strategies, methods=['GET']) + self.app.add_url_rule(f'{BASE_URI}/available_pairs', 'pairs', + view_func=self._list_available_pairs, methods=['GET']) # Combined actions and infos self.app.add_url_rule(f'{BASE_URI}/blacklist', 'blacklist', view_func=self._blacklist, @@ -540,7 +542,7 @@ class ApiServer(RPC): Returns the dataframe of a given timerange Takes the following get arguments: get: - parameters: + parameters: - pair: Pair - timeframe: Timeframe to get data for (should be aligned to strategy.timeframe) - strategy: Strategy to use - Must exist in configured strategy-path! @@ -580,3 +582,38 @@ class ApiServer(RPC): strategy_objs = sorted(strategy_objs, key=lambda x: x['name']) return self.rest_dump({'strategies': [x['name'] for x in strategy_objs]}) + + @require_login + @rpc_catch_errors + def _list_available_pairs(self): + """ + Handler for /available_pairs. + Returns an object, with pairs, available pair length and pair_interval combinations + Takes the following get arguments: + get: + parameters: + - stake_currency: Filter on this stake currency + - timeframe: Timeframe to get data for Filter elements to this timeframe + """ + timeframe = request.args.get("timeframe") + stake_currency = request.args.get("stake_currency") + + from freqtrade.data.history import get_datahandler + dh = get_datahandler(self._config['datadir'], self._config.get('dataformat_ohlcv', None)) + + pair_interval = dh.ohlcv_get_available_data(self._config['datadir']) + + if timeframe: + pair_interval = [pair for pair in pair_interval if pair[1] == timeframe] + if stake_currency: + pair_interval = [pair for pair in pair_interval if pair[0].endswith(stake_currency)] + pair_interval = sorted(pair_interval, key=lambda x: x[0]) + + pairs = list({x[0] for x in pair_interval}) + + result = { + 'length': len(pairs), + 'pairs': pairs, + 'pair_interval': pair_interval, + } + return self.rest_dump(result) diff --git a/tests/conftest.py b/tests/conftest.py index dbd0df8f6..2153fd327 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -146,6 +146,7 @@ def get_patched_freqtradebot(mocker, config) -> FreqtradeBot: :return: FreqtradeBot """ patch_freqtradebot(mocker, config) + config['datadir'] = Path(config['datadir']) return FreqtradeBot(config) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index fbee1cf64..d6c938373 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -878,3 +878,29 @@ def test_api_strategies(botclient): assert_response(rc) assert rc.json == {'strategies': ['DefaultStrategy', 'TestStrategyLegacy']} + + +def test_list_available_pairs(botclient): + ftbot, client = botclient + + rc = client_get(client, f"{BASE_URI}/available_pairs") + + assert_response(rc) + assert rc.json['length'] == 12 + assert isinstance(rc.json['pairs'], list) + + rc = client_get(client, f"{BASE_URI}/available_pairs?timeframe=5m") + assert_response(rc) + assert rc.json['length'] == 12 + + rc = client_get(client, f"{BASE_URI}/available_pairs?stake_currency=ETH") + assert_response(rc) + assert rc.json['length'] == 1 + assert rc.json['pairs'] == ['XRP/ETH'] + assert len(rc.json['pair_interval']) == 2 + + rc = client_get(client, f"{BASE_URI}/available_pairs?stake_currency=ETH&timeframe=5m") + assert_response(rc) + assert rc.json['length'] == 1 + assert rc.json['pairs'] == ['XRP/ETH'] + assert len(rc.json['pair_interval']) == 1