Merge pull request #3390 from freqtrade/rpc/profit
improve /profit to not raise an exception if no trade is closed
This commit is contained in:
@@ -553,6 +553,7 @@ class Trade(_DECL_BASE):
|
||||
def get_best_pair():
|
||||
"""
|
||||
Get best pair with closed trade.
|
||||
:returns: Tuple containing (pair, profit_sum)
|
||||
"""
|
||||
best_pair = Trade.session.query(
|
||||
Trade.pair, func.sum(Trade.close_profit).label('profit_sum')
|
||||
|
@@ -281,11 +281,6 @@ class RPC:
|
||||
|
||||
best_pair = Trade.get_best_pair()
|
||||
|
||||
if not best_pair:
|
||||
raise RPCException('no closed trade')
|
||||
|
||||
bp_pair, bp_rate = best_pair
|
||||
|
||||
# Prepare data to display
|
||||
profit_closed_coin_sum = round(sum(profit_closed_coin), 8)
|
||||
profit_closed_percent = (round(mean(profit_closed_ratio) * 100, 2) if profit_closed_ratio
|
||||
@@ -304,6 +299,8 @@ class RPC:
|
||||
fiat_display_currency
|
||||
) if self._fiat_converter else 0
|
||||
|
||||
first_date = trades[0].open_date if trades else None
|
||||
last_date = trades[-1].open_date if trades else None
|
||||
num = float(len(durations) or 1)
|
||||
return {
|
||||
'profit_closed_coin': profit_closed_coin_sum,
|
||||
@@ -313,13 +310,14 @@ class RPC:
|
||||
'profit_all_percent': profit_all_percent,
|
||||
'profit_all_fiat': profit_all_fiat,
|
||||
'trade_count': len(trades),
|
||||
'first_trade_date': arrow.get(trades[0].open_date).humanize(),
|
||||
'first_trade_timestamp': int(trades[0].open_date.timestamp() * 1000),
|
||||
'latest_trade_date': arrow.get(trades[-1].open_date).humanize(),
|
||||
'latest_trade_timestamp': int(trades[-1].open_date.timestamp() * 1000),
|
||||
'closed_trade_count': len([t for t in trades if not t.is_open]),
|
||||
'first_trade_date': arrow.get(first_date).humanize() if first_date else '',
|
||||
'first_trade_timestamp': int(first_date.timestamp() * 1000) if first_date else 0,
|
||||
'latest_trade_date': arrow.get(last_date).humanize() if last_date else '',
|
||||
'latest_trade_timestamp': int(last_date.timestamp() * 1000) if last_date else 0,
|
||||
'avg_duration': str(timedelta(seconds=sum(durations) / num)).split('.')[0],
|
||||
'best_pair': bp_pair,
|
||||
'best_rate': round(bp_rate * 100, 2),
|
||||
'best_pair': best_pair[0] if best_pair else '',
|
||||
'best_rate': round(best_pair[1] * 100, 2) if best_pair else 0,
|
||||
}
|
||||
|
||||
def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict:
|
||||
|
@@ -311,38 +311,43 @@ class Telegram(RPC):
|
||||
stake_cur = self._config['stake_currency']
|
||||
fiat_disp_cur = self._config.get('fiat_display_currency', '')
|
||||
|
||||
try:
|
||||
stats = self._rpc_trade_statistics(
|
||||
stake_cur,
|
||||
fiat_disp_cur)
|
||||
profit_closed_coin = stats['profit_closed_coin']
|
||||
profit_closed_percent = stats['profit_closed_percent']
|
||||
profit_closed_fiat = stats['profit_closed_fiat']
|
||||
profit_all_coin = stats['profit_all_coin']
|
||||
profit_all_percent = stats['profit_all_percent']
|
||||
profit_all_fiat = stats['profit_all_fiat']
|
||||
trade_count = stats['trade_count']
|
||||
first_trade_date = stats['first_trade_date']
|
||||
latest_trade_date = stats['latest_trade_date']
|
||||
avg_duration = stats['avg_duration']
|
||||
best_pair = stats['best_pair']
|
||||
best_rate = stats['best_rate']
|
||||
stats = self._rpc_trade_statistics(
|
||||
stake_cur,
|
||||
fiat_disp_cur)
|
||||
profit_closed_coin = stats['profit_closed_coin']
|
||||
profit_closed_percent = stats['profit_closed_percent']
|
||||
profit_closed_fiat = stats['profit_closed_fiat']
|
||||
profit_all_coin = stats['profit_all_coin']
|
||||
profit_all_percent = stats['profit_all_percent']
|
||||
profit_all_fiat = stats['profit_all_fiat']
|
||||
trade_count = stats['trade_count']
|
||||
first_trade_date = stats['first_trade_date']
|
||||
latest_trade_date = stats['latest_trade_date']
|
||||
avg_duration = stats['avg_duration']
|
||||
best_pair = stats['best_pair']
|
||||
best_rate = stats['best_rate']
|
||||
if stats['trade_count'] == 0:
|
||||
markdown_msg = 'No trades yet.'
|
||||
else:
|
||||
# Message to display
|
||||
markdown_msg = "*ROI:* Close trades\n" \
|
||||
f"∙ `{profit_closed_coin:.8f} {stake_cur} "\
|
||||
f"({profit_closed_percent:.2f}%)`\n" \
|
||||
f"∙ `{profit_closed_fiat:.3f} {fiat_disp_cur}`\n" \
|
||||
f"*ROI:* All trades\n" \
|
||||
f"∙ `{profit_all_coin:.8f} {stake_cur} ({profit_all_percent:.2f}%)`\n" \
|
||||
f"∙ `{profit_all_fiat:.3f} {fiat_disp_cur}`\n" \
|
||||
f"*Total Trade Count:* `{trade_count}`\n" \
|
||||
f"*First Trade opened:* `{first_trade_date}`\n" \
|
||||
f"*Latest Trade opened:* `{latest_trade_date}`\n" \
|
||||
f"*Avg. Duration:* `{avg_duration}`\n" \
|
||||
f"*Best Performing:* `{best_pair}: {best_rate:.2f}%`"
|
||||
self._send_msg(markdown_msg)
|
||||
except RPCException as e:
|
||||
self._send_msg(str(e))
|
||||
if stats['closed_trade_count'] > 0:
|
||||
markdown_msg = ("*ROI:* Closed trades\n"
|
||||
f"∙ `{profit_closed_coin:.8f} {stake_cur} "
|
||||
f"({profit_closed_percent:.2f}%)`\n"
|
||||
f"∙ `{profit_closed_fiat:.3f} {fiat_disp_cur}`\n")
|
||||
else:
|
||||
markdown_msg = "`No closed trade` \n"
|
||||
|
||||
markdown_msg += (f"*ROI:* All trades\n"
|
||||
f"∙ `{profit_all_coin:.8f} {stake_cur} ({profit_all_percent:.2f}%)`\n"
|
||||
f"∙ `{profit_all_fiat:.3f} {fiat_disp_cur}`\n"
|
||||
f"*Total Trade Count:* `{trade_count}`\n"
|
||||
f"*First Trade opened:* `{first_trade_date}`\n"
|
||||
f"*Latest Trade opened:* `{latest_trade_date}`")
|
||||
if stats['closed_trade_count'] > 0:
|
||||
markdown_msg += (f"\n*Avg. Duration:* `{avg_duration}`\n"
|
||||
f"*Best Performing:* `{best_pair}: {best_rate:.2f}%`")
|
||||
self._send_msg(markdown_msg)
|
||||
|
||||
@authorized_only
|
||||
def _balance(self, update: Update, context: CallbackContext) -> None:
|
||||
|
Reference in New Issue
Block a user