From 8adbe96dcabe529e63e848e0f508d3a0b644fa7e Mon Sep 17 00:00:00 2001 From: Dennis Thiessen Date: Wed, 11 Oct 2017 15:25:09 +0200 Subject: [PATCH] Implemented calculation of arbitrage opportunities --- bot/core.py | 19 ++++++++++++++++-- bot/market_data_analyzer.py | 40 +++++++++++++++++++++++++++++++++++++ bot/market_data_crawler.py | 8 ++++---- 3 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 bot/market_data_analyzer.py diff --git a/bot/core.py b/bot/core.py index 7a9e6ea..e7d392a 100644 --- a/bot/core.py +++ b/bot/core.py @@ -1,5 +1,5 @@ #!/usr/bin/python -from . import market_data_crawler +from . import market_data_crawler, market_data_analyzer from tornado import gen from tornado.ioloop import IOLoop @@ -13,7 +13,7 @@ class MainHandler(tornado.web.RequestHandler): def post(self): print("POST received from IP {0}".format(self.request.remote_ip)) - response = {'error': False, 'msg': ""} + response = {'error': False, 'msg': "None"} request = json.loads(self.request.body.decode('utf-8')) if "token" not in request or request["token"] != "abc": @@ -26,6 +26,11 @@ class MainHandler(tornado.web.RequestHandler): if request["command"] == "init_market_data": yield self.update_market_data(request, response) + elif request["command"] == "get_market_data": + yield self.get_market_data(request, response) + elif request["command"] == "calc_arbitr_opport": + yield self.update_market_data(request, response) + yield self.get_arbitrage_opportunities(request, response) self.write(json.dumps(response)) @@ -35,6 +40,16 @@ class MainHandler(tornado.web.RequestHandler): response["msg"] = "Market Data initialized" response["data"] = market_data_crawler.market_data + @gen.coroutine + def get_market_data(self, request, response): + response["msg"] = "Market Data Retrieved" + response["data"] = market_data_crawler.market_data + + @gen.coroutine + def get_arbitrage_opportunities(self, request, response): + response["msg"] = "Arbitrage Oportunities Retrieved" + response["data"] = market_data_analyzer.calculate_arbitrage_opportunities(request["basecoin"]) + @gen.coroutine def delete(self): print("Stopping server...") diff --git a/bot/market_data_analyzer.py b/bot/market_data_analyzer.py new file mode 100644 index 0000000..97bba07 --- /dev/null +++ b/bot/market_data_analyzer.py @@ -0,0 +1,40 @@ +#!/usr/bin/python +from . import market_data_crawler + +import time +import operator + + +def calculate_arbitrage_opportunities(basecoin): + market_data = market_data_crawler.market_data + print("Total currency pairs: {0}".format(len(market_data))) + market_opport = {} + + print("--- Calculating arbitrage oportunities now ---") + start_time = time.time() + + for pair in market_data: + if len(market_data[pair]) > 1: + price_list = {} + + for price in market_data[pair]: + key, value = price.popitem() + price_list[key] = float(value) + + sorted_x = sorted(price_list.items(), key=operator.itemgetter(1), reverse=True) + spread = sorted_x[0][1] - sorted_x[-1][1] + spread_perc = round((spread / sorted_x[0][1]) * 100, 2) + + market_opport[pair] = {"highest_market": sorted_x[0][0], + "highest_price:": sorted_x[0][1], + "lowest_market": sorted_x[-1][0], + "lowest_price": sorted_x[-1][1], + "spread": spread, + "spread_perc": spread_perc, + "pair": pair} + + market_opport = sorted(market_opport.values(), key=operator.itemgetter("spread_perc"), reverse=True) + + print("--- Arbitrage oportunities calculated in {0:.3f}ms ---".format((time.time() - start_time)*100)) + + return market_opport diff --git a/bot/market_data_crawler.py b/bot/market_data_crawler.py index 167c71e..789cad2 100644 --- a/bot/market_data_crawler.py +++ b/bot/market_data_crawler.py @@ -1,16 +1,17 @@ #!/usr/bin/python -import tornado.escape, tornado.httpclient +import tornado.escape +import tornado.httpclient import tornado.httpclient from tornado import gen import time from collections import defaultdict +market_data = defaultdict(list) + @gen.coroutine def update_market_data_for_basecoin(basecoin): - global market_data - market_data = defaultdict(list) market_requests = [] @gen.coroutine @@ -134,7 +135,6 @@ def update_market_data_for_basecoin(basecoin): "https://api.bitfinex.com/v2/tickers?symbols=tETHBTC,tIOTETH,tEOSETH,tSANETH,tOMGETH,tQTMETH,tAVTETH,tETPETH,tNEOETH,tBCHETH", handle_response_bitfinex)) - print("--- Retrieve market data now ---") start_time = time.time() response_dict = yield market_requests