diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 7b5c0c753..d41c78921 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -134,8 +134,8 @@ def get_balances(): return _API.get_balances() -def get_ticker(pair: str) -> dict: - return _API.get_ticker(pair) +def get_ticker(pair: str, refresh: Optional[bool] = True) -> dict: + return _API.get_ticker(pair, refresh) @cached(TTLCache(maxsize=100, ttl=30)) diff --git a/freqtrade/exchange/bittrex.py b/freqtrade/exchange/bittrex.py index 3714de070..c153091d0 100644 --- a/freqtrade/exchange/bittrex.py +++ b/freqtrade/exchange/bittrex.py @@ -1,5 +1,5 @@ import logging -from typing import List, Dict +from typing import List, Dict, Optional from bittrex.bittrex import Bittrex as _Bittrex, API_V2_0, API_V1_1 from requests.exceptions import ContentDecodingError @@ -38,6 +38,7 @@ class Bittrex(Exchange): calls_per_second=1, api_version=API_V2_0, ) + self.cached_ticker = {} @staticmethod def _validate_response(response) -> None: @@ -95,26 +96,29 @@ class Bittrex(Exchange): raise OperationalException('{message}'.format(message=data['message'])) return data['result'] - def get_ticker(self, pair: str) -> dict: - data = _API.get_ticker(pair.replace('_', '-')) - if not data['success']: - Bittrex._validate_response(data) - raise OperationalException('{message} params=({pair})'.format( - message=data['message'], - pair=pair)) + def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: + data = _API.get_ticker(pair.replace('_', '-'), refresh) + if refresh: + if not data['success']: + Bittrex._validate_response(data) + raise OperationalException('{message} params=({pair})'.format( + message=data['message'], + pair=pair)) - if not data.get('result') \ - or not data['result'].get('Bid') \ - or not data['result'].get('Ask') \ - or not data['result'].get('Last'): - raise ContentDecodingError('{message} params=({pair})'.format( - message='Got invalid response from bittrex', - pair=pair)) - return { - 'bid': float(data['result']['Bid']), - 'ask': float(data['result']['Ask']), - 'last': float(data['result']['Last']), - } + if not data.get('result') \ + or not data['result'].get('Bid') \ + or not data['result'].get('Ask') \ + or not data['result'].get('Last'): + raise ContentDecodingError('{message} params=({pair})'.format( + message='Got invalid response from bittrex', + pair=pair)) + # Update the pair + self.cached_ticker[pair] = { + 'bid': float(data['result']['Bid']), + 'ask': float(data['result']['Ask']), + 'last': float(data['result']['Last']), + } + return self.cached_ticker[pair] def get_ticker_history(self, pair: str, tick_interval: int) -> List[Dict]: if tick_interval == 1: diff --git a/freqtrade/exchange/interface.py b/freqtrade/exchange/interface.py index a46b3c054..167a824d0 100644 --- a/freqtrade/exchange/interface.py +++ b/freqtrade/exchange/interface.py @@ -1,5 +1,5 @@ from abc import ABC, abstractmethod -from typing import List, Dict +from typing import List, Dict, Optional class Exchange(ABC): @@ -62,10 +62,11 @@ class Exchange(ABC): """ @abstractmethod - def get_ticker(self, pair: str) -> dict: + def get_ticker(self, pair: str, refresh: Optional[bool] = True) -> dict: """ Gets ticker for given pair. :param pair: Pair as str, format: BTC_ETC + :param refresh: Shall we query a new value or a cached value is enought :return: dict, format: { 'bid': float, 'ask': float, diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 7636c2b8a..ba3dd3c3e 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -140,7 +140,7 @@ def _status(bot: Bot, update: Update) -> None: if trade.open_order_id: order = exchange.get_order(trade.open_order_id) # calculate profit and send message to user - current_rate = exchange.get_ticker(trade.pair)['bid'] + current_rate = exchange.get_ticker(trade.pair, False)['bid'] current_profit = trade.calc_profit_percent(current_rate) fmt_close_profit = '{:.2f}%'.format( round(trade.close_profit * 100, 2) @@ -193,7 +193,7 @@ def _status_table(bot: Bot, update: Update) -> None: trades_list = [] for trade in trades: # calculate profit and send message to user - current_rate = exchange.get_ticker(trade.pair)['bid'] + current_rate = exchange.get_ticker(trade.pair, False)['bid'] trades_list.append([ trade.id, trade.pair, @@ -301,7 +301,7 @@ def _profit(bot: Bot, update: Update) -> None: profit_closed_percent.append(profit_percent) else: # Get current rate - current_rate = exchange.get_ticker(trade.pair)['bid'] + current_rate = exchange.get_ticker(trade.pair, False)['bid'] profit_percent = trade.calc_profit_percent(rate=current_rate) profit_all_coin.append(trade.calc_profit(rate=Decimal(trade.close_rate or current_rate))) @@ -577,7 +577,7 @@ def _exec_forcesell(trade: Trade) -> None: return # Get current rate and execute sell - current_rate = exchange.get_ticker(trade.pair)['bid'] + current_rate = exchange.get_ticker(trade.pair, False)['bid'] from freqtrade.main import execute_sell execute_sell(trade, current_rate)