save rpc instances only in registered_modules, add some abstract methods

This commit is contained in:
gcarq
2018-06-08 03:49:09 +02:00
parent 13ba68acc6
commit cddb062db5
6 changed files with 95 additions and 104 deletions

View File

@@ -2,21 +2,21 @@
This module contains class to define a RPC communications
"""
import logging
from abc import abstractmethod
from datetime import datetime, timedelta, date
from decimal import Decimal
from typing import Dict, Tuple, Any
import arrow
import sqlalchemy as sql
from pandas import DataFrame
from numpy import mean, nan_to_num
from pandas import DataFrame
from freqtrade import exchange
from freqtrade.misc import shorten_date
from freqtrade.persistence import Trade
from freqtrade.state import State
logger = logging.getLogger(__name__)
@@ -32,6 +32,19 @@ class RPC(object):
"""
self.freqtrade = freqtrade
@abstractmethod
def cleanup(self) -> str:
""" Cleanup pending module resources """
@property
@abstractmethod
def name(self) -> None:
""" Returns the lowercase name of this module """
@abstractmethod
def send_msg(self, msg: str) -> None:
""" Sends a message to all registered rpc modules """
def rpc_trade_status(self) -> Tuple[bool, Any]:
"""
Below follows the RPC backend it is prefixed with rpc_ to raise awareness that it is

View File

@@ -1,12 +1,12 @@
"""
This module contains class to manage RPC communications (Telegram, Slack, ...)
"""
from typing import Any, List
import logging
from typing import List
from freqtrade.rpc.rpc import RPC
from freqtrade.rpc.telegram import Telegram
logger = logging.getLogger(__name__)
@@ -15,36 +15,21 @@ class RPCManager(object):
Class to manage RPC objects (Telegram, Slack, ...)
"""
def __init__(self, freqtrade) -> None:
"""
Initializes all enabled rpc modules
:param config: config to use
:return: None
"""
self.freqtrade = freqtrade
""" Initializes all enabled rpc modules """
self.registered_modules: List[RPC] = []
self.registered_modules: List[str] = []
self.telegram: Any = None
self._init()
def _init(self) -> None:
"""
Init RPC modules
:return:
"""
if self.freqtrade.config['telegram'].get('enabled', False):
# Enable telegram
if freqtrade.config['telegram'].get('enabled', False):
logger.info('Enabling rpc.telegram ...')
self.registered_modules.append('telegram')
self.telegram = Telegram(self.freqtrade)
self.registered_modules.append(Telegram(freqtrade))
def cleanup(self) -> None:
"""
Stops all enabled rpc modules
:return: None
"""
if 'telegram' in self.registered_modules:
logger.info('Cleaning up rpc.telegram ...')
self.registered_modules.remove('telegram')
self.telegram.cleanup()
""" Stops all enabled rpc modules """
for mod in self.registered_modules:
logger.info('Cleaning up rpc.%s ...', mod.name)
mod.cleanup()
self.registered_modules = []
def send_msg(self, msg: str) -> None:
"""
@@ -52,6 +37,7 @@ class RPCManager(object):
:param msg: message
:return: None
"""
logger.info(msg)
if 'telegram' in self.registered_modules:
self.telegram.send_msg(msg)
logger.info('Sending rpc message: %s', msg)
for mod in self.registered_modules:
logger.debug('Forwarding message to rpc.%s', mod.name)
mod.send_msg(msg)

View File

@@ -14,7 +14,6 @@ from telegram.ext import CommandHandler, Updater
from freqtrade.__init__ import __version__
from freqtrade.rpc.rpc import RPC
logger = logging.getLogger(__name__)
@@ -57,6 +56,11 @@ class Telegram(RPC):
"""
Telegram, this class send messages to Telegram
"""
@property
def name(self) -> str:
return "telegram"
def __init__(self, freqtrade) -> None:
"""
Init the Telegram call, and init the super class RPC
@@ -120,6 +124,10 @@ class Telegram(RPC):
self._updater.stop()
def send_msg(self, msg: str) -> None:
""" Send a message to telegram channel """
self._send_msg(msg)
def is_enabled(self) -> bool:
"""
Returns True if the telegram module is activated, False otherwise
@@ -146,10 +154,10 @@ class Telegram(RPC):
# Fetch open trade
(error, trades) = self.rpc_trade_status()
if error:
self.send_msg(trades, bot=bot)
self._send_msg(trades, bot=bot)
else:
for trademsg in trades:
self.send_msg(trademsg, bot=bot)
self._send_msg(trademsg, bot=bot)
@authorized_only
def _status_table(self, bot: Bot, update: Update) -> None:
@@ -163,12 +171,12 @@ class Telegram(RPC):
# Fetch open trade
(err, df_statuses) = self.rpc_status_table()
if err:
self.send_msg(df_statuses, bot=bot)
self._send_msg(df_statuses, bot=bot)
else:
message = tabulate(df_statuses, headers='keys', tablefmt='simple')
message = "<pre>{}</pre>".format(message)
self.send_msg(message, parse_mode=ParseMode.HTML)
self._send_msg(message, parse_mode=ParseMode.HTML)
@authorized_only
def _daily(self, bot: Bot, update: Update) -> None:
@@ -189,7 +197,7 @@ class Telegram(RPC):
self._config['fiat_display_currency']
)
if error:
self.send_msg(stats, bot=bot)
self._send_msg(stats, bot=bot)
else:
stats = tabulate(stats,
headers=[
@@ -203,7 +211,7 @@ class Telegram(RPC):
timescale,
stats
)
self.send_msg(message, bot=bot, parse_mode=ParseMode.HTML)
self._send_msg(message, bot=bot, parse_mode=ParseMode.HTML)
@authorized_only
def _profit(self, bot: Bot, update: Update) -> None:
@@ -219,7 +227,7 @@ class Telegram(RPC):
self._config['fiat_display_currency']
)
if error:
self.send_msg(stats, bot=bot)
self._send_msg(stats, bot=bot)
return
# Message to display
@@ -250,7 +258,7 @@ class Telegram(RPC):
best_pair=stats['best_pair'],
best_rate=stats['best_rate']
)
self.send_msg(markdown_msg, bot=bot)
self._send_msg(markdown_msg, bot=bot)
@authorized_only
def _balance(self, bot: Bot, update: Update) -> None:
@@ -259,7 +267,7 @@ class Telegram(RPC):
"""
(error, result) = self.rpc_balance(self._config['fiat_display_currency'])
if error:
self.send_msg('`All balances are zero.`')
self._send_msg('`All balances are zero.`')
return
(currencys, total, symbol, value) = result
@@ -274,7 +282,7 @@ class Telegram(RPC):
output += "\n*Estimated Value*:\n" \
"\t`BTC: {0: .8f}`\n" \
"\t`{1}: {2: .2f}`\n".format(total, symbol, value)
self.send_msg(output)
self._send_msg(output)
@authorized_only
def _start(self, bot: Bot, update: Update) -> None:
@@ -287,7 +295,7 @@ class Telegram(RPC):
"""
(error, msg) = self.rpc_start()
if error:
self.send_msg(msg, bot=bot)
self._send_msg(msg, bot=bot)
@authorized_only
def _stop(self, bot: Bot, update: Update) -> None:
@@ -299,7 +307,7 @@ class Telegram(RPC):
:return: None
"""
(error, msg) = self.rpc_stop()
self.send_msg(msg, bot=bot)
self._send_msg(msg, bot=bot)
@authorized_only
def _reload_conf(self, bot: Bot, update: Update) -> None:
@@ -326,7 +334,7 @@ class Telegram(RPC):
trade_id = update.message.text.replace('/forcesell', '').strip()
(error, message) = self.rpc_forcesell(trade_id)
if error:
self.send_msg(message, bot=bot)
self._send_msg(message, bot=bot)
return
@authorized_only
@@ -340,7 +348,7 @@ class Telegram(RPC):
"""
(error, trades) = self.rpc_performance()
if error:
self.send_msg(trades, bot=bot)
self._send_msg(trades, bot=bot)
return
stats = '\n'.join('{index}.\t<code>{pair}\t{profit:.2f}% ({count})</code>'.format(
@@ -350,7 +358,7 @@ class Telegram(RPC):
count=trade['count']
) for i, trade in enumerate(trades))
message = '<b>Performance:</b>\n{}'.format(stats)
self.send_msg(message, parse_mode=ParseMode.HTML)
self._send_msg(message, parse_mode=ParseMode.HTML)
@authorized_only
def _count(self, bot: Bot, update: Update) -> None:
@@ -363,7 +371,7 @@ class Telegram(RPC):
"""
(error, trades) = self.rpc_count()
if error:
self.send_msg(trades, bot=bot)
self._send_msg(trades, bot=bot)
return
message = tabulate({
@@ -373,7 +381,7 @@ class Telegram(RPC):
}, headers=['current', 'max', 'total stake'], tablefmt='simple')
message = "<pre>{}</pre>".format(message)
logger.debug(message)
self.send_msg(message, parse_mode=ParseMode.HTML)
self._send_msg(message, parse_mode=ParseMode.HTML)
@authorized_only
def _help(self, bot: Bot, update: Update) -> None:
@@ -399,7 +407,7 @@ class Telegram(RPC):
"*/help:* `This help message`\n" \
"*/version:* `Show version`"
self.send_msg(message, bot=bot)
self._send_msg(message, bot=bot)
@authorized_only
def _version(self, bot: Bot, update: Update) -> None:
@@ -410,10 +418,10 @@ class Telegram(RPC):
:param update: message update
:return: None
"""
self.send_msg('*Version:* `{}`'.format(__version__), bot=bot)
self._send_msg('*Version:* `{}`'.format(__version__), bot=bot)
def send_msg(self, msg: str, bot: Bot = None,
parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
def _send_msg(self, msg: str, bot: Bot = None,
parse_mode: ParseMode = ParseMode.MARKDOWN) -> None:
"""
Send given markdown message
:param msg: message