use dict as argument for rpc.send_msg

This commit is contained in:
gcarq 2018-06-25 00:04:27 +02:00
parent 85851bd026
commit 127e50c932
9 changed files with 91 additions and 72 deletions

View File

@ -93,7 +93,9 @@ class FreqtradeBot(object):
# Log state transition
state = self.state
if state != old_state:
self.rpc.send_msg(f'*Status:* `{state.name.lower()}`')
self.rpc.send_msg({
'status': f'{state.name.lower()}'
})
logger.info('Changing state to: %s', state.name)
if state == State.STOPPED:
@ -169,9 +171,9 @@ class FreqtradeBot(object):
except OperationalException:
tb = traceback.format_exc()
hint = 'Issue `/start` if you think it is safe to restart.'
self.rpc.send_msg(
f'*Status:* OperationalException:\n```\n{tb}```{hint}'
)
self.rpc.send_msg({
'status': f'OperationalException:\n```\n{tb}```{hint}'
})
logger.exception('OperationalException. Stopping trader ...')
self.state = State.STOPPED
return state_changed
@ -356,11 +358,12 @@ class FreqtradeBot(object):
)
# Create trade entity and return
self.rpc.send_msg(
f"""*{exc_name}:* Buying [{pair_s}]({pair_url}) \
with limit `{buy_limit:.8f} ({stake_amount:.6f} \
{stake_currency}, {stake_amount_fiat:.3f} {fiat_currency})`"""
)
self.rpc.send_msg({
'status':
f"""*{exc_name}:* Buying [{pair_s}]({pair_url}) \
with limit `{buy_limit:.8f} ({stake_amount:.6f} \
{stake_currency}, {stake_amount_fiat:.3f} {fiat_currency})`"""
})
# Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker')
trade = Trade(
@ -540,7 +543,9 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
Trade.session.delete(trade)
Trade.session.flush()
logger.info('Buy order timeout for %s.', trade)
self.rpc.send_msg(f'*Timeout:* Unfilled buy order for {pair_s} cancelled')
self.rpc.send_msg({
'status': f'Unfilled buy order for {pair_s} cancelled due to timeout'
})
return True
# if trade is partially complete, edit the stake details for the trade
@ -549,7 +554,9 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
trade.stake_amount = trade.amount * trade.open_rate
trade.open_order_id = None
logger.info('Partial buy order timeout for %s.', trade)
self.rpc.send_msg(f'*Timeout:* Remaining buy order for {pair_s} cancelled')
self.rpc.send_msg({
'status': f'Remaining buy order for {pair_s} cancelled due to timeout'
})
return False
# FIX: 20180110, should cancel_order() be cond. or unconditionally called?
@ -567,7 +574,9 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
trade.close_date = None
trade.is_open = True
trade.open_order_id = None
self.rpc.send_msg(f'*Timeout:* Unfilled sell order for {pair_s} cancelled')
self.rpc.send_msg({
'status': f'Unfilled sell order for {pair_s} cancelled due to timeout'
})
logger.info('Sell order timeout for %s.', trade)
return True
@ -627,5 +636,5 @@ with limit `{buy_limit:.8f} ({stake_amount:.6f} \
)
# Send the message
self.rpc.send_msg(message)
self.rpc.send_msg({'status': message})
Trade.session.flush()

View File

@ -59,7 +59,9 @@ def main(sysargv: List[str]) -> None:
logger.exception('Fatal exception!')
finally:
if freqtrade:
freqtrade.rpc.send_msg('*Status:* `Process died ...`')
freqtrade.rpc.send_msg({
'status': 'process died'
})
freqtrade.cleanup()
sys.exit(return_code)
@ -73,11 +75,9 @@ def reconfigure(freqtrade: FreqtradeBot, args: Namespace) -> FreqtradeBot:
# Create new instance
freqtrade = FreqtradeBot(Configuration(args).get_config())
freqtrade.rpc.send_msg(
'*Status:* `Config reloaded ...`'.format(
freqtrade.state.name.lower()
)
)
freqtrade.rpc.send_msg({
'status': 'config reloaded'
})
return freqtrade

View File

@ -2,6 +2,7 @@ import json
import threading
import logging
# import json
from typing import Dict
from flask import Flask, request, jsonify
# from flask_restful import Resource, Api
@ -81,7 +82,7 @@ class ApiServer(RPC):
def cleanup(self) -> None:
pass
def send_msg(self, msg: str) -> None:
def send_msg(self, msg: Dict[str, str]) -> None:
pass
"""

View File

@ -59,7 +59,7 @@ class RPC(object):
""" Cleanup pending module resources """
@abstractmethod
def send_msg(self, msg: str) -> None:
def send_msg(self, msg: Dict[str, str]) -> None:
""" Sends a message to all registered rpc modules """
def _rpc_trade_status(self) -> List[Dict]:

View File

@ -2,7 +2,7 @@
This module contains class to manage RPC communications (Telegram, Slack, Rest ....)
"""
import logging
from typing import List
from typing import List, Dict
from freqtrade.rpc.rpc import RPC
@ -38,11 +38,14 @@ class RPCManager(object):
mod.cleanup()
del mod
def send_msg(self, msg: str) -> None:
def send_msg(self, msg: Dict[str, str]) -> None:
"""
Send given markdown message to all registered rpc modules
:param msg: message
:return: None
Send given message to all registered rpc modules.
A message consists of one or more key value pairs of strings.
e.g.:
{
'status': 'stopping bot'
}
"""
logger.info('Sending rpc message: %s', msg)
for mod in self.registered_modules:

View File

@ -4,7 +4,7 @@
This module manage Telegram communication
"""
import logging
from typing import Any, Callable
from typing import Any, Callable, Dict
import arrow
from pandas import DataFrame
@ -113,9 +113,9 @@ class Telegram(RPC):
"""
self._updater.stop()
def send_msg(self, msg: str) -> None:
def send_msg(self, msg: Dict[str, str]) -> None:
""" Send a message to telegram channel """
self._send_msg(msg)
self._send_msg('*Status:* `{status}`'.format(**msg))
@authorized_only
def _status(self, bot: Bot, update: Update) -> None:

View File

@ -102,9 +102,9 @@ def test_send_msg_telegram_disabled(mocker, default_conf, caplog) -> None:
freqtradebot = get_patched_freqtradebot(mocker, conf)
rpc_manager = RPCManager(freqtradebot)
rpc_manager.send_msg('test')
rpc_manager.send_msg({'status': 'test'})
assert log_has('Sending rpc message: test', caplog.record_tuples)
assert log_has("Sending rpc message: {'status': 'test'}", caplog.record_tuples)
assert telegram_mock.call_count == 0
@ -117,7 +117,7 @@ def test_send_msg_telegram_enabled(mocker, default_conf, caplog) -> None:
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
rpc_manager = RPCManager(freqtradebot)
rpc_manager.send_msg('test')
rpc_manager.send_msg({'status': 'test'})
assert log_has('Sending rpc message: test', caplog.record_tuples)
assert log_has("Sending rpc message: {'status': 'test'}", caplog.record_tuples)
assert telegram_mock.call_count == 1

View File

@ -700,12 +700,13 @@ def test_forcesell_handle(default_conf, update, ticker, fee,
telegram._forcesell(bot=MagicMock(), update=update)
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert 'Amount' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001172' in rpc_mock.call_args_list[-1][0][0]
assert 'profit: 6.11%, 0.00006126' in rpc_mock.call_args_list[-1][0][0]
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert 'Amount' in last_call
assert '0.00001172' in last_call
assert 'profit: 6.11%, 0.00006126' in last_call
assert '0.919 USD' in last_call
def test_forcesell_down_handle(default_conf, update, ticker, fee,
@ -745,13 +746,14 @@ def test_forcesell_down_handle(default_conf, update, ticker, fee,
update.message.text = '/forcesell 1'
telegram._forcesell(bot=MagicMock(), update=update)
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert 'Amount' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001044' in rpc_mock.call_args_list[-1][0][0]
assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0]
assert '-0.824 USD' in rpc_mock.call_args_list[-1][0][0]
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert 'Amount' in last_call
assert '0.00001044' in last_call
assert 'loss: -5.48%, -0.00005492' in last_call
assert '-0.824 USD' in last_call
def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker) -> None:
@ -785,9 +787,9 @@ def test_forcesell_all_handle(default_conf, update, ticker, fee, markets, mocker
assert rpc_mock.call_count == 4
for args in rpc_mock.call_args_list:
assert '0.00001098' in args[0][0]
assert 'loss: -0.59%, -0.00000591 BTC' in args[0][0]
assert '-0.089 USD' in args[0][0]
assert '0.00001098' in args[0][0]['status']
assert 'loss: -0.59%, -0.00000591 BTC' in args[0][0]['status']
assert '-0.089 USD' in args[0][0]['status']
def test_forcesell_handle_invalid(default_conf, update, mocker) -> None:

View File

@ -725,7 +725,7 @@ def test_process_operational_exception(default_conf, ticker, markets, mocker) ->
result = freqtrade._process()
assert result is False
assert freqtrade.state == State.STOPPED
assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]
assert 'OperationalException' in msg_mock.call_args_list[-1][0][0]['status']
def test_process_trade_handling(
@ -1345,13 +1345,14 @@ def test_execute_sell_up(default_conf, ticker, fee, ticker_sell_up, markets, moc
freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'])
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert 'Amount' in rpc_mock.call_args_list[-1][0][0]
assert 'Profit' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001172' in rpc_mock.call_args_list[-1][0][0]
assert 'profit: 6.11%, 0.00006126' in rpc_mock.call_args_list[-1][0][0]
assert '0.919 USD' in rpc_mock.call_args_list[-1][0][0]
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert 'Amount' in last_call
assert 'Profit' in last_call
assert '0.00001172' in last_call
assert 'profit: 6.11%, 0.00006126' in last_call
assert '0.919 USD' in last_call
def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets, mocker) -> None:
@ -1387,12 +1388,13 @@ def test_execute_sell_down(default_conf, ticker, fee, ticker_sell_down, markets,
freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'])
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert 'Amount' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001044' in rpc_mock.call_args_list[-1][0][0]
assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0]
assert '-0.824 USD' in rpc_mock.call_args_list[-1][0][0]
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert 'Amount' in last_call
assert '0.00001044' in last_call
assert 'loss: -5.48%, -0.00005492' in last_call
assert '-0.824 USD' in last_call
def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
@ -1429,12 +1431,13 @@ def test_execute_sell_without_conf_sell_up(default_conf, ticker, fee,
freqtrade.execute_sell(trade=trade, limit=ticker_sell_up()['bid'])
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert 'Amount' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001172' in rpc_mock.call_args_list[-1][0][0]
assert '(profit: 6.11%, 0.00006126)' in rpc_mock.call_args_list[-1][0][0]
assert 'USD' not in rpc_mock.call_args_list[-1][0][0]
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert 'Amount' in last_call
assert '0.00001172' in last_call
assert '(profit: 6.11%, 0.00006126)' in last_call
assert 'USD' not in last_call
def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
@ -1471,10 +1474,11 @@ def test_execute_sell_without_conf_sell_down(default_conf, ticker, fee,
freqtrade.execute_sell(trade=trade, limit=ticker_sell_down()['bid'])
assert rpc_mock.call_count == 2
assert 'Selling' in rpc_mock.call_args_list[-1][0][0]
assert '[ETH/BTC]' in rpc_mock.call_args_list[-1][0][0]
assert '0.00001044' in rpc_mock.call_args_list[-1][0][0]
assert 'loss: -5.48%, -0.00005492' in rpc_mock.call_args_list[-1][0][0]
last_call = rpc_mock.call_args_list[-1][0][0]['status']
assert 'Selling' in last_call
assert '[ETH/BTC]' in last_call
assert '0.00001044' in last_call
assert 'loss: -5.48%, -0.00005492' in last_call
def test_sell_profit_only_enable_profit(default_conf, limit_buy_order,