Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add order book and recent trades data for realtime evaluators #657

Merged
merged 1 commit into from
Feb 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,14 @@ class ExchangeConstantsMarketStatusInfoColumns(Enum):
MAX_QTY = "maxQty"


class ExchangeConstantsOrderBookInfoColumns(Enum):
BIDS = "bids"
ASKS = "asks"
TIMESTAMP = "timestamp"
DATETIME = "datetime"
NONCE = "nonce"


class ExchangeConstantsOrderColumns(Enum):
INFO = "info"
ID = "id"
Expand Down
6 changes: 6 additions & 0 deletions evaluator/RealTime/realtime_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ async def _get_data_from_exchange(self, time_frame, limit=None, return_list=Fals
return await self.exchange.get_symbol_prices(self.symbol, time_frame,
limit=limit, return_list=return_list)

async def _get_order_book_from_exchange(self, limit=None):
return await self.exchange.get_order_book(self.symbol, limit=limit)

async def _get_recent_trades_from_exchange(self, limit=None):
return await self.exchange.get_recent_trades(self.symbol, limit=limit)

@staticmethod
def _compare_data(new_data, old_data):
try:
Expand Down
8 changes: 8 additions & 0 deletions evaluator/Strategies/strategies_evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,11 @@ class MixedStrategiesEvaluator(StrategiesEvaluator):
@abstractmethod
async def eval_impl(self) -> None:
raise NotImplementedError("Eval_impl not implemented")


class MarketMakingStrategiesEvaluator(StrategiesEvaluator):
__metaclass__ = StrategiesEvaluator

@abstractmethod
async def eval_impl(self) -> None:
raise NotImplementedError("Eval_impl not implemented")
13 changes: 9 additions & 4 deletions trading/exchanges/exchange_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,15 @@ async def _handle_web_socket_reset(self):
# return bid and asks on each side of the order book stack
# careful here => can be for binance limit > 100 has a 5 weight and > 500 a 10 weight !
async def get_order_book(self, symbol, limit=50):
if not self._web_socket_available():
await self.exchange.get_order_book(symbol, limit)
symbol_data = self.get_symbol_data(symbol)

if not self._web_socket_available() or not symbol_data.order_book_is_initialized():
if not self._web_socket_available() or \
(self._web_socket_available() and self.exchange_web_socket.handles_order_book()):
symbol_data.init_order_book()
await self.exchange.get_order_book(symbol=symbol, limit=limit)

return self.get_symbol_data(symbol).get_symbol_order_book(limit)
return symbol_data.get_symbol_order_book()

async def get_recent_trades(self, symbol, limit=50):
symbol_data = self.get_symbol_data(symbol)
Expand All @@ -171,7 +176,7 @@ async def get_recent_trades(self, symbol, limit=50):
symbol_data.init_recent_trades()
await self.exchange.get_recent_trades(symbol=symbol, limit=limit)

return symbol_data.get_symbol_recent_trades(limit)
return symbol_data.get_symbol_recent_trades()

# A price ticker contains statistics for a particular market/symbol for some period of time in recent past (24h)
async def get_price_ticker(self, symbol):
Expand Down
21 changes: 14 additions & 7 deletions trading/exchanges/exchange_symbol_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this library.

from tools.logging.logging_util import get_logger
import time

import numpy as np

from config import PriceIndexes, TimeFramesMinutes, MINUTE_TO_SECONDS
from tools.logging.logging_util import get_logger


class SymbolData:
Expand All @@ -38,6 +38,7 @@ def __init__(self, symbol):
self.previous_candle_time = {}

self.are_recent_trades_initialized = False
self.is_order_book_initialized = False
self.logger = get_logger(f"{self.__class__.__name__} - {self.symbol}")

'''
Expand Down Expand Up @@ -70,7 +71,7 @@ def ensure_data_validity(self, time_frame):
# if update time from the previous time frame is greater than this given time frame:
# data did not get updated => data are invalid
if current_time - previous_candle_timestamp > \
TimeFramesMinutes[time_frame]*MINUTE_TO_SECONDS*error_allowance:
TimeFramesMinutes[time_frame] * MINUTE_TO_SECONDS * error_allowance:
return False
return True

Expand Down Expand Up @@ -106,11 +107,11 @@ def get_symbol_ticker(self):
return self.symbol_ticker

# order book functions
def get_symbol_order_book(self, limit=None):
def get_symbol_order_book(self):
return self.order_book

# recent trade functions
def get_symbol_recent_trades(self, limit=None):
def get_symbol_recent_trades(self):
return self.recent_trades

# private functions
Expand Down Expand Up @@ -143,6 +144,12 @@ def recent_trades_are_initialized(self):
def init_recent_trades(self):
self.are_recent_trades_initialized = True

def order_book_is_initialized(self):
return self.is_order_book_initialized

def init_order_book(self):
self.is_order_book_initialized = True


class CandleData:
def __init__(self, all_candles_data):
Expand Down Expand Up @@ -209,7 +216,7 @@ def get_symbol_volume_candles(self, limit=None, return_list=False):
return self.extract_limited_data(self.volume_candles_array, limit)

def get_symbol_prices(self, limit=None, return_list=False):
symbol_prices = [None]*len(PriceIndexes)
symbol_prices = [None] * len(PriceIndexes)
symbol_prices[PriceIndexes.IND_PRICE_CLOSE.value] = self.get_symbol_close_candles(limit, return_list)
symbol_prices[PriceIndexes.IND_PRICE_OPEN.value] = self.get_symbol_open_candles(limit, return_list)
symbol_prices[PriceIndexes.IND_PRICE_HIGH.value] = self.get_symbol_high_candles(limit, return_list)
Expand Down Expand Up @@ -292,12 +299,12 @@ def sanitize_last_candle(close_candle_data, high_candle_data, low_candle_data):
low_candle_data[-1] = close_last_candle
if high_candle_data[-1] < close_last_candle:
high_candle_data[-1] = close_last_candle

@staticmethod
def set_last_candle_arrays(list_updated, array_to_update):
if array_to_update is not None:
array_to_update[-1] = list_updated[-1]

@staticmethod
def convert_list_to_array(list_to_convert):
return np.array(list_to_convert)
Expand Down
5 changes: 3 additions & 2 deletions trading/exchanges/rest_exchanges/rest_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ async def get_symbol_prices(self, symbol, time_frame, limit=None, return_list=Tr
self.get_symbol_data(symbol).update_symbol_candles(time_frame, candles, replace_all=True)

# return up to ten bidasks on each side of the order book stack
async def get_order_book(self, symbol, limit=30):
self.get_symbol_data(symbol).update_order_book(await self.client.fetch_order_book(symbol, limit))
async def get_order_book(self, symbol, limit=5):
order_book = await self.client.fetch_order_book(symbol, limit)
self.get_symbol_data(symbol).update_order_book(order_book)

async def get_recent_trades(self, symbol, limit=50):
trades = await self.client.fetch_trades(symbol, limit=limit)
Expand Down