Improve /balance output to include starting balance and percentual change
closes #5503
This commit is contained in:
parent
c1895a0fc2
commit
ab88217186
@ -46,6 +46,13 @@ class Balances(BaseModel):
|
|||||||
value: float
|
value: float
|
||||||
stake: str
|
stake: str
|
||||||
note: str
|
note: str
|
||||||
|
starting_capital: float
|
||||||
|
starting_capital_ratio: float
|
||||||
|
starting_capital_pct: float
|
||||||
|
starting_capital_fiat: float
|
||||||
|
starting_capital_fiat_ratio: float
|
||||||
|
starting_capital_fiat_pct: float
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Count(BaseModel):
|
class Count(BaseModel):
|
||||||
|
@ -458,6 +458,9 @@ class RPC:
|
|||||||
raise RPCException('Error getting current tickers.')
|
raise RPCException('Error getting current tickers.')
|
||||||
|
|
||||||
self._freqtrade.wallets.update(require_update=False)
|
self._freqtrade.wallets.update(require_update=False)
|
||||||
|
starting_capital = self._freqtrade.wallets.get_starting_balance()
|
||||||
|
starting_capital_fiat = self._fiat_converter.convert_amount(
|
||||||
|
starting_capital, stake_currency, fiat_display_currency) if self._fiat_converter else 0
|
||||||
|
|
||||||
for coin, balance in self._freqtrade.wallets.get_all_balances().items():
|
for coin, balance in self._freqtrade.wallets.get_all_balances().items():
|
||||||
if not balance.total:
|
if not balance.total:
|
||||||
@ -493,15 +496,28 @@ class RPC:
|
|||||||
else:
|
else:
|
||||||
raise RPCException('All balances are zero.')
|
raise RPCException('All balances are zero.')
|
||||||
|
|
||||||
symbol = fiat_display_currency
|
value = self._fiat_converter.convert_amount(
|
||||||
value = self._fiat_converter.convert_amount(total, stake_currency,
|
total, stake_currency, fiat_display_currency) if self._fiat_converter else 0
|
||||||
symbol) if self._fiat_converter else 0
|
|
||||||
|
starting_capital_ratio = 0.0
|
||||||
|
starting_capital_fiat_ratio = 0.0
|
||||||
|
if starting_capital:
|
||||||
|
starting_capital_ratio = (total / starting_capital) - 1
|
||||||
|
if starting_capital_fiat:
|
||||||
|
starting_capital_fiat_ratio = (value / starting_capital_fiat) - 1
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'currencies': output,
|
'currencies': output,
|
||||||
'total': total,
|
'total': total,
|
||||||
'symbol': symbol,
|
'symbol': fiat_display_currency,
|
||||||
'value': value,
|
'value': value,
|
||||||
'stake': stake_currency,
|
'stake': stake_currency,
|
||||||
|
'starting_capital': starting_capital,
|
||||||
|
'starting_capital_ratio': starting_capital_ratio,
|
||||||
|
'starting_capital_pct': round(starting_capital_ratio * 100, 2),
|
||||||
|
'starting_capital_fiat': starting_capital_fiat,
|
||||||
|
'starting_capital_fiat_ratio': starting_capital_fiat_ratio,
|
||||||
|
'starting_capital_fiat_pct': round(starting_capital_fiat_ratio * 100, 2),
|
||||||
'note': 'Simulated balances' if self._freqtrade.config['dry_run'] else ''
|
'note': 'Simulated balances' if self._freqtrade.config['dry_run'] else ''
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,12 +603,15 @@ class Telegram(RPCHandler):
|
|||||||
|
|
||||||
output = ''
|
output = ''
|
||||||
if self._config['dry_run']:
|
if self._config['dry_run']:
|
||||||
output += (
|
output += "*Warning:* Simulated balances in Dry Mode.\n"
|
||||||
f"*Warning:* Simulated balances in Dry Mode.\n"
|
|
||||||
"This mode is still experimental!\n"
|
output += ("Starting capital: "
|
||||||
"Starting capital: "
|
f"`{result['starting_capital']}` {self._config['stake_currency']}"
|
||||||
f"`{self._config['dry_run_wallet']}` {self._config['stake_currency']}.\n"
|
)
|
||||||
)
|
output += (f" `{result['starting_capital_fiat']}` "
|
||||||
|
f"{self._config['fiat_display_currency']}.\n"
|
||||||
|
) if result['starting_capital_fiat'] > 0 else '.\n'
|
||||||
|
|
||||||
total_dust_balance = 0
|
total_dust_balance = 0
|
||||||
total_dust_currencies = 0
|
total_dust_currencies = 0
|
||||||
for curr in result['currencies']:
|
for curr in result['currencies']:
|
||||||
@ -641,9 +644,13 @@ class Telegram(RPCHandler):
|
|||||||
f"{round_coin_value(total_dust_balance, result['stake'], False)}`\n")
|
f"{round_coin_value(total_dust_balance, result['stake'], False)}`\n")
|
||||||
|
|
||||||
output += ("\n*Estimated Value*:\n"
|
output += ("\n*Estimated Value*:\n"
|
||||||
f"\t`{result['stake']}: {result['total']: .8f}`\n"
|
f"\t`{result['stake']}: "
|
||||||
|
f"{round_coin_value(result['total'], result['stake'], False)}`"
|
||||||
|
f" `({result['starting_capital_pct']}%)`\n"
|
||||||
f"\t`{result['symbol']}: "
|
f"\t`{result['symbol']}: "
|
||||||
f"{round_coin_value(result['value'], result['symbol'], False)}`\n")
|
f"{round_coin_value(result['value'], result['symbol'], False)}`"
|
||||||
|
f" `({result['starting_capital_fiat_pct']}%)`\n"
|
||||||
|
)
|
||||||
self._send_msg(output, reload_able=True, callback_path="update_balance",
|
self._send_msg(output, reload_able=True, callback_path="update_balance",
|
||||||
query=update.callback_query)
|
query=update.callback_query)
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
|
@ -422,20 +422,22 @@ def test_api_stopbuy(botclient):
|
|||||||
assert ftbot.config['max_open_trades'] == 0
|
assert ftbot.config['max_open_trades'] == 0
|
||||||
|
|
||||||
|
|
||||||
def test_api_balance(botclient, mocker, rpc_balance):
|
def test_api_balance(botclient, mocker, rpc_balance, tickers):
|
||||||
ftbot, client = botclient
|
ftbot, client = botclient
|
||||||
|
|
||||||
ftbot.config['dry_run'] = False
|
ftbot.config['dry_run'] = False
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
||||||
|
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
|
||||||
mocker.patch('freqtrade.exchange.Exchange.get_valid_pair_combination',
|
mocker.patch('freqtrade.exchange.Exchange.get_valid_pair_combination',
|
||||||
side_effect=lambda a, b: f"{a}/{b}")
|
side_effect=lambda a, b: f"{a}/{b}")
|
||||||
ftbot.wallets.update()
|
ftbot.wallets.update()
|
||||||
|
|
||||||
rc = client_get(client, f"{BASE_URI}/balance")
|
rc = client_get(client, f"{BASE_URI}/balance")
|
||||||
assert_response(rc)
|
assert_response(rc)
|
||||||
assert "currencies" in rc.json()
|
response = rc.json()
|
||||||
assert len(rc.json()["currencies"]) == 5
|
assert "currencies" in response
|
||||||
assert rc.json()['currencies'][0] == {
|
assert len(response["currencies"]) == 5
|
||||||
|
assert response['currencies'][0] == {
|
||||||
'currency': 'BTC',
|
'currency': 'BTC',
|
||||||
'free': 12.0,
|
'free': 12.0,
|
||||||
'balance': 12.0,
|
'balance': 12.0,
|
||||||
@ -443,6 +445,10 @@ def test_api_balance(botclient, mocker, rpc_balance):
|
|||||||
'est_stake': 12.0,
|
'est_stake': 12.0,
|
||||||
'stake': 'BTC',
|
'stake': 'BTC',
|
||||||
}
|
}
|
||||||
|
assert 'starting_capital' in response
|
||||||
|
assert 'starting_capital_fiat' in response
|
||||||
|
assert 'starting_capital_pct' in response
|
||||||
|
assert 'starting_capital_ratio' in response
|
||||||
|
|
||||||
|
|
||||||
def test_api_count(botclient, mocker, ticker, fee, markets):
|
def test_api_count(botclient, mocker, ticker, fee, markets):
|
||||||
|
@ -576,6 +576,8 @@ def test_balance_handle_too_large_response(default_conf, update, mocker) -> None
|
|||||||
'total': 100.0,
|
'total': 100.0,
|
||||||
'symbol': 100.0,
|
'symbol': 100.0,
|
||||||
'value': 1000.0,
|
'value': 1000.0,
|
||||||
|
'starting_capital': 1000,
|
||||||
|
'starting_capital_fiat': 1000,
|
||||||
})
|
})
|
||||||
|
|
||||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||||
|
Loading…
Reference in New Issue
Block a user