remove _rpc_status_table and reuse _rpc_status instead

This commit is contained in:
gcarq 2018-06-23 09:28:13 +02:00
parent 4aab55d27b
commit 77d53b0b7c
4 changed files with 46 additions and 77 deletions

View File

@ -10,10 +10,8 @@ from typing import Dict, Any, List
import arrow import arrow
import sqlalchemy as sql import sqlalchemy as sql
from numpy import mean, nan_to_num from numpy import mean, nan_to_num
from pandas import DataFrame
from freqtrade import exchange from freqtrade import exchange
from freqtrade.misc import shorten_date
from freqtrade.persistence import Trade from freqtrade.persistence import Trade
from freqtrade.state import State from freqtrade.state import State
@ -93,7 +91,7 @@ class RPC(object):
trade_id=trade.id, trade_id=trade.id,
pair=trade.pair, pair=trade.pair,
market_url=exchange.get_pair_detail_url(trade.pair), market_url=exchange.get_pair_detail_url(trade.pair),
date=arrow.get(trade.open_date).humanize(), open_date=arrow.get(trade.open_date),
open_rate=trade.open_rate, open_rate=trade.open_rate,
close_rate=trade.close_rate, close_rate=trade.close_rate,
current_rate=current_rate, current_rate=current_rate,
@ -106,29 +104,6 @@ class RPC(object):
)) ))
return results return results
def _rpc_status_table(self) -> DataFrame:
trades = Trade.query.filter(Trade.is_open.is_(True)).all()
if self._freqtrade.state != State.RUNNING:
raise RPCException('trader is not running')
elif not trades:
raise RPCException('no active order')
else:
trades_list = []
for trade in trades:
# calculate profit and send message to user
current_rate = exchange.get_ticker(trade.pair, False)['bid']
trades_list.append([
trade.id,
trade.pair,
shorten_date(arrow.get(trade.open_date).humanize(only_distance=True)),
'{:.2f}%'.format(100 * trade.calc_profit_percent(current_rate))
])
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
def _rpc_daily_profit( def _rpc_daily_profit(
self, timescale: int, self, timescale: int,
stake_currency: str, fiat_display_currency: str) -> List[List[Any]]: stake_currency: str, fiat_display_currency: str) -> List[List[Any]]:

View File

@ -6,12 +6,15 @@ This module manage Telegram communication
import logging import logging
from typing import Any, Callable from typing import Any, Callable
import arrow
from pandas import DataFrame
from tabulate import tabulate from tabulate import tabulate
from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update from telegram import Bot, ParseMode, ReplyKeyboardMarkup, Update
from telegram.error import NetworkError, TelegramError from telegram.error import NetworkError, TelegramError
from telegram.ext import CommandHandler, Updater from telegram.ext import CommandHandler, Updater
from freqtrade.__init__ import __version__ from freqtrade.__init__ import __version__
from freqtrade.misc import shorten_date
from freqtrade.rpc.rpc import RPC, RPCException from freqtrade.rpc.rpc import RPC, RPCException
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -137,10 +140,13 @@ class Telegram(RPC):
try: try:
results = self._rpc_trade_status() results = self._rpc_trade_status()
messages = [ messages = []
for result in results:
result['open_date'] = arrow.get(result['open_date']).humanize()
messages.append(
"*Trade ID:* `{trade_id}`\n" "*Trade ID:* `{trade_id}`\n"
"*Current Pair:* [{pair}]({market_url})\n" "*Current Pair:* [{pair}]({market_url})\n"
"*Open Since:* `{date}`\n" "*Open Since:* `{open_date}`\n"
"*Amount:* `{amount}`\n" "*Amount:* `{amount}`\n"
"*Open Rate:* `{open_rate:.8f}`\n" "*Open Rate:* `{open_rate:.8f}`\n"
"*Close Rate:* `{close_rate}`\n" "*Close Rate:* `{close_rate}`\n"
@ -148,10 +154,11 @@ class Telegram(RPC):
"*Close Profit:* `{close_profit}`\n" "*Close Profit:* `{close_profit}`\n"
"*Current Profit:* `{current_profit:.2f}%`\n" "*Current Profit:* `{current_profit:.2f}%`\n"
"*Open Order:* `{open_order}`".format(**result) "*Open Order:* `{open_order}`".format(**result)
for result in results )
]
for msg in messages: for msg in messages:
self._send_msg(msg, bot=bot) self._send_msg(msg, bot=bot)
except RPCException as e: except RPCException as e:
self._send_msg(str(e), bot=bot) self._send_msg(str(e), bot=bot)
@ -165,7 +172,20 @@ class Telegram(RPC):
:return: None :return: None
""" """
try: try:
df_statuses = self._rpc_status_table()
results = self._rpc_trade_status()
data = [
[
result['trade_id'],
result['pair'],
shorten_date(arrow.get(result['open_date']).humanize(only_distance=True)),
result['current_profit'],
] for result in results
]
columns = ['ID', 'Pair', 'Since', 'Profit']
df_statuses = DataFrame.from_records(data, columns=columns)
df_statuses = df_statuses.set_index(columns[0])
message = tabulate(df_statuses, headers='keys', tablefmt='simple') message = tabulate(df_statuses, headers='keys', tablefmt='simple')
self._send_msg("<pre>{}</pre>".format(message), parse_mode=ParseMode.HTML) self._send_msg("<pre>{}</pre>".format(message), parse_mode=ParseMode.HTML)
except RPCException as e: except RPCException as e:

View File

@ -7,6 +7,7 @@ Unit test file for rpc/rpc.py
from datetime import datetime from datetime import datetime
from unittest.mock import MagicMock from unittest.mock import MagicMock
import arrow
import pytest import pytest
from freqtrade.freqtradebot import FreqtradeBot from freqtrade.freqtradebot import FreqtradeBot
@ -39,6 +40,10 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
get_fee=fee get_fee=fee
) )
now = arrow.utcnow()
now_mock = mocker.patch('freqtrade.freqtradebot.datetime', MagicMock())
now_mock.utcnow = lambda: now.datetime
freqtradebot = FreqtradeBot(default_conf) freqtradebot = FreqtradeBot(default_conf)
rpc = RPC(freqtradebot) rpc = RPC(freqtradebot)
@ -57,7 +62,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
'trade_id': 1, 'trade_id': 1,
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'market_url': 'https://bittrex.com/Market/Index?MarketName=BTC-ETH', 'market_url': 'https://bittrex.com/Market/Index?MarketName=BTC-ETH',
'date': 'just now', 'open_date': now,
'open_rate': 1.099e-05, 'open_rate': 1.099e-05,
'close_rate': None, 'close_rate': None,
'current_rate': 1.098e-05, 'current_rate': 1.098e-05,
@ -68,38 +73,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
} == results[0] } == results[0]
def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
"""
Test rpc_status_table() method
"""
patch_get_signal(mocker, (True, False))
patch_coinmarketcap(mocker)
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
mocker.patch.multiple(
'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(),
get_ticker=ticker,
get_fee=fee
)
freqtradebot = FreqtradeBot(default_conf)
rpc = RPC(freqtradebot)
freqtradebot.state = State.STOPPED
with pytest.raises(RPCException, match=r'.*trader is not running*'):
rpc._rpc_status_table()
freqtradebot.state = State.RUNNING
with pytest.raises(RPCException, match=r'.*no active order*'):
rpc._rpc_status_table()
freqtradebot.create_trade()
result = rpc._rpc_status_table()
assert 'just now' in result['Since'].all()
assert 'ETH/BTC' in result['Pair'].all()
assert '-0.59%' in result['Profit'].all()
def test_rpc_daily_profit(default_conf, update, ticker, fee, def test_rpc_daily_profit(default_conf, update, ticker, fee,
limit_buy_order, limit_sell_order, mocker) -> None: limit_buy_order, limit_sell_order, mocker) -> None:
""" """

View File

@ -213,7 +213,7 @@ def test_status(default_conf, update, mocker, fee, ticker) -> None:
'trade_id': 1, 'trade_id': 1,
'pair': 'ETH/BTC', 'pair': 'ETH/BTC',
'market_url': 'https://bittrex.com/Market/Index?MarketName=BTC-ETH', 'market_url': 'https://bittrex.com/Market/Index?MarketName=BTC-ETH',
'date': 'just now', 'open_date': datetime.utcnow(),
'open_rate': 1.099e-05, 'open_rate': 1.099e-05,
'close_rate': None, 'close_rate': None,
'current_rate': 1.098e-05, 'current_rate': 1.098e-05,
@ -289,7 +289,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
assert '[ETH/BTC]' in msg_mock.call_args_list[0][0][0] assert '[ETH/BTC]' in msg_mock.call_args_list[0][0][0]
def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None: def test_status_table_handle(default_conf, limit_buy_order, update, ticker, fee, mocker) -> None:
""" """
Test _status_table() method Test _status_table() method
""" """
@ -299,7 +299,8 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
'freqtrade.freqtradebot.exchange', 'freqtrade.freqtradebot.exchange',
validate_pairs=MagicMock(), validate_pairs=MagicMock(),
get_ticker=ticker, get_ticker=ticker,
buy=MagicMock(return_value={'id': 'mocked_order_id'}), buy=MagicMock(return_value={'id': limit_buy_order['id']}),
get_order=MagicMock(return_value=limit_buy_order),
get_fee=fee, get_fee=fee,
) )
msg_mock = MagicMock() msg_mock = MagicMock()
@ -324,7 +325,7 @@ def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
freqtradebot.state = State.RUNNING freqtradebot.state = State.RUNNING
telegram._status_table(bot=MagicMock(), update=update) telegram._status_table(bot=MagicMock(), update=update)
assert msg_mock.call_count == 1 assert msg_mock.call_count == 1
assert 'no active order' in msg_mock.call_args_list[0][0][0] assert 'no active trade' in msg_mock.call_args_list[0][0][0]
msg_mock.reset_mock() msg_mock.reset_mock()
# Create some test data # Create some test data