list-pairs, list-markets subcommands
This commit is contained in:
parent
4823656028
commit
dbdeab4639
@ -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')
|
||||
|
||||
@ -449,6 +473,23 @@ class Arguments(object):
|
||||
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:
|
||||
"""
|
||||
|
@ -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]
|
||||
|
@ -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'
|
||||
|
@ -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'))
|
||||
|
Loading…
Reference in New Issue
Block a user