diff --git a/freqtrade/analyze.py b/freqtrade/analyze.py index 493228e68..7b7a1f1e0 100755 --- a/freqtrade/analyze.py +++ b/freqtrade/analyze.py @@ -7,6 +7,7 @@ from enum import Enum from typing import Dict, List, Tuple import arrow +import pandas as pd from pandas import DataFrame, to_datetime from freqtrade import constants @@ -269,3 +270,28 @@ class Analyze(object): """ return {pair: self.populate_indicators(self.parse_ticker_dataframe(pair_data)) for pair, pair_data in tickerdata.items()} + + def order_book_to_dataframe(self, data: list) -> DataFrame: + """ + Gets order book list, returns dataframe with below format per suggested by creslin + ------------------------------------------------------------------- + b_sum b_size bids asks a_size a_sum + ------------------------------------------------------------------- + uses: + order_book = exchange.get_order_book(pair, 1000) + order_book_df = self.analyze.order_book_to_dataframe(order_book) + """ + cols = ['bids', 'b_size'] + bids_frame = DataFrame(data['bids'], columns=cols) + # add cumulative sum column for bids + bids_frame['b_sum'] = bids_frame['b_size'].cumsum() + cols2 = ['asks', 'a_size'] + asks_frame = DataFrame(data['asks'], columns=cols2) + # add cumulative sum column for asks + asks_frame['a_sum'] = asks_frame['a_size'].cumsum() + # There might be a better way to do this... a refactor would be welcome :) + frame = pd.concat([bids_frame['b_sum'], bids_frame['b_size'], bids_frame['bids'], \ + asks_frame['asks'], asks_frame['a_size'], asks_frame['a_sum']], axis=1, \ + keys=['b_sum', 'b_size', 'bids', 'asks', 'a_size', 'a_sum']) + + return frame diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index acfefdad4..54ff62618 100755 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -237,6 +237,29 @@ class Exchange(object): except ccxt.BaseError as e: raise OperationalException(e) + @retrier + def get_order_book(self, pair: str, limit: Optional[int] = 100) -> dict: + try: + # 20180619: bittrex doesnt support limits -.- + # 20180619: binance support limits but only on specific range + if self.name == 'Binance': + limit_range = [5, 10, 20, 50, 100, 500, 1000] + for limitx in limit_range: + if limit < limitx: + limit = limitx + break + + return self._api.fetch_l2_order_book(pair, limit) + except ccxt.NotSupported as e: + raise OperationalException( + f'Exchange {self.name} does not support fetching order book.' + f'Message: {e}') + except (ccxt.NetworkError, ccxt.ExchangeError) as e: + raise TemporaryError( + f'Could not load order book due to {e.__class__.__name__}. Message: {e}') + except ccxt.BaseError as e: + raise OperationalException(e) + @retrier def get_tickers(self) -> Dict: try: