Repository: freqtrade/freqtrade

Issue:
Please add new column in /status table to show USD profit or loss
Please add new column in /status table to show USD profit or loss


Discussion:
Lets fix https://github.com/gcarq/freqtrade/issues/462 first
After that maybe update all tables to 1 more consistent format and reduced data (width)
`'{value:0.2f}'.format(value=_FIAT_CONVERT.convert_amount(current_rate['amount'],_CONF['stake_currency'],_CONF['fiat_display_currency']))`
somethong wrong here, dont know what

error: TypeError: 'float' object is not subscriptable

Resolving patch:
diff --git a/freqtrade/rpc/api_server.py b/freqtrade/rpc/api_server.py
--- a/freqtrade/rpc/api_server.py
+++ b/freqtrade/rpc/api_server.py
@@ -274,7 +274,7 @@ def _daily(self):
 
         stats = self._rpc_daily_profit(timescale,
                                        self._config['stake_currency'],
-                                       self._config['fiat_display_currency']
+                                       self._config.get('fiat_display_currency', '')
                                        )
 
         return self.rest_dump(stats)
diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py
--- a/freqtrade/rpc/rpc.py
+++ b/freqtrade/rpc/rpc.py
@@ -3,16 +3,15 @@
 """
 import logging
 from abc import abstractmethod
-from datetime import timedelta, datetime, date
-from decimal import Decimal
+from datetime import date, datetime, timedelta
 from enum import Enum
-from typing import Dict, Any, List, Optional
+from math import isnan
+from typing import Any, Dict, List, Optional, Tuple
 
 import arrow
-from numpy import mean, NAN
-from pandas import DataFrame
+from numpy import NAN, mean
 
-from freqtrade import TemporaryError, DependencyException
+from freqtrade import DependencyException, TemporaryError
 from freqtrade.misc import shorten_date
 from freqtrade.persistence import Trade
 from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
@@ -117,7 +116,7 @@ def _rpc_trade_status(self) -> List[Dict[str, Any]]:
                 results.append(trade_dict)
             return results
 
-    def _rpc_status_table(self) -> DataFrame:
+    def _rpc_status_table(self, stake_currency, fiat_display_currency: str) -> Tuple[List, List]:
         trades = Trade.get_open_trades()
         if not trades:
             raise RPCException('no active order')
@@ -130,17 +129,28 @@ def _rpc_status_table(self) -> DataFrame:
                 except DependencyException:
                     current_rate = NAN
                 trade_perc = (100 * trade.calc_profit_percent(current_rate))
+                trade_profit = trade.calc_profit(current_rate)
+                profit_str = f'{trade_perc:.2f}%'
+                if self._fiat_converter:
+                    fiat_profit = self._fiat_converter.convert_amount(
+                            trade_profit,
+                            stake_currency,
+                            fiat_display_currency
+                        )
+                    if fiat_profit and not isnan(fiat_profit):
+                        profit_str += f" ({fiat_profit:.2f})"
                 trades_list.append([
                     trade.id,
                     trade.pair,
                     shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)),
-                    f'{trade_perc:.2f}%'
+                    profit_str
                 ])
+            profitcol = "Profit"
+            if self._fiat_converter:
+                profitcol += " (" + fiat_display_currency + ")"
 
-            columns = ['ID', 'Pair', 'Since', 'Profit']
-            df_statuses = DataFrame.from_records(trades_list, columns=columns)
-            df_statuses = df_statuses.set_index(columns[0])
-            return df_statuses
+            columns = ['ID', 'Pair', 'Since', profitcol]
+            return trades_list, columns
 
     def _rpc_daily_profit(
             self, timescale: int,
@@ -219,7 +229,7 @@ def _rpc_trade_statistics(
                 profit_percent = trade.calc_profit_percent(rate=current_rate)
 
             profit_all_coin.append(
-                trade.calc_profit(rate=Decimal(trade.close_rate or current_rate))
+                trade.calc_profit(rate=trade.close_rate or current_rate)
             )
             profit_all_perc.append(profit_percent)
 
diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py
--- a/freqtrade/rpc/telegram.py
+++ b/freqtrade/rpc/telegram.py
@@ -234,8 +234,9 @@ def _status_table(self, update: Update, context: CallbackContext) -> None:
         :return: None
         """
         try:
-            df_statuses = self._rpc_status_table()
-            message = tabulate(df_statuses, headers='keys', tablefmt='simple')
+            statlist, head = self._rpc_status_table(self._config['stake_currency'],
+                                                    self._config.get('fiat_display_currency', ''))
+            message = tabulate(statlist, headers=head, tablefmt='simple')
             self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML)
         except RPCException as e:
             self._send_msg(str(e))


Test patch:
diff --git a/tests/rpc/test_rpc.py b/tests/rpc/test_rpc.py
--- a/tests/rpc/test_rpc.py
+++ b/tests/rpc/test_rpc.py
@@ -96,6 +96,11 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
 
 
 def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
+    mocker.patch.multiple(
+        'freqtrade.rpc.fiat_convert.Market',
+        ticker=MagicMock(return_value={'price_usd': 15000.0}),
+    )
+    mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
     mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
     mocker.patch.multiple(
         'freqtrade.exchange.Exchange',
@@ -109,22 +114,34 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
 
     freqtradebot.state = State.RUNNING
     with pytest.raises(RPCException, match=r'.*no active order*'):
-        rpc._rpc_status_table()
+        rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
 
     freqtradebot.create_trades()
-    result = rpc._rpc_status_table()
-    assert 'instantly' in result['Since'].all()
-    assert 'ETH/BTC' in result['Pair'].all()
-    assert '-0.59%' in result['Profit'].all()
+
+    result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
+    assert "Since" in headers
+    assert "Pair" in headers
+    assert 'instantly' == result[0][2]
+    assert 'ETH/BTC' == result[0][1]
+    assert '-0.59%' == result[0][3]
+    # Test with fiatconvert
+
+    rpc._fiat_converter = CryptoToFiatConverter()
+    result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
+    assert "Since" in headers
+    assert "Pair" in headers
+    assert 'instantly' == result[0][2]
+    assert 'ETH/BTC' == result[0][1]
+    assert '-0.59% (-0.09)' == result[0][3]
 
     mocker.patch('freqtrade.exchange.Exchange.get_ticker',
                  MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
     # invalidate ticker cache
     rpc._freqtrade.exchange._cached_ticker = {}
-    result = rpc._rpc_status_table()
-    assert 'instantly' in result['Since'].all()
-    assert 'ETH/BTC' in result['Pair'].all()
-    assert 'nan%' in result['Profit'].all()
+    result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
+    assert 'instantly' == result[0][2]
+    assert 'ETH/BTC' == result[0][1]
+    assert 'nan%' == result[0][3]
 
 
 def test_rpc_daily_profit(default_conf, update, ticker, fee,