From ecd66da969b45e10a7cc9d7f7b5c1120f934536d Mon Sep 17 00:00:00 2001 From: Michael Robinson Date: Thu, 11 May 2017 21:32:26 +0100 Subject: [PATCH 01/11] Adding tools dir and a simple script to analyse lending history --- tools/analyseLendingHistory.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 tools/analyseLendingHistory.py diff --git a/tools/analyseLendingHistory.py b/tools/analyseLendingHistory.py new file mode 100644 index 00000000..50b632d0 --- /dev/null +++ b/tools/analyseLendingHistory.py @@ -0,0 +1,20 @@ +import pandas as pd +import sys + +curs = ['BTC', 'BTS', 'CLAM', 'DASH', 'DOGE', 'ETH', 'FCT', 'LTC', 'MAID', 'STR', 'XMR', 'XRP'] +frame_dict = {} + +lendingFile = sys.argv[1] + +df = pd.read_csv(lendingFile, + usecols=['Currency', 'Rate', 'Earned', 'Close', 'Open'], + index_col='Open', + parse_dates=['Open', 'Close'], + infer_datetime_format=True) + +for cur in curs: + frame_dict[cur] = df[df.Currency == cur] + print("Summary for {0}".format(cur)) + print("Total earned : {0}".format(frame_dict[cur].Earned.sum())) + print("Best rate : {0}%".format(frame_dict[cur].Rate.max() * 100)) + print("Average rate : {0:.6f}%".format(frame_dict[cur].Rate.mean() * 100)) From b70294c0983f50e7b64557a82403ba403bf31db1 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 14 May 2017 23:10:41 +0200 Subject: [PATCH 02/11] Implement AccountStats plugin - WORK IN PROGRESS - Created Plugin system, allowing user to define which Plugins are loaded from config file - Started implementation of AccountStats (fetching history) --- lendingbot.py | 15 ++++++++----- modules/Configuration.py | 7 ++++++ modules/PluginsManager.py | 46 +++++++++++++++++++++++++++++++++++++++ modules/Poloniex.py | 3 +++ plugins/AccountStats.py | 42 +++++++++++++++++++++++++++++++++++ plugins/Plugin.py | 29 ++++++++++++++++++++++++ plugins/__init__.py | 15 +++++++++++++ 7 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 modules/PluginsManager.py create mode 100644 plugins/AccountStats.py create mode 100644 plugins/Plugin.py create mode 100644 plugins/__init__.py diff --git a/lendingbot.py b/lendingbot.py index e99b2ffb..3bb5ab14 100644 --- a/lendingbot.py +++ b/lendingbot.py @@ -4,17 +4,18 @@ import sys import time import traceback +from decimal import Decimal from httplib import BadStatusLine from urllib2 import URLError -from decimal import Decimal - -from modules.Logger import Logger -from modules.Poloniex import Poloniex, PoloniexApiError import modules.Configuration as Config -import modules.MaxToLend as MaxToLend import modules.Data as Data import modules.Lending as Lending +import modules.MaxToLend as MaxToLend +from modules.Logger import Logger +from modules.Poloniex import Poloniex, PoloniexApiError +import modules.PluginsManager as PluginsManager + try: open('lendingbot.py', 'r') @@ -57,6 +58,8 @@ analysis = None Lending.init(Config, api, log, Data, MaxToLend, dry_run, analysis, notify_conf) +# load plugins +PluginsManager.init(Config, api, log, notify_conf) print 'Welcome to Poloniex Lending Bot' # Configure web server @@ -73,6 +76,7 @@ Lending.transfer_balances() Lending.cancel_all() Lending.lend_all() + PluginsManager.on_bot_loop() log.refreshStatus(Data.stringify_total_lent(*Data.get_total_lent()), Data.get_max_duration(end_date, "status")) log.persistStatus() @@ -116,6 +120,7 @@ except KeyboardInterrupt: if web_server_enabled: WebServer.stop_web_server() + PluginsManager.on_bot_exit() log.log('bye') print 'bye' os._exit(0) # Ad-hoc solution in place of 'exit(0)' TODO: Find out why non-daemon thread(s) are hanging on exit diff --git a/modules/Configuration.py b/modules/Configuration.py index 3cdee763..12a62e96 100644 --- a/modules/Configuration.py +++ b/modules/Configuration.py @@ -158,3 +158,10 @@ def get_notification_config(): notify_conf[conf] = get('notifications', conf) return notify_conf + + +def get_plugins_config(): + active_plugins = [] + if config.has_option("BOT", "plugins"): + active_plugins = config.get("BOT", "plugins").split(',') + return active_plugins diff --git a/modules/PluginsManager.py b/modules/PluginsManager.py new file mode 100644 index 00000000..730909b5 --- /dev/null +++ b/modules/PluginsManager.py @@ -0,0 +1,46 @@ +from plugins import * +import plugins.Plugin as Plugin + +config = None +api = None +log = None +notify_conf = None +plugins = [] + + +def init_plugin(plugin_name): + """ + :return: instance of requested class + :rtype: Plugin + """ + klass = globals()[plugin_name] # type: Plugin + instance = klass(config, api, log, notify_conf) + instance.on_bot_init() + return instance + + +def init(cfg, api1, log1, notify_conf1): + """ + @type cfg1: modules.Configuration + @type api1: modules.Poloniex.Poloniex + @type log1: modules.Logger.Logger + """ + global config, api, log, notify_conf + config = cfg + api = api1 + log = log1 + notify_conf = notify_conf1 + + plugin_names = config.get_plugins_config(); + for plugin_name in plugin_names: + plugins.append(init_plugin(plugin_name)) + + +def on_bot_loop(): + for plugin in plugins: + plugin.on_bot_loop() + + +def on_bot_exit(): + for plugin in plugins: + plugin.on_bot_exit() diff --git a/modules/Poloniex.py b/modules/Poloniex.py index 297ef423..97cd0c1a 100644 --- a/modules/Poloniex.py +++ b/modules/Poloniex.py @@ -175,6 +175,9 @@ def return_open_loan_offers(self): def return_active_loans(self): return self.api_query('returnActiveLoans') + def return_lending_history(self, start, stop): + return self.api_query('returnLendingHistory', {'start': start, 'end': stop}) + # Returns your trade history for a given market, specified by the "currencyPair" POST parameter # Inputs: # currencyPair The currency pair e.g. "BTC_XCP" diff --git a/plugins/AccountStats.py b/plugins/AccountStats.py new file mode 100644 index 00000000..76643ab0 --- /dev/null +++ b/plugins/AccountStats.py @@ -0,0 +1,42 @@ +# coding=utf-8 +from plugins.Plugin import Plugin +import modules.Poloniex as Poloniex +import sqlite3 + +DB_CREATE = "CREATE TABLE IF NOT EXISTS history(" \ + "id INTEGER UNIQUE, open TIMESTAMP, close TIMESTAMP," \ + " duration NUMBER, interest NUMBER, rate NUMBER," \ + " currency TEXT, amount NUMBER, earned NUMBER, fee NUMBER )" +DB_INSERT = "INSERT OR REPLACE INTO 'history'" \ + "('id','open','close','duration','interest','rate','currency','amount','earned','fee')" \ + " VALUES (?,?,?,?,?,?,?,?,?,?);" +DB_GET_LAST_TIMESTAMP = "SELECT max(close) as last_timestamp FROM 'history'" + + +class AccountStats(Plugin): + def on_bot_init(self): + super(AccountStats, self).on_bot_init() + self.init_db() + self.update_history() + + def on_bot_loop(self): + pass + + # noinspection PyAttributeOutsideInit + def init_db(self): + self.db = sqlite3.connect(r'market_data\loan_history.sqlite3') + self.db.execute(DB_CREATE) + self.db.commit() + + def update_history(self): + cursor = self.db.execute(DB_GET_LAST_TIMESTAMP) + self.log.log(cursor.fetchone()[0]) + cursor.close() + + history = self.api.return_lending_history(Poloniex.create_time_stamp("2017-05-13 00:00:00") + , Poloniex.create_time_stamp("2017-05-15 00:00:00")) + for loan in history: + self.db.execute(DB_INSERT, [loan['id'], loan['open'], loan['close'], loan['duration'], loan['interest'], + loan['rate'], loan['currency'], loan['amount'], loan['earned'], loan['fee']]) + self.db.commit() + self.log.log(str(len(history))) diff --git a/plugins/Plugin.py b/plugins/Plugin.py new file mode 100644 index 00000000..781fe0c9 --- /dev/null +++ b/plugins/Plugin.py @@ -0,0 +1,29 @@ +# coding=utf-8 +import modules.Logger +import modules.Configuration +import modules.Poloniex + + +class Plugin(object): + """ + @type cfg1: modules.Configuration + @type api1: modules.Poloniex.Poloniex + @type log1: modules.Logger.Logger + """ + def __init__(self, cfg1, api1, log1, notify_config1): + self.api = api1 + self.config = cfg1 + self.notify_config = notify_config1 + self.log = log1 + + # override this to run plugin init code + def on_bot_init(self): + self.log.log(self.__class__.__name__ + ' plugin started.') + + # override this to run plugin loop code + def on_bot_loop(self): + pass + + # override this to run plugin stop code + def on_bot_stop(self): + pass diff --git a/plugins/__init__.py b/plugins/__init__.py new file mode 100644 index 00000000..6bbb0cfa --- /dev/null +++ b/plugins/__init__.py @@ -0,0 +1,15 @@ +# coding=utf-8 +__all__ = [] + +import pkgutil +import inspect + +for loader, name, is_pkg in pkgutil.walk_packages(__path__): + module = loader.find_module(name).load_module(name) + + for name, value in inspect.getmembers(module): + if name.startswith('__'): + continue + + globals()[name] = value + __all__.append(name) \ No newline at end of file From 6565e5745f451e78984072ae98726e5a447f0d87 Mon Sep 17 00:00:00 2001 From: Raanan Date: Tue, 16 May 2017 23:47:40 +0200 Subject: [PATCH 03/11] Fetch all lending history from Poloniex Split Plugin events to before and after lending --- lendingbot.py | 3 ++- modules/PluginsManager.py | 9 +++++++-- modules/Poloniex.py | 8 +++++--- plugins/AccountStats.py | 26 +++++++++++++++++--------- plugins/Plugin.py | 9 +++++++-- 5 files changed, 38 insertions(+), 17 deletions(-) diff --git a/lendingbot.py b/lendingbot.py index 3bb5ab14..8fcde393 100644 --- a/lendingbot.py +++ b/lendingbot.py @@ -73,10 +73,11 @@ while True: try: Data.update_conversion_rates(output_currency, json_output_enabled) + PluginsManager.before_lending() Lending.transfer_balances() Lending.cancel_all() Lending.lend_all() - PluginsManager.on_bot_loop() + PluginsManager.after_lending() log.refreshStatus(Data.stringify_total_lent(*Data.get_total_lent()), Data.get_max_duration(end_date, "status")) log.persistStatus() diff --git a/modules/PluginsManager.py b/modules/PluginsManager.py index 730909b5..de29a205 100644 --- a/modules/PluginsManager.py +++ b/modules/PluginsManager.py @@ -36,9 +36,14 @@ def init(cfg, api1, log1, notify_conf1): plugins.append(init_plugin(plugin_name)) -def on_bot_loop(): +def after_lending(): for plugin in plugins: - plugin.on_bot_loop() + plugin.after_lending() + + +def before_lending(): + for plugin in plugins: + plugin.before_lending() def on_bot_exit(): diff --git a/modules/Poloniex.py b/modules/Poloniex.py index 97cd0c1a..be97aa07 100644 --- a/modules/Poloniex.py +++ b/modules/Poloniex.py @@ -7,6 +7,8 @@ import urllib import urllib2 import threading +import calendar + from modules.RingBuffer import RingBuffer @@ -15,7 +17,7 @@ class PoloniexApiError(Exception): def create_time_stamp(datestr, formatting="%Y-%m-%d %H:%M:%S"): - return time.mktime(time.strptime(datestr, formatting)) + return calendar.timegm(time.strptime(datestr, formatting)) def post_process(before): @@ -175,8 +177,8 @@ def return_open_loan_offers(self): def return_active_loans(self): return self.api_query('returnActiveLoans') - def return_lending_history(self, start, stop): - return self.api_query('returnLendingHistory', {'start': start, 'end': stop}) + def return_lending_history(self, start, stop, limit=500): + return self.api_query('returnLendingHistory', {'start': start, 'end': stop, 'limit': limit}) # Returns your trade history for a given market, specified by the "currencyPair" POST parameter # Inputs: diff --git a/plugins/AccountStats.py b/plugins/AccountStats.py index 76643ab0..a8ee75a2 100644 --- a/plugins/AccountStats.py +++ b/plugins/AccountStats.py @@ -19,8 +19,8 @@ def on_bot_init(self): self.init_db() self.update_history() - def on_bot_loop(self): - pass + def after_lending(self): + self.update_history() # noinspection PyAttributeOutsideInit def init_db(self): @@ -29,14 +29,22 @@ def init_db(self): self.db.commit() def update_history(self): + # timestamps are in UTC + last_time_stamp = "2009-01-03 18:15:05" cursor = self.db.execute(DB_GET_LAST_TIMESTAMP) - self.log.log(cursor.fetchone()[0]) + row = cursor.fetchone() + if row[0] is not None: + last_time_stamp = row[0] + self.log.log(last_time_stamp) cursor.close() - history = self.api.return_lending_history(Poloniex.create_time_stamp("2017-05-13 00:00:00") - , Poloniex.create_time_stamp("2017-05-15 00:00:00")) - for loan in history: - self.db.execute(DB_INSERT, [loan['id'], loan['open'], loan['close'], loan['duration'], loan['interest'], - loan['rate'], loan['currency'], loan['amount'], loan['earned'], loan['fee']]) + history = self.api.return_lending_history(Poloniex.create_time_stamp(last_time_stamp) + , sqlite3.time.time(), 10000000) + loans = [] + for loan in reversed(history): + loans.append( + [loan['id'], loan['open'], loan['close'], loan['duration'], loan['interest'], + loan['rate'], loan['currency'], loan['amount'], loan['earned'], loan['fee']]) + self.db.executemany(DB_INSERT, loans) self.db.commit() - self.log.log(str(len(history))) + self.log.log(str(len(loans))) diff --git a/plugins/Plugin.py b/plugins/Plugin.py index 781fe0c9..541ac903 100644 --- a/plugins/Plugin.py +++ b/plugins/Plugin.py @@ -20,10 +20,15 @@ def __init__(self, cfg1, api1, log1, notify_config1): def on_bot_init(self): self.log.log(self.__class__.__name__ + ' plugin started.') - # override this to run plugin loop code - def on_bot_loop(self): + # override this to run plugin loop code before lending + def before_lending(self): + pass + + # override this to run plugin loop code after lending + def after_lending(self): pass # override this to run plugin stop code + # since the bot can be killed, there is not guarantee this will be called. def on_bot_stop(self): pass From 2cd271871e6aa8cb8f70e3e2b2334fb1ff6769e8 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 21 May 2017 11:19:20 +0200 Subject: [PATCH 04/11] Fix fetch all lending history from Poloniex Added notify event (every cycle at the moment) --- plugins/AccountStats.py | 90 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 11 deletions(-) diff --git a/plugins/AccountStats.py b/plugins/AccountStats.py index a8ee75a2..141a666b 100644 --- a/plugins/AccountStats.py +++ b/plugins/AccountStats.py @@ -1,8 +1,13 @@ # coding=utf-8 +from datetime import date + from plugins.Plugin import Plugin import modules.Poloniex as Poloniex import sqlite3 +BITCOIN_GENESIS_BLOCK_DATE = "2009-01-03 18:15:05" + +DB_DROP = "DROP TABLE IF EXISTS history" DB_CREATE = "CREATE TABLE IF NOT EXISTS history(" \ "id INTEGER UNIQUE, open TIMESTAMP, close TIMESTAMP," \ " duration NUMBER, interest NUMBER, rate NUMBER," \ @@ -11,16 +16,20 @@ "('id','open','close','duration','interest','rate','currency','amount','earned','fee')" \ " VALUES (?,?,?,?,?,?,?,?,?,?);" DB_GET_LAST_TIMESTAMP = "SELECT max(close) as last_timestamp FROM 'history'" +DB_GET_FIRST_TIMESTAMP = "SELECT min(close) as first_timestamp FROM 'history'" +DB_GET_TOTAL_EARNED = "SELECT sum(earned) as total_earned, currency FROM 'history' GROUP BY currency" +DB_GET_24HR_EARNED = "SELECT sum(earned) as total_earned, currency FROM 'history' " \ + "WHERE close BETWEEN datetime('now','-1 day') AND datetime('now') GROUP BY currency" class AccountStats(Plugin): def on_bot_init(self): super(AccountStats, self).on_bot_init() self.init_db() - self.update_history() def after_lending(self): self.update_history() + self.notify_daily() # noinspection PyAttributeOutsideInit def init_db(self): @@ -30,16 +39,36 @@ def init_db(self): def update_history(self): # timestamps are in UTC - last_time_stamp = "2009-01-03 18:15:05" - cursor = self.db.execute(DB_GET_LAST_TIMESTAMP) - row = cursor.fetchone() - if row[0] is not None: - last_time_stamp = row[0] - self.log.log(last_time_stamp) - cursor.close() + last_time_stamp = self.get_last_timestamp() - history = self.api.return_lending_history(Poloniex.create_time_stamp(last_time_stamp) - , sqlite3.time.time(), 10000000) + if last_time_stamp is None: + # no entries means db is empty and needs initialization + last_time_stamp = BITCOIN_GENESIS_BLOCK_DATE + self.db.execute("PRAGMA user_version = 0") + + self.fetch_history(Poloniex.create_time_stamp(last_time_stamp), sqlite3.time.time()) + + # As Poloniex API return a unspecified number of recent loans, but not all so we need to loop back. + if (self.get_db_version() == 0) and (self.get_first_timestamp() is not None): + last_time_stamp = BITCOIN_GENESIS_BLOCK_DATE + loop = True + while loop: + sqlite3.time.sleep(10) # delay a bit, try not to annoy poloniex + first_time_stamp = self.get_first_timestamp() + count = self.fetch_history(Poloniex.create_time_stamp(last_time_stamp, ) + , Poloniex.create_time_stamp(first_time_stamp)) + loop = count != 0 + # if we reached here without errors means we managed to fetch all the history, db is ready. + self.set_db_version(1) + + def set_db_version(self, version): + self.db.execute("PRAGMA user_version = " + str(version)) + + def get_db_version(self): + return self.db.execute("PRAGMA user_version").fetchone()[0] + + def fetch_history(self, first_time_stamp, last_time_stamp): + history = self.api.return_lending_history(first_time_stamp, last_time_stamp - 1, 50000) loans = [] for loan in reversed(history): loans.append( @@ -47,4 +76,43 @@ def update_history(self): loan['rate'], loan['currency'], loan['amount'], loan['earned'], loan['fee']]) self.db.executemany(DB_INSERT, loans) self.db.commit() - self.log.log(str(len(loans))) + count = len(loans) + self.log.log('Downloaded ' + str(count) + ' loans history ' + + sqlite3.datetime.datetime.utcfromtimestamp(first_time_stamp).strftime('%Y-%m-%d %H:%M:%S') + + ' to ' + sqlite3.datetime.datetime.utcfromtimestamp(last_time_stamp - 1).strftime( + '%Y-%m-%d %H:%M:%S')) + if count > 0: + self.log.log('Last: ' + history[0]['close'] + ' First:' + history[count - 1]['close']) + return count + + def get_last_timestamp(self): + cursor = self.db.execute(DB_GET_LAST_TIMESTAMP) + row = cursor.fetchone() + cursor.close() + return row[0] + + def get_first_timestamp(self): + cursor = self.db.execute(DB_GET_FIRST_TIMESTAMP) + row = cursor.fetchone() + cursor.close() + return row[0] + + def notify_daily(self): + if self.get_db_version() == 0: + self.log.log_error('AccountStats DB isn\'t ready.') + return + + cursor = self.db.execute(DB_GET_24HR_EARNED) + output = '' + for row in cursor: + output += str(row[0]) + ' ' + str(row[1]) + ' in last 24hrs\n' + cursor.close() + + cursor = self.db.execute(DB_GET_TOTAL_EARNED) + for row in cursor: + output += str(row[0]) + ' ' + str(row[1]) + ' in total\n' + cursor.close() + if output != '': + output = 'Earnings:\n----------\n' + output + self.log.notify(output, self.notify_config) + self.log.log(output) From 5cd95a7aa9e882a7d937bcd4e3a332a0db514060 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 21 May 2017 15:32:05 +0200 Subject: [PATCH 05/11] Notify every 24Hrs --- plugins/AccountStats.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/plugins/AccountStats.py b/plugins/AccountStats.py index 141a666b..fa56c4c5 100644 --- a/plugins/AccountStats.py +++ b/plugins/AccountStats.py @@ -6,7 +6,7 @@ import sqlite3 BITCOIN_GENESIS_BLOCK_DATE = "2009-01-03 18:15:05" - +DAY_IN_SEC = 86400 DB_DROP = "DROP TABLE IF EXISTS history" DB_CREATE = "CREATE TABLE IF NOT EXISTS history(" \ "id INTEGER UNIQUE, open TIMESTAMP, close TIMESTAMP," \ @@ -23,6 +23,8 @@ class AccountStats(Plugin): + last_notification = 0 + def on_bot_init(self): super(AccountStats, self).on_bot_init() self.init_db() @@ -102,6 +104,9 @@ def notify_daily(self): self.log.log_error('AccountStats DB isn\'t ready.') return + if self.last_notification != 0 and self.last_notification + DAY_IN_SEC > sqlite3.time.time(): + return + cursor = self.db.execute(DB_GET_24HR_EARNED) output = '' for row in cursor: @@ -113,6 +118,7 @@ def notify_daily(self): output += str(row[0]) + ' ' + str(row[1]) + ' in total\n' cursor.close() if output != '': + self.last_notification = sqlite3.time.time() output = 'Earnings:\n----------\n' + output self.log.notify(output, self.notify_config) self.log.log(output) From 5a1bba12151287220dbe2ae5aaa232cdcd2adf65 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 21 May 2017 20:49:49 +0200 Subject: [PATCH 06/11] Updated documentation --- docs/configuration.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/configuration.rst b/docs/configuration.rst index a9e4dbb6..211e2fd7 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -295,6 +295,26 @@ Advanced logging and Web Display - Acceptable values: BTC, USDT, Any coin with a direct Poloniex BTC trading pair (ex. DOGE, MAID, ETH), Currencies that have a BTC exchange rate on blockchain.info (i.e. EUR, USD) - Will be a close estimate, due to unexpected market fluctuations, trade fees, and other unforseeable factors. +Plugins +------- + +Plugins allow extending Bot functionality with extra features. +To enable/disable a plugin add/remove it to the ``plugins`` list config option, example:: + + plugins = Plugin1, Plugin2, etc... + +AccountStats Plugin +~~~~~~~~~~~~~~~~~~~ + +The AccountStats plugin fetches all your loan history and provides statistics based on it. +Current implementation sends a earnings summery Notification (see Notifications sections) every 24hr. + +To enable the plugin add ``AccountStats`` to the ``plugins`` config options, example:: + + plugins = AccountStats + +Be aware that first initialization might take longer as the bot will fetch all the history. + lendingbot.html options ----------------------- From 9da81a5e3d76bfb0ac49e4d6d5338e1143ff111e Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 21 May 2017 20:53:22 +0200 Subject: [PATCH 07/11] Removed tools --- tools/analyseLendingHistory.py | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 tools/analyseLendingHistory.py diff --git a/tools/analyseLendingHistory.py b/tools/analyseLendingHistory.py deleted file mode 100644 index 50b632d0..00000000 --- a/tools/analyseLendingHistory.py +++ /dev/null @@ -1,20 +0,0 @@ -import pandas as pd -import sys - -curs = ['BTC', 'BTS', 'CLAM', 'DASH', 'DOGE', 'ETH', 'FCT', 'LTC', 'MAID', 'STR', 'XMR', 'XRP'] -frame_dict = {} - -lendingFile = sys.argv[1] - -df = pd.read_csv(lendingFile, - usecols=['Currency', 'Rate', 'Earned', 'Close', 'Open'], - index_col='Open', - parse_dates=['Open', 'Close'], - infer_datetime_format=True) - -for cur in curs: - frame_dict[cur] = df[df.Currency == cur] - print("Summary for {0}".format(cur)) - print("Total earned : {0}".format(frame_dict[cur].Earned.sum())) - print("Best rate : {0}%".format(frame_dict[cur].Rate.max() * 100)) - print("Average rate : {0:.6f}%".format(frame_dict[cur].Rate.mean() * 100)) From e31400c608b755ab1563c32eecd51fca2f31d518 Mon Sep 17 00:00:00 2001 From: Raanan Nevet Date: Fri, 26 May 2017 12:13:05 +0200 Subject: [PATCH 08/11] Strip plugin names from config Typo in docs --- docs/configuration.rst | 2 +- modules/Configuration.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 211e2fd7..2281273a 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -307,7 +307,7 @@ AccountStats Plugin ~~~~~~~~~~~~~~~~~~~ The AccountStats plugin fetches all your loan history and provides statistics based on it. -Current implementation sends a earnings summery Notification (see Notifications sections) every 24hr. +Current implementation sends a earnings summary Notification (see Notifications sections) every 24hr. To enable the plugin add ``AccountStats`` to the ``plugins`` config options, example:: diff --git a/modules/Configuration.py b/modules/Configuration.py index 12a62e96..8fa84904 100644 --- a/modules/Configuration.py +++ b/modules/Configuration.py @@ -163,5 +163,5 @@ def get_notification_config(): def get_plugins_config(): active_plugins = [] if config.has_option("BOT", "plugins"): - active_plugins = config.get("BOT", "plugins").split(',') + active_plugins = map(str.strip, config.get("BOT", "plugins").split(',')) return active_plugins From 3922aba50fd9f6452e8aa0d1aa67bad383072b03 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sat, 27 May 2017 23:55:38 +0200 Subject: [PATCH 09/11] Removed semicolon --- modules/PluginsManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/PluginsManager.py b/modules/PluginsManager.py index de29a205..8b15e7af 100644 --- a/modules/PluginsManager.py +++ b/modules/PluginsManager.py @@ -31,7 +31,7 @@ def init(cfg, api1, log1, notify_conf1): log = log1 notify_conf = notify_conf1 - plugin_names = config.get_plugins_config(); + plugin_names = config.get_plugins_config() for plugin_name in plugin_names: plugins.append(init_plugin(plugin_name)) From e3abd2ec48ab841083b2a5d51d335c3800f081fc Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 28 May 2017 00:02:20 +0200 Subject: [PATCH 10/11] removed trailing space --- modules/PluginsManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/PluginsManager.py b/modules/PluginsManager.py index 8b15e7af..9eeb0393 100644 --- a/modules/PluginsManager.py +++ b/modules/PluginsManager.py @@ -10,7 +10,7 @@ def init_plugin(plugin_name): """ - :return: instance of requested class + :return: instance of requested class :rtype: Plugin """ klass = globals()[plugin_name] # type: Plugin From bee639a2318457c351e154bdaf1e89f4fa9d1a44 Mon Sep 17 00:00:00 2001 From: Raanan Date: Sun, 28 May 2017 00:07:22 +0200 Subject: [PATCH 11/11] Removed unused imports --- plugins/AccountStats.py | 2 -- plugins/Plugin.py | 3 --- 2 files changed, 5 deletions(-) diff --git a/plugins/AccountStats.py b/plugins/AccountStats.py index fa56c4c5..e63b1a77 100644 --- a/plugins/AccountStats.py +++ b/plugins/AccountStats.py @@ -1,6 +1,4 @@ # coding=utf-8 -from datetime import date - from plugins.Plugin import Plugin import modules.Poloniex as Poloniex import sqlite3 diff --git a/plugins/Plugin.py b/plugins/Plugin.py index 541ac903..b1636737 100644 --- a/plugins/Plugin.py +++ b/plugins/Plugin.py @@ -1,7 +1,4 @@ # coding=utf-8 -import modules.Logger -import modules.Configuration -import modules.Poloniex class Plugin(object):