Update list-exchanges to use rich tables
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
import csv
|
import csv
|
||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
from typing import Any, Dict, List, Union
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
import rapidjson
|
import rapidjson
|
||||||
from colorama import Fore, Style
|
from colorama import Fore, Style
|
||||||
from colorama import init as colorama_init
|
from colorama import init as colorama_init
|
||||||
|
from rich.console import Console
|
||||||
|
from rich.table import Table
|
||||||
|
from rich.text import Text
|
||||||
from tabulate import tabulate
|
from tabulate import tabulate
|
||||||
|
|
||||||
from freqtrade.configuration import setup_utils_configuration
|
from freqtrade.configuration import setup_utils_configuration
|
||||||
@@ -14,7 +17,7 @@ from freqtrade.exceptions import ConfigurationError, OperationalException
|
|||||||
from freqtrade.exchange import list_available_exchanges, market_is_active
|
from freqtrade.exchange import list_available_exchanges, market_is_active
|
||||||
from freqtrade.misc import parse_db_uri_for_logging, plural
|
from freqtrade.misc import parse_db_uri_for_logging, plural
|
||||||
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
from freqtrade.resolvers import ExchangeResolver, StrategyResolver
|
||||||
from freqtrade.types import ValidExchangesType
|
from freqtrade.types.valid_exchanges_type import ValidExchangesType
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -26,51 +29,55 @@ def start_list_exchanges(args: Dict[str, Any]) -> None:
|
|||||||
:param args: Cli args from Arguments()
|
:param args: Cli args from Arguments()
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
available_exchanges = list_available_exchanges(args["list_exchanges_all"])
|
available_exchanges: List[ValidExchangesType] = list_available_exchanges(
|
||||||
|
args["list_exchanges_all"]
|
||||||
|
)
|
||||||
|
|
||||||
if args["print_one_column"]:
|
if args["print_one_column"]:
|
||||||
print("\n".join([e["name"] for e in available_exchanges]))
|
print("\n".join([e["name"] for e in available_exchanges]))
|
||||||
else:
|
else:
|
||||||
headers = {
|
if args["list_exchanges_all"]:
|
||||||
"name": "Exchange name",
|
title = (
|
||||||
"supported": "Supported",
|
f"All exchanges supported by the ccxt library "
|
||||||
"trade_modes": "Markets",
|
f"({len(available_exchanges)} exchanges):"
|
||||||
"comment": "Reason",
|
)
|
||||||
}
|
else:
|
||||||
headers.update({"valid": "Valid"} if args["list_exchanges_all"] else {})
|
available_exchanges = [e for e in available_exchanges if e["valid"] is not False]
|
||||||
|
title = f"Exchanges available for Freqtrade ({len(available_exchanges)} exchanges):"
|
||||||
|
|
||||||
def build_entry(exchange: ValidExchangesType, valid: bool):
|
table = Table(title=title)
|
||||||
valid_entry = {"valid": exchange["valid"]} if valid else {}
|
|
||||||
result: Dict[str, Union[str, bool]] = {
|
table.add_column("Exchange Name")
|
||||||
"name": exchange["name"],
|
table.add_column("Markets")
|
||||||
**valid_entry,
|
table.add_column("Reason")
|
||||||
"supported": "Official" if exchange["supported"] else "",
|
|
||||||
"trade_modes": ("DEX: " if exchange["dex"] else "")
|
for exchange in available_exchanges:
|
||||||
+ ", ".join(
|
name = Text(exchange["name"])
|
||||||
(f"{a['margin_mode']} " if a["margin_mode"] else "") + a["trading_mode"]
|
if exchange["supported"]:
|
||||||
|
name.append(" (Official)", style="italic")
|
||||||
|
name.stylize("green bold")
|
||||||
|
|
||||||
|
trade_modes = Text(
|
||||||
|
", ".join(
|
||||||
|
(f"{a.get('margin_mode', '')} {a["trading_mode"]}").lstrip()
|
||||||
for a in exchange["trade_modes"]
|
for a in exchange["trade_modes"]
|
||||||
),
|
),
|
||||||
"comment": exchange["comment"],
|
style="",
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
if args["list_exchanges_all"]:
|
|
||||||
exchanges = [build_entry(e, True) for e in available_exchanges]
|
|
||||||
title = f"All exchanges supported by the ccxt library ({len(exchanges)} exchanges):"
|
|
||||||
else:
|
|
||||||
exchanges = [
|
|
||||||
build_entry(e, False) for e in available_exchanges if e["valid"] is not False
|
|
||||||
]
|
|
||||||
title = f"Exchanges available for Freqtrade ({len(exchanges)} exchanges):"
|
|
||||||
|
|
||||||
print(title)
|
|
||||||
print(
|
|
||||||
tabulate(
|
|
||||||
exchanges,
|
|
||||||
headers=headers,
|
|
||||||
)
|
)
|
||||||
)
|
if exchange["dex"]:
|
||||||
|
trade_modes = Text("DEX: ") + trade_modes
|
||||||
|
trade_modes.stylize("bold", 0, 3)
|
||||||
|
|
||||||
|
table.add_row(
|
||||||
|
name,
|
||||||
|
trade_modes,
|
||||||
|
exchange["comment"],
|
||||||
|
style=None if exchange["valid"] else "red",
|
||||||
|
)
|
||||||
|
# table.add_row(*[exchange[header] for header in headers])
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
console.print(table)
|
||||||
|
|
||||||
|
|
||||||
def _print_objs_tabular(objs: List, print_colorized: bool) -> None:
|
def _print_objs_tabular(objs: List, print_colorized: bool) -> None:
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ def test_list_exchanges(capsys):
|
|||||||
|
|
||||||
start_list_exchanges(get_args(args))
|
start_list_exchanges(get_args(args))
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert re.match(r"Exchanges available for Freqtrade.*", captured.out)
|
assert re.search(r".*Exchanges available for Freqtrade.*", captured.out)
|
||||||
assert re.search(r".*binance.*", captured.out)
|
assert re.search(r".*binance.*", captured.out)
|
||||||
assert re.search(r".*bybit.*", captured.out)
|
assert re.search(r".*bybit.*", captured.out)
|
||||||
|
|
||||||
@@ -139,7 +139,7 @@ def test_list_exchanges(capsys):
|
|||||||
|
|
||||||
start_list_exchanges(get_args(args))
|
start_list_exchanges(get_args(args))
|
||||||
captured = capsys.readouterr()
|
captured = capsys.readouterr()
|
||||||
assert re.match(r"All exchanges supported by the ccxt library.*", captured.out)
|
assert re.search(r"All exchanges supported by the ccxt library.*", captured.out)
|
||||||
assert re.search(r".*binance.*", captured.out)
|
assert re.search(r".*binance.*", captured.out)
|
||||||
assert re.search(r".*bingx.*", captured.out)
|
assert re.search(r".*bingx.*", captured.out)
|
||||||
assert re.search(r".*bitmex.*", captured.out)
|
assert re.search(r".*bitmex.*", captured.out)
|
||||||
|
|||||||
Reference in New Issue
Block a user