From 5c7d0ff1df9857f55ac183f4fe27aadf650069bd Mon Sep 17 00:00:00 2001 From: enenn Date: Sun, 4 Feb 2018 11:30:54 +0100 Subject: [PATCH] Implement get_balance and telegram balance formatting --- freqtrade/exchange/__init__.py | 13 ++++-- freqtrade/rpc/telegram.py | 50 +++++++++++---------- freqtrade/tests/exchange/test_exchange.py | 2 +- freqtrade/tests/rpc/test_rpc_telegram.py | 54 +++++++++++------------ freqtrade/tests/test_misc.py | 2 +- 5 files changed, 63 insertions(+), 58 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 77ce8d899..417b8baa9 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -135,11 +135,18 @@ def get_balance(currency: str) -> float: return _API.fetch_balance()[currency]['free'] -def get_balances(): +def get_balances() -> dict: if _CONF['dry_run']: - return [] + return {} - return _API.fetch_balance() + balances = _API.fetch_balance() + # Remove additional info from ccxt results + balances.pop("info", None) + balances.pop("free", None) + balances.pop("total", None) + balances.pop("used", None) + + return balances def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict: diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index ef2367395..987228947 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -94,6 +94,7 @@ def authorized_only(command_handler: Callable[[Bot, Update], None]) -> Callable[ :param command_handler: Telegram CommandHandler :return: decorated function """ + def wrapper(*args, **kwargs): update = kwargs.get('update') or args[1] @@ -108,6 +109,7 @@ def authorized_only(command_handler: Callable[[Bot, Update], None]) -> Callable[ return command_handler(*args, **kwargs) except BaseException: logger.exception('Exception occurred within Telegram module') + return wrapper @@ -238,9 +240,9 @@ def _daily(bot: Bot, update: Update) -> None: profitday = today - timedelta(days=day) trades = Trade.query \ .filter(Trade.is_open.is_(False)) \ - .filter(Trade.close_date >= profitday)\ - .filter(Trade.close_date < (profitday + timedelta(days=1)))\ - .order_by(Trade.close_date)\ + .filter(Trade.close_date >= profitday) \ + .filter(Trade.close_date < (profitday + timedelta(days=1))) \ + .order_by(Trade.close_date) \ .all() curdayprofit = sum(trade.calc_profit() for trade in trades) profit_days[profitday] = { @@ -385,42 +387,42 @@ def _balance(bot: Bot, update: Update) -> None: Returns current account balance per crypto """ output = '' - balances = [ - c for c in exchange.get_balances() - if c['Balance'] or c['Available'] or c['Pending'] - ] + balances = { + k: c for k, c in exchange.get_balances().items() + if c['total'] or c['free'] or c['used'] + } if not balances: send_msg('`All balances are zero.`') return total = 0.0 - for currency in balances: - coin = currency['Currency'] + for coin, balance in balances.items(): if coin == 'BTC': - currency["Rate"] = 1.0 + balance["rate"] = 1.0 else: if coin == 'USDT': - currency["Rate"] = 1.0 / exchange.get_ticker('BTC/USDT', False)['bid'] + balance["rate"] = 1.0 / exchange.get_ticker('BTC/USDT', False)['bid'] else: - currency["Rate"] = exchange.get_ticker(coin + '/BTC', False)['bid'] - currency['BTC'] = currency["Rate"] * currency["Balance"] - total = total + currency['BTC'] - output += """*Currency*: {Currency} -*Available*: {Available} -*Balance*: {Balance} -*Pending*: {Pending} -*Est. BTC*: {BTC: .8f} - -""".format(**currency) + balance["rate"] = exchange.get_ticker(coin + '/BTC', False)['bid'] + balance['BTCequiv'] = balance["rate"] * balance["total"] + balance['coin'] = coin + total = total + balance['BTCequiv'] + output += """*Currency*: {coin} + *Available*: {free} + *Balance*: {total} + *Pending*: {used} + *Est. BTC*: {BTCequiv: .8f} + + """.format(**balance) symbol = _CONF['fiat_display_currency'] value = _FIAT_CONVERT.convert_amount( total, 'BTC', symbol ) output += """*Estimated Value*: -*BTC*: {0: .8f} -*{1}*: {2: .2f} -""".format(total, symbol, value) + *BTC*: {0: .8f} + *{1}*: {2: .2f} + """.format(total, symbol, value) send_msg(output) diff --git a/freqtrade/tests/exchange/test_exchange.py b/freqtrade/tests/exchange/test_exchange.py index 84e3448ed..b916e6d63 100644 --- a/freqtrade/tests/exchange/test_exchange.py +++ b/freqtrade/tests/exchange/test_exchange.py @@ -147,7 +147,7 @@ def test_get_balances_dry_run(default_conf, mocker): default_conf['dry_run'] = True mocker.patch.dict('freqtrade.exchange._CONF', default_conf) - assert get_balances() == [] + assert get_balances() == {} def test_get_balances_prod(default_conf, mocker): diff --git a/freqtrade/tests/rpc/test_rpc_telegram.py b/freqtrade/tests/rpc/test_rpc_telegram.py index 23bde2404..ef6eb6383 100644 --- a/freqtrade/tests/rpc/test_rpc_telegram.py +++ b/freqtrade/tests/rpc/test_rpc_telegram.py @@ -639,35 +639,31 @@ def test_stop_handle_already_stopped(default_conf, update, mocker): def test_balance_handle(default_conf, update, mocker): - - mock_balance = [{ - 'Currency': 'BTC', - 'Balance': 10.0, - 'Available': 12.0, - 'Pending': 0.0, - 'CryptoAddress': 'XXXX', - }, { - 'Currency': 'ETH', - 'Balance': 0.0, - 'Available': 0.0, - 'Pending': 0.0, - 'CryptoAddress': 'XXXX', - }, { - 'Currency': 'USDT', - 'Balance': 10000.0, - 'Available': 0.0, - 'Pending': 0.0, - 'CryptoAddress': 'XXXX', - }, { - 'Currency': 'LTC', - 'Balance': 10.0, - 'Available': 10.0, - 'Pending': 0.0, - 'CryptoAddress': 'XXXX', - }] + mock_balance = { + 'BTC': { + 'total': 12.0, + 'free': 12.0, + 'used': 0.0, + }, + 'ETH': { + 'total': 0.0, + 'free': 0.0, + 'used': 0.0, + }, + 'USDT': { + 'total': 10000.0, + 'free': 0.0, + 'used': 0.0, + }, + 'LTC': { + 'total': 10.0, + 'free': 10.0, + 'used': 0.0, + } + } def mock_ticker(symbol, refresh): - if symbol == 'USDT_BTC': + if symbol == 'BTC/USDT': return { 'bid': 10000.00, 'ask': 10000.00, @@ -701,7 +697,7 @@ def test_balance_handle(default_conf, update, mocker): assert '*Currency*: USDT' in result assert 'Balance' in result assert 'Est. BTC' in result - assert '*BTC*: 12.00000000' in result + assert '*BTC*: 14.00000000' in result def test_zero_balance_handle(default_conf, update, mocker): @@ -712,7 +708,7 @@ def test_zero_balance_handle(default_conf, update, mocker): init=MagicMock(), send_msg=msg_mock) mocker.patch.multiple('freqtrade.main.exchange', - get_balances=MagicMock(return_value=[])) + get_balances=MagicMock(return_value={})) _balance(bot=MagicMock(), update=update) result = msg_mock.call_args_list[0][0][0] assert msg_mock.call_count == 1 diff --git a/freqtrade/tests/test_misc.py b/freqtrade/tests/test_misc.py index 8724637b3..5bcbd36cc 100644 --- a/freqtrade/tests/test_misc.py +++ b/freqtrade/tests/test_misc.py @@ -161,7 +161,7 @@ def test_load_config(default_conf, mocker): def test_load_config_invalid_pair(default_conf, mocker): conf = deepcopy(default_conf) - conf['exchange']['pair_whitelist'].append('ETH/BTC') + conf['exchange']['pair_whitelist'].append('ETH_BTC') # Should have format ETH/BTC mocker.patch( 'freqtrade.misc.open', mocker.mock_open(