From cb2608522914df2af27f30c51e3a0b6a452e6a54 Mon Sep 17 00:00:00 2001 From: misagh Date: Thu, 9 Aug 2018 12:47:26 +0200 Subject: [PATCH] =?UTF-8?q?Moving=20should=5Fnot=5Fupdate=20logic=20to=20a?= =?UTF-8?q?sync=20function=20per=20pair.=20if=20there=20is=20no=20new=20ca?= =?UTF-8?q?ndle,=20async=20function=20will=20just=20return=20the=20last=20?= =?UTF-8?q?cached=20candle=20locally=20and=20doesn=E2=80=99t=20hit=20the?= =?UTF-8?q?=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- freqtrade/exchange/__init__.py | 28 ++++++++++++++++++++++++++-- freqtrade/freqtradebot.py | 15 +-------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 50d759936..449a8270d 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -5,6 +5,7 @@ from random import randint from typing import List, Dict, Tuple, Any, Optional from datetime import datetime from math import floor, ceil +import time import asyncio import ccxt @@ -52,6 +53,12 @@ class Exchange(object): _conf: Dict = {} _cached_ticker: Dict[str, Any] = {} + # Holds last candle refreshed time of each pair + _pairs_last_refreshed_time = {} + + # Holds candles + _cached_klines: Dict[str, Any] = {} + # Holds all open sell orders for dry_run _dry_run_open_orders: Dict[str, Any] = {} @@ -349,8 +356,25 @@ class Exchange(object): since_ms: Optional[int] = None) -> Tuple[str, List]: try: # fetch ohlcv asynchronously - logger.debug("fetching %s ...", pair) - data = await self._api_async.fetch_ohlcv(pair, timeframe=tick_interval, since=since_ms) + logger.debug("fetching %s ...", pair) + + # Calculating ticker interval in second + interval_in_seconds = constants.TICKER_INTERVAL_MINUTES[tick_interval] * 60 + + # If (last update time) + (interval in second) + (1 second) is greater than now + # that means we don't have to hit the API as there is no new candle + # so we fetch it from local cache + if self._pairs_last_refreshed_time.get(pair, 0) + interval_in_seconds + 1 > round(time.time()): + data = self._cached_klines[pair] + else: + data = await self._api_async.fetch_ohlcv(pair, timeframe=tick_interval, since=since_ms) + + # keeping last candle time as last refreshed time of the pair + self._pairs_last_refreshed_time[pair] = data[-1][0] / 1000 + + # keeping candles in cache + self._cached_klines[pair] = data + logger.debug("done fetching %s ...", pair) return pair, data diff --git a/freqtrade/freqtradebot.py b/freqtrade/freqtradebot.py index f4e9c1d5b..d552dc65f 100644 --- a/freqtrade/freqtradebot.py +++ b/freqtrade/freqtradebot.py @@ -137,22 +137,9 @@ class FreqtradeBot(object): """ # TODO: maybe add since_ms to use async in the download-script? # TODO: Add tests for this and the async stuff above - - ticker_interval = self.strategy.ticker_interval - interval_in_seconds = constants.TICKER_INTERVAL_MINUTES[ticker_interval] * 60 - - should_not_update = ((self._klines_last_fetched_time + - interval_in_seconds + 1) > round(time.time())) - - if should_not_update: - return False - logger.debug("Refreshing klines for %d pairs", len(pair_list)) datatups = asyncio.get_event_loop().run_until_complete( - self.exchange.async_get_candles_history(pair_list, ticker_interval)) - - # fetching the timestamp of last candle - self._klines_last_fetched_time = datatups[0][1][-1][0] / 1000 + self.exchange.async_get_candles_history(pair_list, self.strategy.ticker_interval)) # updating klines self._klines = {pair: data for (pair, data) in datatups}