From efbeabf14101d205b9035000c02197914f909b2b Mon Sep 17 00:00:00 2001 From: creslinux Date: Fri, 8 Jun 2018 18:35:01 +0000 Subject: [PATCH] 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 --- freqtrade/rpc/local_rpc_server.py | 83 +++++++++++++++++++++++++++++++ freqtrade/rpc/rpc_manager.py | 8 +++ requirements.txt | 3 ++ 3 files changed, 94 insertions(+) create mode 100644 freqtrade/rpc/local_rpc_server.py diff --git a/freqtrade/rpc/local_rpc_server.py b/freqtrade/rpc/local_rpc_server.py new file mode 100644 index 000000000..50b6b3a6d --- /dev/null +++ b/freqtrade/rpc/local_rpc_server.py @@ -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) diff --git a/freqtrade/rpc/rpc_manager.py b/freqtrade/rpc/rpc_manager.py index 58e9bf2b9..b89e8a0d5 100644 --- a/freqtrade/rpc/rpc_manager.py +++ b/freqtrade/rpc/rpc_manager.py @@ -3,8 +3,10 @@ This module contains class to manage RPC communications (Telegram, Slack, ...) """ from typing import Any, List import logging +import time from freqtrade.rpc.telegram import Telegram +from freqtrade.rpc.local_rpc_server import LocalRPCSuperWrap logger = logging.getLogger(__name__) @@ -36,6 +38,12 @@ class RPCManager(object): self.registered_modules.append('telegram') 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: """ Stops all enabled rpc modules diff --git a/requirements.txt b/requirements.txt index 5f5183321..4f4924225 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,3 +23,6 @@ coinmarketcap==5.0.3 # Required for plotting data #plotly==2.3.0 + +#Added for localRCP +zerorpc== \ No newline at end of file