From 882b30ef172591778d8d23051aea6eb74f1c3f5f Mon Sep 17 00:00:00 2001 From: Nullart Date: Mon, 11 Jun 2018 16:17:21 +0800 Subject: [PATCH] Added feature to bid/buy cryptocurrency using book orders from exchange. The idea, is to get rates from the top 2 (depending on the config settings) of book orders instead of tickers. This way we can offset the lags from the OHLCV data. --- config.json.example | 4 +++- config_full.json.example | 4 +++- freqtrade/constants.py | 2 ++ freqtrade/exchange/__init__.py | 13 +++++++++++++ freqtrade/freqtradebot.py | 21 +++++++++++++++------ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/config.json.example b/config.json.example index d3dbeb52e..d2f70d82c 100644 --- a/config.json.example +++ b/config.json.example @@ -7,7 +7,9 @@ "dry_run": false, "unfilledtimeout": 600, "bid_strategy": { - "ask_last_balance": 0.0 + "ask_last_balance": 0.0, + "use_book_order": true, + "book_order_top": 6 }, "exchange": { "name": "bittrex", diff --git a/config_full.json.example b/config_full.json.example index c17d22a15..bec845b3b 100644 --- a/config_full.json.example +++ b/config_full.json.example @@ -14,7 +14,9 @@ "stoploss": -0.10, "unfilledtimeout": 600, "bid_strategy": { - "ask_last_balance": 0.0 + "ask_last_balance": 0.0, + "use_book_order": true, + "book_order_top": 6 }, "exchange": { "name": "bittrex", diff --git a/freqtrade/constants.py b/freqtrade/constants.py index 5be01f977..d56353c6e 100644 --- a/freqtrade/constants.py +++ b/freqtrade/constants.py @@ -65,6 +65,8 @@ CONF_SCHEMA = { 'maximum': 1, 'exclusiveMaximum': False }, + 'use_book_order': {'type': 'boolean'}, + 'book_order_top': {'type': 'number', 'maximum':20,'minimum':1} }, 'required': ['ask_last_balance'] }, diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 54d564f04..26e828db3 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -239,6 +239,19 @@ def get_balances() -> dict: except ccxt.BaseError as e: raise OperationalException(e) +@retrier +def get_order_book(pair: str, refresh: Optional[bool] = True) -> dict: + try: + return _API.fetch_order_book(pair) + except ccxt.NotSupported as e: + raise OperationalException( + f'Exchange {_API.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() -> Dict: diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index 6058b7242..e9111ac87 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -237,16 +237,25 @@ class FreqtradeBot(object): return final_list - def get_target_bid(self, ticker: Dict[str, float]) -> float: + def get_target_bid(self, pair: str) -> float: """ Calculates bid target between current ask price and last price :param ticker: Ticker to use for getting Ask and Last Price :return: float: Price """ - if ticker['ask'] < ticker['last']: - return ticker['ask'] - balance = self.config['bid_strategy']['ask_last_balance'] - return ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + + if self.config['bid_strategy']['use_book_order']: + logger.info('Using order book ') + orderBook = exchange.get_order_book(pair) + return orderBook['bids'][self.config['bid_strategy']['use_book_order']][0] + else: + logger.info('Using Ask / Last Price') + ticker = exchange.get_ticker(pair); + if ticker['ask'] < ticker['last']: + return ticker['ask'] + balance = self.config['bid_strategy']['ask_last_balance'] + return ticker['ask'] + balance * (ticker['last'] - ticker['ask']) + def create_trade(self) -> bool: """ @@ -290,7 +299,7 @@ class FreqtradeBot(object): pair_s = pair.replace('_', '/') pair_url = exchange.get_pair_detail_url(pair) # Calculate amount - buy_limit = self.get_target_bid(exchange.get_ticker(pair)) + buy_limit = self.get_target_bid(pair) amount = stake_amount / buy_limit order_id = exchange.buy(pair, buy_limit, amount)['id']