list-pairs, list-markets subcommands

This commit is contained in:
hroff-1902 2019-07-01 14:36:42 +03:00
parent 4823656028
commit dbdeab4639
4 changed files with 115 additions and 5 deletions

View File

@ -5,7 +5,9 @@ This module contains the argument manager class
import argparse
import os
import re
from functools import partial
from typing import List, NamedTuple, Optional
import arrow
from freqtrade import __version__, constants
@ -255,6 +257,26 @@ AVAILABLE_CLI_OPTIONS = {
action='store_true',
dest='print_one_column',
),
# List pairs / markets
"print_list": Arg(
'--print-list',
help='Print list of pairs or market symbols. By default data is'
'printed in the tabular format.',
action='store_true',
),
"quote_currency": Arg(
'--quote-currency',
help='Select quote currency.',
),
"base_currency": Arg(
'--base-currency',
help='Select base currency.',
),
"active_only": Arg(
'--active-only',
help='Print only active pairs or markets.',
action='store_true',
),
# Common script options
"pairs": Arg(
'-p', '--pairs',
@ -346,9 +368,11 @@ ARGS_HYPEROPT = ARGS_COMMON_OPTIMIZE + ["hyperopt", "position_stacking", "epochs
ARGS_EDGE = ARGS_COMMON_OPTIMIZE + ["stoploss_range"]
ARGS_LIST_EXCHANGE = ["print_one_column"]
ARGS_LIST_PAIRS = ARGS_COMMON + ["exchange", "print_list", "base_currency", "quote_currency",
"active_only"]
ARGS_DOWNLOADER = ARGS_COMMON + ["pairs", "pairs_file", "days", "exchange", "timeframes", "erase"]
ARGS_PLOT_DATAFRAME = (ARGS_COMMON + ARGS_STRATEGY +
@ -422,7 +446,7 @@ class Arguments(object):
:return: None
"""
from freqtrade.optimize import start_backtesting, start_hyperopt, start_edge
from freqtrade.utils import start_list_exchanges
from freqtrade.utils import start_list_exchanges, start_list_pairs
subparsers = self.parser.add_subparsers(dest='subparser')
@ -443,12 +467,29 @@ class Arguments(object):
# Add list-exchanges subcommand
list_exchanges_cmd = subparsers.add_parser(
'list-exchanges',
help='Print available exchanges.'
'list-exchanges',
help='Print available exchanges.'
)
list_exchanges_cmd.set_defaults(func=start_list_exchanges)
self.build_args(optionlist=ARGS_LIST_EXCHANGE, parser=list_exchanges_cmd)
# Add list-markets subcommand
list_markets_cmd = subparsers.add_parser(
'list-markets',
help='Print markets on exchange.'
)
list_markets_cmd.set_defaults(func=partial(start_list_pairs, pairs_only=False))
self.build_args(optionlist=ARGS_LIST_PAIRS, parser=list_markets_cmd)
# Add list-pairs subcommand
list_pairs_cmd = subparsers.add_parser(
'list-pairs',
help='Print pairs on exchange.'
)
list_pairs_cmd.set_defaults(func=partial(start_list_pairs, pairs_only=True))
self.build_args(optionlist=ARGS_LIST_PAIRS, parser=list_pairs_cmd)
@staticmethod
def parse_timerange(text: Optional[str]) -> TimeRange:
"""

View File

@ -196,6 +196,23 @@ class Exchange(object):
self._load_markets()
return self._api.markets
def get_markets(self, base_currency: str = None, quote_currency: str = None,
pairs_only: bool = False, active_only: bool = False) -> Dict:
"""
Return exchange ccxt markets, filtered out by base currency and quote currency
if this was requested in parameters.
"""
markets = self.markets
if base_currency:
markets = {k: v for k, v in markets.items() if v['base'] == base_currency}
if quote_currency:
markets = {k: v for k, v in markets.items() if v['quote'] == quote_currency}
if pairs_only:
markets = {k: v for k, v in markets.items() if '/' in v['symbol']}
if active_only:
markets = {k: v for k, v in markets.items() if v['active']}
return markets
def klines(self, pair_interval: Tuple[str, str], copy=True) -> DataFrame:
if pair_interval in self._klines:
return self._klines[pair_interval].copy() if copy else self._klines[pair_interval]

View File

@ -133,3 +133,6 @@ def deep_merge_dicts(source, destination):
destination[key] = value
return destination
def plural(num, singular: str, plural: str = None) -> str:
return singular if (num == 1 or num == -1) else plural or singular + 's'

View File

@ -3,9 +3,12 @@ from argparse import Namespace
from typing import Any, Dict
from freqtrade.configuration import Configuration
from freqtrade.exchange import available_exchanges
from freqtrade.exchange import available_exchanges, Exchange
from freqtrade.misc import plural
from freqtrade.state import RunMode
from tabulate import tabulate
logger = logging.getLogger(__name__)
@ -39,3 +42,49 @@ def start_list_exchanges(args: Namespace) -> None:
else:
print(f"Exchanges supported by ccxt and available for Freqtrade: "
f"{', '.join(available_exchanges())}")
def start_list_pairs(args: Namespace, pairs_only: bool = False) -> None:
"""
Print pairs on the exchange
:param args: Cli args from Arguments()
:return: None
"""
# Initialize configuration
config = setup_utils_configuration(args, RunMode.OTHER)
# Fetch exchange name from args, use bittrex as default exchange
config['exchange']['name'] = args.exchange or 'bittrex'
# Init exchange
exchange = Exchange(config)
logger.debug(f"Exchange markets: {exchange.markets}")
pairs = exchange.get_markets(base_currency=args.base_currency,
quote_currency=args.quote_currency,
pairs_only=pairs_only,
active_only=args.active_only)
if args.print_list:
# print data as a list
print(f"Exchange {exchange.name} has {len(pairs)} " +
(plural(len(pairs), "pair" if pairs_only else "market")) +
(f" with {args.base_currency} as base currency" if args.base_currency else "") +
(" and" if args.base_currency and args.quote_currency else "") +
(f" with {args.quote_currency} as quote currency" if args.quote_currency else "") +
(f": {sorted(pairs.keys())}" if len(pairs) else "") + ".")
else:
# # print a table of pairs (markets)
# print('{:<15} {:<15} {:<15} {:<15} {:<15}'.format('id', 'symbol', 'base', 'quote', 'active'))
#
# for (k, v) in pairs.items():
# print('{:<15} {:<15} {:<15} {:<15} {:<15}'.format(v['id'], v['symbol'], v['base'], v['quote'], "Yes" if v['active'] else "No"))
tabular_data = []
for _, v in pairs.items():
tabular_data.append([v['id'], v['symbol'], v['base'], v['quote'],
"Yes" if v['active'] else "No"])
headers = ['Id', 'Symbol', 'Base', 'Quote', 'Active']
print(tabulate(tabular_data, headers=headers, tablefmt='pipe'))