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',
)
@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:
"""
Builds and attaches all subcommands
:return: None
"""
from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge
from freqtrade.utils import start_list_exchanges
subparsers = self.parser.add_subparsers(dest='subparser')
@ -362,6 +375,14 @@ class Arguments(object):
self.optimizer_shared_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
def parse_timerange(text: Optional[str]) -> TimeRange:
"""

View File

@ -5,6 +5,7 @@ import re
from copy import deepcopy
from datetime import datetime
from functools import reduce
from typing import List
from unittest.mock import MagicMock, PropertyMock
import arrow
@ -12,6 +13,7 @@ import pytest
from telegram import Chat, Message, Update
from freqtrade import constants, persistence
from freqtrade.arguments import Arguments
from freqtrade.data.converter import parse_ticker_dataframe
from freqtrade.edge import Edge, PairInfo
from freqtrade.exchange import Exchange
@ -36,6 +38,10 @@ def log_has_re(line, logs):
False)
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
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.validate_pairs', MagicMock())

View File

@ -3,7 +3,6 @@
import json
import math
import random
from typing import List
from unittest.mock import MagicMock
import numpy as np
@ -12,7 +11,7 @@ import pytest
from arrow import Arrow
from freqtrade import DependencyException, constants
from freqtrade.arguments import Arguments, TimeRange
from freqtrade.arguments import TimeRange
from freqtrade.data import history
from freqtrade.data.btanalysis import evaluate_result_multi
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.strategy.default_strategy import DefaultStrategy
from freqtrade.strategy.interface import SellType
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
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
import json
from typing import List
from unittest.mock import MagicMock
from freqtrade.arguments import Arguments
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.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange
def get_args(args) -> List[str]:
return Arguments(args, '').get_parsed_arg()
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
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.resolvers.hyperopt_resolver import HyperOptResolver
from freqtrade.state import RunMode
from freqtrade.tests.conftest import log_has, log_has_re, patch_exchange
from freqtrade.tests.optimize.test_backtesting import get_args
from freqtrade.tests.conftest import get_args, log_has, log_has_re, patch_exchange
@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())}")