Repository: freqtrade/freqtrade

Issue:
Telegram Balance not updating correctly after sell
## Describe your environment

  * Operating system: Ubuntu 18.04
  * Python Version:  2.7.17
  * CCXT version: 1.34.7
  * Freqtrade Version: develop-4c349342
  
## Describe the problem:

Balance is not updated after sell on Bittrex live. All positions ever bought, but where sold, are shown in Telegram via /balance, as if they where actually held and in the wallet and are summed up in the estimated value too. The stake currency is updated correctly and the bot trades with correct values.

### Steps to reproduce:

  1. Live trade on Bittrex and have a successful buy and sell on the same position by the bot.
  2. Call /balance in Telegram.
  3. In the response all successfully sold positions show up as not pending, held and available.
  
### Observed Results:

  * What happened?
     Calling  /balance in Telegram shows all ever bought assets (tested for 3 Days) although they where successfully sold.
  * What did you expect to happen?
      /balance shows actual held positions/wallet. For instance, If no positions are held, the stake currency only would be shown.

### Relevant code exceptions or logs

2020-09-22 11:42:52 freqtrade.worker: INFO - Bot heartbeat. PID=25032, version='develop-4c349342', state='RUNNING'
2020-09-22 11:43:13 freqtrade.rpc.telegram: INFO - Executing handler: _balance for chat_id: XXX
2020-09-22 11:43:15 freqtrade.wallets: INFO - Wallets synced.
2020-09-22 11:43:15 freqtrade.rpc.rpc: WARNING -  Could not get rate for pair BTXCRD.
2020-09-22 11:43:52 freqtrade.worker: INFO - Bot heartbeat. PID=25032, version='develop-4c349342', state='RUNNING'



Discussion:
to understand this correctly - the total balance (`/balance` - and "manually" sum up all balances) is then your available "stakecurrency+ trades * stake_amount"?

so for example you use USDT as stake currency and use 10 USDT as stake, you'd then have:

104 USDT (you made 4$ profits)
2 XRP (20 USDT) (2 trades x 5 XRP)
...
Hi, thanks for looking in to it.
The stakecurrency (BTC here) and profit was always correct and the same as on the exchange.
The 'Estimated Value' is "stake Est. BTC + positions Est. BTC" (no *stake_amount), what would be correct, but theses position are not in the wallet anymore nor open trades, but below is what i get with _only_ BTC in the wallet (and nothing happening like orders). The estimated value at the bottom should be 0.00097305 BTC since there are no other positions.
All these positions shown have been sold successfully before and the balance was added back to the stake amount. It seems "just visual", as if they weren't removed after the sale.

I'd like to add that /reload_config resets the balance to its correct status

BTC:
 Available:  0.00097305
 Balance:  0.00097305
 Pending:  0.00000000
 Est. BTC:  0.00097305
ETH: not showing <1$ amount 
LTC:
 Available:  0.22350693
 Balance:  0.22350693
 Pending:  0.00000000
 Est. BTC:  0.00093428
USDT: not showing <1$ amount 
TUSD:
 Available:  9.99661107
 Balance:  9.99661107
 Pending:  0.00000000
 Est. BTC:  0.00095428
KMD:
 Available:  16.49403409
 Balance:  16.49403409
 Pending:  0.00000000
 Est. BTC:  0.00087600
XEM:
 Available:  92.83441205
 Balance:  92.83441205
 Pending:  0.00000000
 Est. BTC:  0.00093206
XTZ:
 Available:  4.98379999
 Balance:  4.98379999
 Pending:  0.00000000
 Est. BTC:  0.00100000
LSK:
 Available:  8.37305414
 Balance:  8.37305414
 Pending:  0.00000000
 Est. BTC:  0.00094507
XMR:
 Available:  0.11325856
 Balance:  0.11325856
 Pending:  0.00000000
 Est. BTC:  0.00096145

Estimated Value:
 BTC:  0.00757619
 EUR:  67.40


correct /balance:
BTC:
 Available:  0.00097305
 Balance:  0.00097305
 Pending:  0.00000000
 Est. BTC:  0.00097305
ETH: not showing <1$ amount 
USDT: not showing <1$ amount 

Estimated Value:
 BTC:  0.00097305
 EUR:  17.02



Resolving patch:
diff --git a/freqtrade/wallets.py b/freqtrade/wallets.py
--- a/freqtrade/wallets.py
+++ b/freqtrade/wallets.py
@@ -2,6 +2,7 @@
 """ Wallet """
 
 import logging
+from copy import deepcopy
 from typing import Any, Dict, NamedTuple
 
 import arrow
@@ -93,6 +94,10 @@ def _update_live(self) -> None:
                 balances[currency].get('used', None),
                 balances[currency].get('total', None)
             )
+        # Remove currencies no longer in get_balances output
+        for currency in deepcopy(self._wallets):
+            if currency not in balances:
+                del self._wallets[currency]
 
     def update(self, require_update: bool = True) -> None:
         """


Test patch:
diff --git a/tests/test_wallets.py b/tests/test_wallets.py
--- a/tests/test_wallets.py
+++ b/tests/test_wallets.py
@@ -19,12 +19,17 @@ def test_sync_wallet_at_boot(mocker, default_conf):
                 "used": 0.0,
                 "total": 0.260739
             },
+            "USDT": {
+                "free": 20,
+                "used": 20,
+                "total": 40
+            },
         })
     )
 
     freqtrade = get_patched_freqtradebot(mocker, default_conf)
 
-    assert len(freqtrade.wallets._wallets) == 2
+    assert len(freqtrade.wallets._wallets) == 3
     assert freqtrade.wallets._wallets['BNT'].free == 1.0
     assert freqtrade.wallets._wallets['BNT'].used == 2.0
     assert freqtrade.wallets._wallets['BNT'].total == 3.0
@@ -32,6 +37,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
     assert freqtrade.wallets._wallets['GAS'].used == 0.0
     assert freqtrade.wallets._wallets['GAS'].total == 0.260739
     assert freqtrade.wallets.get_free('BNT') == 1.0
+    assert 'USDT' in freqtrade.wallets._wallets
     assert freqtrade.wallets._last_wallet_refresh > 0
     mocker.patch.multiple(
         'freqtrade.exchange.Exchange',
@@ -51,6 +57,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
 
     freqtrade.wallets.update()
 
+    # USDT is missing from the 2nd result - so should not be in this either.
     assert len(freqtrade.wallets._wallets) == 2
     assert freqtrade.wallets._wallets['BNT'].free == 1.2
     assert freqtrade.wallets._wallets['BNT'].used == 1.9