Merge pull request #1927 from hroff-1902/list-exchanges-module

list-exchanges subcommand added
This commit is contained in:
Matthias 2019-06-16 19:25:23 +02:00 committed by GitHub
commit 2369161bb0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 113 additions and 17 deletions

View File

@ -335,12 +335,25 @@ class Arguments(object):
metavar='INT', metavar='INT',
) )
@staticmethod
def list_exchanges_options(parser: argparse.ArgumentParser) -> None:
"""
Parses given arguments for the list-exchanges command.
"""
parser.add_argument(
'-1', '--one-column',
help='Print exchanges in one column',
action='store_true',
dest='print_one_column',
)
def _build_subcommands(self) -> None: def _build_subcommands(self) -> None:
""" """
Builds and attaches all subcommands Builds and attaches all subcommands
:return: None :return: None
""" """
from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge
from freqtrade.utils import start_list_exchanges
subparsers = self.parser.add_subparsers(dest='subparser') subparsers = self.parser.add_subparsers(dest='subparser')
@ -362,6 +375,14 @@ class Arguments(object):
self.optimizer_shared_options(hyperopt_cmd) self.optimizer_shared_options(hyperopt_cmd)
self.hyperopt_options(hyperopt_cmd) self.hyperopt_options(hyperopt_cmd)
# Add list-exchanges subcommand
list_exchanges_cmd = subparsers.add_parser(
'list-exchanges',
help='Print available exchanges.'
)
list_exchanges_cmd.set_defaults(func=start_list_exchanges)
self.list_exchanges_options(list_exchanges_cmd)
@staticmethod @staticmethod
def parse_timerange(text: Optional[str]) -> TimeRange: def parse_timerange(text: Optional[str]) -> TimeRange:
""" """

View File

@ -5,6 +5,7 @@ import re
from copy import deepcopy from copy import deepcopy
from datetime import datetime from datetime import datetime
from functools import reduce from functools import reduce
from typing import List
from unittest.mock import MagicMock, PropertyMock from unittest.mock import MagicMock, PropertyMock
import arrow import arrow
@ -12,6 +13,7 @@ import pytest
from telegram import Chat, Message, Update from telegram import Chat, Message, Update
from freqtrade import constants, persistence from freqtrade import constants, persistence
from freqtrade.arguments import Arguments
from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.converter import parse_ticker_dataframe
from freqtrade.edge import Edge, PairInfo from freqtrade.edge import Edge, PairInfo
from freqtrade.exchange import Exchange from freqtrade.exchange import Exchange
@ -36,6 +38,10 @@ def log_has_re(line, logs):
False) False)
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
def patch_exchange(mocker, api_mock=None, id='bittrex') -> None: def patch_exchange(mocker, api_mock=None, id='bittrex') -> None:
mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={})) mocker.patch('freqtrade.exchange.Exchange._load_markets', MagicMock(return_value={}))
mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock()) mocker.patch('freqtrade.exchange.Exchange.validate_pairs', MagicMock())

View File

@ -3,7 +3,6 @@
import json import json
import math import math
import random import random
from typing import List
from unittest.mock import MagicMock from unittest.mock import MagicMock
import numpy as np import numpy as np
@ -12,7 +11,7 @@ import pytest
from arrow import Arrow from arrow import Arrow
from freqtrade import DependencyException, constants from freqtrade import DependencyException, constants
from freqtrade.arguments import Arguments, TimeRange from freqtrade.arguments import TimeRange
from freqtrade.data import history from freqtrade.data import history
from freqtrade.data.btanalysis import evaluate_result_multi from freqtrade.data.btanalysis import evaluate_result_multi
from freqtrade.data.converter import parse_ticker_dataframe from freqtrade.data.converter import parse_ticker_dataframe
@ -23,11 +22,7 @@ from freqtrade.optimize.backtesting import Backtesting
from freqtrade.state import RunMode from freqtrade.state import RunMode
from freqtrade.strategy.default_strategy import DefaultStrategy from freqtrade.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import SellType from freqtrade.strategy.interface import SellType
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
def trim_dictlist(dict_list, num): def trim_dictlist(dict_list, num):

View File

@ -2,19 +2,13 @@
# pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments # pragma pylint: disable=protected-access, too-many-lines, invalid-name, too-many-arguments
import json import json
from typing import List
from unittest.mock import MagicMock from unittest.mock import MagicMock
from freqtrade.arguments import Arguments
from freqtrade.edge import PairInfo from freqtrade.edge import PairInfo
from freqtrade.optimize import start_edge, setup_configuration from freqtrade.optimize import setup_configuration, start_edge
from freqtrade.optimize.edge_cli import EdgeCli from freqtrade.optimize.edge_cli import EdgeCli
from freqtrade.state import RunMode from freqtrade.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None: def test_setup_configuration_without_arguments(mocker, default_conf, caplog) -> None:

View File

@ -16,8 +16,7 @@ from freqtrade.optimize.hyperopt import Hyperopt, HYPEROPT_LOCKFILE
from freqtrade.optimize import setup_configuration, start_hyperopt from freqtrade.optimize import setup_configuration, start_hyperopt
from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver from freqtrade.resolvers.hyperopt_resolver import HyperOptResolver
from freqtrade.state import RunMode from freqtrade.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
from freqtrade.tests.optimize.test_backtesting import get_args
@pytest.fixture(scope='function') @pytest.fixture(scope='function')

View File

@ -0,0 +1,41 @@
from freqtrade.utils import setup_configuration, start_list_exchanges
from freqtrade.tests.conftest import get_args
from freqtrade.state import RunMode
import re
def test_setup_configuration():
args = [
'--config', 'config.json.example',
]
config = setup_configuration(get_args(args), RunMode.OTHER)
assert "exchange" in config
assert config['exchange']['key'] == ''
assert config['exchange']['secret'] == ''
def test_list_exchanges(capsys):
args = [
"list-exchanges",
]
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert re.match(r"Exchanges supported by ccxt and available.*", captured.out)
assert re.match(r".*binance,.*", captured.out)
assert re.match(r".*bittrex,.*", captured.out)
# Test with --one-column
args = [
"list-exchanges",
"--one-column",
]
start_list_exchanges(get_args(args))
captured = capsys.readouterr()
assert not re.match(r"Exchanges supported by ccxt and available.*", captured.out)
assert re.search(r"^binance$", captured.out, re.MULTILINE)
assert re.search(r"^bittrex$", captured.out, re.MULTILINE)

40
freqtrade/utils.py Normal file
View File

@ -0,0 +1,40 @@
import logging
from argparse import Namespace
from typing import Any, Dict
from freqtrade.configuration import Configuration
from freqtrade.exchange import available_exchanges
from freqtrade.state import RunMode
logger = logging.getLogger(__name__)
def setup_configuration(args: Namespace, method: RunMode) -> Dict[str, Any]:
"""
Prepare the configuration for the Hyperopt module
:param args: Cli args from Arguments()
:return: Configuration
"""
configuration = Configuration(args, method)
config = configuration.load_config()
# Ensure we do not use Exchange credentials
config['exchange']['key'] = ''
config['exchange']['secret'] = ''
return config
def start_list_exchanges(args: Namespace) -> None:
"""
Print available exchanges
:param args: Cli args from Arguments()
:return: None
"""
if args.print_one_column:
print('\n'.join(available_exchanges()))
else:
print(f"Exchanges supported by ccxt and available for Freqtrade: "
f"{', '.join(available_exchanges())}")