Merge pull request #2521 from freqtrade/rpc/status_table
Add fiat to status table
This commit is contained in:
commit
1d7fb2ffac
@ -274,7 +274,7 @@ class ApiServer(RPC):
|
|||||||
|
|
||||||
stats = self._rpc_daily_profit(timescale,
|
stats = self._rpc_daily_profit(timescale,
|
||||||
self._config['stake_currency'],
|
self._config['stake_currency'],
|
||||||
self._config['fiat_display_currency']
|
self._config.get('fiat_display_currency', '')
|
||||||
)
|
)
|
||||||
|
|
||||||
return self.rest_dump(stats)
|
return self.rest_dump(stats)
|
||||||
|
@ -3,16 +3,15 @@ This module contains class to define a RPC communications
|
|||||||
"""
|
"""
|
||||||
import logging
|
import logging
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from datetime import timedelta, datetime, date
|
from datetime import date, datetime, timedelta
|
||||||
from decimal import Decimal
|
|
||||||
from enum import Enum
|
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
|
import arrow
|
||||||
from numpy import mean, NAN
|
from numpy import NAN, mean
|
||||||
from pandas import DataFrame
|
|
||||||
|
|
||||||
from freqtrade import TemporaryError, DependencyException
|
from freqtrade import DependencyException, TemporaryError
|
||||||
from freqtrade.misc import shorten_date
|
from freqtrade.misc import shorten_date
|
||||||
from freqtrade.persistence import Trade
|
from freqtrade.persistence import Trade
|
||||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||||
@ -117,7 +116,7 @@ class RPC:
|
|||||||
results.append(trade_dict)
|
results.append(trade_dict)
|
||||||
return results
|
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()
|
trades = Trade.get_open_trades()
|
||||||
if not trades:
|
if not trades:
|
||||||
raise RPCException('no active order')
|
raise RPCException('no active order')
|
||||||
@ -130,17 +129,28 @@ class RPC:
|
|||||||
except DependencyException:
|
except DependencyException:
|
||||||
current_rate = NAN
|
current_rate = NAN
|
||||||
trade_perc = (100 * trade.calc_profit_percent(current_rate))
|
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([
|
trades_list.append([
|
||||||
trade.id,
|
trade.id,
|
||||||
trade.pair,
|
trade.pair,
|
||||||
shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)),
|
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']
|
columns = ['ID', 'Pair', 'Since', profitcol]
|
||||||
df_statuses = DataFrame.from_records(trades_list, columns=columns)
|
return trades_list, columns
|
||||||
df_statuses = df_statuses.set_index(columns[0])
|
|
||||||
return df_statuses
|
|
||||||
|
|
||||||
def _rpc_daily_profit(
|
def _rpc_daily_profit(
|
||||||
self, timescale: int,
|
self, timescale: int,
|
||||||
@ -219,7 +229,7 @@ class RPC:
|
|||||||
profit_percent = trade.calc_profit_percent(rate=current_rate)
|
profit_percent = trade.calc_profit_percent(rate=current_rate)
|
||||||
|
|
||||||
profit_all_coin.append(
|
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)
|
profit_all_perc.append(profit_percent)
|
||||||
|
|
||||||
|
@ -234,8 +234,9 @@ class Telegram(RPC):
|
|||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
df_statuses = self._rpc_status_table()
|
statlist, head = self._rpc_status_table(self._config['stake_currency'],
|
||||||
message = tabulate(df_statuses, headers='keys', tablefmt='simple')
|
self._config.get('fiat_display_currency', ''))
|
||||||
|
message = tabulate(statlist, headers=head, tablefmt='simple')
|
||||||
self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML)
|
self._send_msg(f"<pre>{message}</pre>", parse_mode=ParseMode.HTML)
|
||||||
except RPCException as e:
|
except RPCException as e:
|
||||||
self._send_msg(str(e))
|
self._send_msg(str(e))
|
||||||
|
@ -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:
|
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('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
@ -109,22 +114,34 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
|||||||
|
|
||||||
freqtradebot.state = State.RUNNING
|
freqtradebot.state = State.RUNNING
|
||||||
with pytest.raises(RPCException, match=r'.*no active order*'):
|
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()
|
freqtradebot.create_trades()
|
||||||
result = rpc._rpc_status_table()
|
|
||||||
assert 'instantly' in result['Since'].all()
|
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||||
assert 'ETH/BTC' in result['Pair'].all()
|
assert "Since" in headers
|
||||||
assert '-0.59%' in result['Profit'].all()
|
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',
|
mocker.patch('freqtrade.exchange.Exchange.get_ticker',
|
||||||
MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
|
MagicMock(side_effect=DependencyException(f"Pair 'ETH/BTC' not available")))
|
||||||
# invalidate ticker cache
|
# invalidate ticker cache
|
||||||
rpc._freqtrade.exchange._cached_ticker = {}
|
rpc._freqtrade.exchange._cached_ticker = {}
|
||||||
result = rpc._rpc_status_table()
|
result, headers = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||||
assert 'instantly' in result['Since'].all()
|
assert 'instantly' == result[0][2]
|
||||||
assert 'ETH/BTC' in result['Pair'].all()
|
assert 'ETH/BTC' == result[0][1]
|
||||||
assert 'nan%' in result['Profit'].all()
|
assert 'nan%' == result[0][3]
|
||||||
|
|
||||||
|
|
||||||
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
def test_rpc_daily_profit(default_conf, update, ticker, fee,
|
||||||
|
Loading…
Reference in New Issue
Block a user