Added Local RPC client

- added only "Daily" call so far, submitting for early review/feedback

This depends on zerorpc as a requirement.
simple examples here:
http://www.zerorpc.io/

Installed with pip3 install zerorpc

localRCP is enabled/disabled from within config.json
e.g
    "localrpc": {
        "enabled": true
       },

The server is enabled from within existing rpc manager
and makes use of the existing superclass (RPC)

Though making use of the existing hardwork done in rpc.py
It *should be easy to add the other Telegram calls into local_rpy_server.py

The server is wrapped in a thread to be non-blocking
The server and client accept serialised calls or not, used in daily to return json
The client can be used from command line or in a python script

As example, from cmdline for last 3 days Daily

/Users/creslin/PycharmProjects/freqtrade_new/.env/bin/zerorpc tcp://127.0.0.1:4242 daily 3
connecting to "tcp://127.0.0.1:4242"
False
('[\n'
 '    [\n'
 '        "2018-06-08",\n'
 '        "0.00000000 BTC",\n'
 '        "0.000 USDT",\n'
 '        "0 trade"\n'
 '    ],\n'
 '    [\n'
 '        "2018-06-07",\n'
 '        "0.00000000 BTC",\n'
 '        "0.000 USDT",\n'
 '        "0 trade"\n'
 '    ],\n'
 '    [\n'
 '        "2018-06-06",\n'
 '        "0.00000000 BTC",\n'
 '        "0.000 USDT",\n'
 '        "0 trade"\n'
 '    ]\n'
 ']')

Programitcally this would be:
import zerorpc

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")

for item in c.daily(3):
    print item
This commit is contained in:
creslinux 2018-06-08 18:35:01 +00:00
parent d23bcc435a
commit efbeabf141
3 changed files with 94 additions and 0 deletions

View File

@ -0,0 +1,83 @@
import threading
import time
import zerorpc
import logging
import json
from freqtrade.rpc.rpc import RPC
logger = logging.getLogger(__name__)
class LocalRPCControls(object):
"""
zeroRPC - allows local cmdline calls to super class in rpc.py
as used by Telegram.py
"""
def __init__(self, freqtrade) -> None:
"""
Initializes all enabled rpc modules
:param freqtrade: Instance of a freqtrade bot
:return: None
"""
self.freqtrade = freqtrade
self._config = freqtrade.config
# # Example of calling none serialed call
# # without decorator - left if as template while in dev for me
# def add_42(self, n):
# """ Add 42 to an integer argument to make it cooler, and return the
# result. """
# n = int(n)
# r = n + 42
# s = str(r)
# return s
@zerorpc.stream
def daily(self, timescale):
logger.info("LocalRPC - Daily Command Called")
timescale = int(timescale)
(error, stats) = RPC.rpc_daily_profit(self, timescale,
self._config['stake_currency'],
self._config['fiat_display_currency']
)
#Everything in stats to a string, serialised, then back to client.
stats = json.dumps(stats, indent=4, sort_keys=True, default=str)
return(error, stats)
class LocalRPCSuperWrap(RPC):
"""
Telegram, this class send messages to Telegram
"""
def __init__(self, freqtrade) -> None:
"""
Init the LocalRPCServer call, and init the super class RPC
:param freqtrade: Instance of a freqtrade bot
:return: None
"""
super().__init__(freqtrade)
""" Constructor
:type interval: int
:param interval: Check interval, in seconds
"""
self.interval = int(1)
thread = threading.Thread(target=self.run, args=(freqtrade,)) # extra comma as ref ! Tuple
thread.daemon = True # Daemonize thread
thread.start() # Start the execution
def run(self, freqtrade):
""" Method that runs forever """
self._config = freqtrade.config
# TODO add IP address / port to bind to in config.json and use in below.
while True:
# Do something
logger.info('Starting Local RPC Listener')
s = zerorpc.Server(LocalRPCControls(freqtrade))
s.bind("tcp://0.0.0.0:4242")
s.run()
time.sleep(self.interval)

View File

@ -3,8 +3,10 @@ This module contains class to manage RPC communications (Telegram, Slack, ...)
""" """
from typing import Any, List from typing import Any, List
import logging import logging
import time
from freqtrade.rpc.telegram import Telegram from freqtrade.rpc.telegram import Telegram
from freqtrade.rpc.local_rpc_server import LocalRPCSuperWrap
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -36,6 +38,12 @@ class RPCManager(object):
self.registered_modules.append('telegram') self.registered_modules.append('telegram')
self.telegram = Telegram(self.freqtrade) self.telegram = Telegram(self.freqtrade)
# Added another RPC client - for cmdline local client.
# Uses existing superclass RPC build for Telegram
if self.freqtrade.config['localrpc'].get('enabled', False):
self.localRPC = LocalRPCSuperWrap(self.freqtrade)
time.sleep(1)
def cleanup(self) -> None: def cleanup(self) -> None:
""" """
Stops all enabled rpc modules Stops all enabled rpc modules

View File

@ -23,3 +23,6 @@ coinmarketcap==5.0.3
# Required for plotting data # Required for plotting data
#plotly==2.3.0 #plotly==2.3.0
#Added for localRCP
zerorpc==