remove _rpc_status_table and reuse _rpc_status instead
This commit is contained in:
parent
4aab55d27b
commit
77d53b0b7c
@ -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]]:
|
||||||
|
@ -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,21 +140,25 @@ class Telegram(RPC):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
results = self._rpc_trade_status()
|
results = self._rpc_trade_status()
|
||||||
messages = [
|
messages = []
|
||||||
"*Trade ID:* `{trade_id}`\n"
|
for result in results:
|
||||||
"*Current Pair:* [{pair}]({market_url})\n"
|
result['open_date'] = arrow.get(result['open_date']).humanize()
|
||||||
"*Open Since:* `{date}`\n"
|
messages.append(
|
||||||
"*Amount:* `{amount}`\n"
|
"*Trade ID:* `{trade_id}`\n"
|
||||||
"*Open Rate:* `{open_rate:.8f}`\n"
|
"*Current Pair:* [{pair}]({market_url})\n"
|
||||||
"*Close Rate:* `{close_rate}`\n"
|
"*Open Since:* `{open_date}`\n"
|
||||||
"*Current Rate:* `{current_rate:.8f}`\n"
|
"*Amount:* `{amount}`\n"
|
||||||
"*Close Profit:* `{close_profit}`\n"
|
"*Open Rate:* `{open_rate:.8f}`\n"
|
||||||
"*Current Profit:* `{current_profit:.2f}%`\n"
|
"*Close Rate:* `{close_rate}`\n"
|
||||||
"*Open Order:* `{open_order}`".format(**result)
|
"*Current Rate:* `{current_rate:.8f}`\n"
|
||||||
for result in results
|
"*Close Profit:* `{close_profit}`\n"
|
||||||
]
|
"*Current Profit:* `{current_profit:.2f}%`\n"
|
||||||
|
"*Open Order:* `{open_order}`".format(**result)
|
||||||
|
)
|
||||||
|
|
||||||
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:
|
||||||
|
@ -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:
|
||||||
"""
|
"""
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user