Merge pull request #1927 from hroff-1902/list-exchanges-module
list-exchanges subcommand added
This commit is contained in:
commit
2369161bb0
@ -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:
|
||||||
"""
|
"""
|
||||||
|
@ -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())
|
||||||
|
@ -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):
|
||||||
|
@ -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:
|
||||||
|
@ -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')
|
||||||
|
41
freqtrade/tests/test_utils.py
Normal file
41
freqtrade/tests/test_utils.py
Normal 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
40
freqtrade/utils.py
Normal 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())}")
|
Loading…
Reference in New Issue
Block a user