Merge pull request #4947 from freqtrade/performance_abs

/performance - sort by absolute profit
This commit is contained in:
Matthias 2021-05-15 20:32:58 +02:00 committed by GitHub
commit 32bdceee12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 23 additions and 14 deletions

View File

@ -262,11 +262,11 @@ Note that for this to work, `forcebuy_enable` needs to be set to true.
Return the performance of each crypto-currency the bot has sold. Return the performance of each crypto-currency the bot has sold.
> Performance: > Performance:
> 1. `RCN/BTC 57.77%` > 1. `RCN/BTC 0.003 BTC (57.77%) (1)`
> 2. `PAY/BTC 56.91%` > 2. `PAY/BTC 0.0012 BTC (56.91%) (1)`
> 3. `VIB/BTC 47.07%` > 3. `VIB/BTC 0.0011 BTC (47.07%) (1)`
> 4. `SALT/BTC 30.24%` > 4. `SALT/BTC 0.0010 BTC (30.24%) (1)`
> 5. `STORJ/BTC 27.24%` > 5. `STORJ/BTC 0.0009 BTC (27.24%) (1)`
> ... > ...
### /balance ### /balance

View File

@ -815,18 +815,20 @@ class Trade(_DECL_BASE, LocalTrade):
pair_rates = Trade.query.with_entities( pair_rates = Trade.query.with_entities(
Trade.pair, Trade.pair,
func.sum(Trade.close_profit).label('profit_sum'), func.sum(Trade.close_profit).label('profit_sum'),
func.sum(Trade.close_profit_abs).label('profit_sum_abs'),
func.count(Trade.pair).label('count') func.count(Trade.pair).label('count')
).filter(Trade.is_open.is_(False))\ ).filter(Trade.is_open.is_(False))\
.group_by(Trade.pair) \ .group_by(Trade.pair) \
.order_by(desc('profit_sum')) \ .order_by(desc('profit_sum_abs')) \
.all() .all()
return [ return [
{ {
'pair': pair, 'pair': pair,
'profit': rate, 'profit': profit,
'profit_abs': profit_abs,
'count': count 'count': count
} }
for pair, rate, count in pair_rates for pair, profit, profit_abs, count in pair_rates
] ]
@staticmethod @staticmethod

View File

@ -57,6 +57,7 @@ class Count(BaseModel):
class PerformanceEntry(BaseModel): class PerformanceEntry(BaseModel):
pair: str pair: str
profit: float profit: float
profit_abs: float
count: int count: int

View File

@ -711,8 +711,11 @@ class Telegram(RPCHandler):
trades = self._rpc._rpc_performance() trades = self._rpc._rpc_performance()
output = "<b>Performance:</b>\n" output = "<b>Performance:</b>\n"
for i, trade in enumerate(trades): for i, trade in enumerate(trades):
stat_line = (f"{i+1}.\t <code>{trade['pair']}\t{trade['profit']:.2f}% " stat_line = (
f"({trade['count']})</code>\n") f"{i+1}.\t <code>{trade['pair']}\t"
f"{round_coin_value(trade['profit_abs'], self._config['stake_currency'])} "
f"({trade['profit']:.2f}%) "
f"({trade['count']})</code>\n")
if len(output + stat_line) >= MAX_TELEGRAM_MESSAGE_LENGTH: if len(output + stat_line) >= MAX_TELEGRAM_MESSAGE_LENGTH:
self._send_msg(output, parse_mode=ParseMode.HTML) self._send_msg(output, parse_mode=ParseMode.HTML)

View File

@ -710,7 +710,7 @@ def test_api_stats(botclient, mocker, ticker, fee, markets,):
assert 'draws' in rc.json()['durations'] assert 'draws' in rc.json()['durations']
def test_api_performance(botclient, mocker, ticker, fee): def test_api_performance(botclient, fee):
ftbot, client = botclient ftbot, client = botclient
patch_get_signal(ftbot, (True, False)) patch_get_signal(ftbot, (True, False))
@ -728,6 +728,7 @@ def test_api_performance(botclient, mocker, ticker, fee):
) )
trade.close_profit = trade.calc_profit_ratio() trade.close_profit = trade.calc_profit_ratio()
trade.close_profit_abs = trade.calc_profit()
Trade.query.session.add(trade) Trade.query.session.add(trade)
trade = Trade( trade = Trade(
@ -743,14 +744,16 @@ def test_api_performance(botclient, mocker, ticker, fee):
close_rate=0.391 close_rate=0.391
) )
trade.close_profit = trade.calc_profit_ratio() trade.close_profit = trade.calc_profit_ratio()
trade.close_profit_abs = trade.calc_profit()
Trade.query.session.add(trade) Trade.query.session.add(trade)
Trade.query.session.flush() Trade.query.session.flush()
rc = client_get(client, f"{BASE_URI}/performance") rc = client_get(client, f"{BASE_URI}/performance")
assert_response(rc) assert_response(rc)
assert len(rc.json()) == 2 assert len(rc.json()) == 2
assert rc.json() == [{'count': 1, 'pair': 'LTC/ETH', 'profit': 7.61}, assert rc.json() == [{'count': 1, 'pair': 'LTC/ETH', 'profit': 7.61, 'profit_abs': 0.01872279},
{'count': 1, 'pair': 'XRP/ETH', 'profit': -5.57}] {'count': 1, 'pair': 'XRP/ETH', 'profit': -5.57, 'profit_abs': -0.1150375}]
def test_api_status(botclient, mocker, ticker, fee, markets): def test_api_status(botclient, mocker, ticker, fee, markets):

View File

@ -929,7 +929,7 @@ def test_performance_handle(default_conf, update, ticker, fee,
telegram._performance(update=update, context=MagicMock()) telegram._performance(update=update, context=MagicMock())
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'Performance' in msg_mock.call_args_list[0][0][0] assert 'Performance' in msg_mock.call_args_list[0][0][0]
assert '<code>ETH/BTC\t6.20% (1)</code>' in msg_mock.call_args_list[0][0][0] assert '<code>ETH/BTC\t0.00006217 BTC (6.20%) (1)</code>' in msg_mock.call_args_list[0][0][0]
def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: def test_count_handle(default_conf, update, ticker, fee, mocker) -> None: