Moving should_not_update logic to async function per pair. if there is

no new candle, async function will just return the last cached candle
locally and doesn’t hit the API
This commit is contained in:
misagh 2018-08-09 12:47:26 +02:00
parent cef09f49a6
commit cb26085229
2 changed files with 27 additions and 16 deletions

View File

@ -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

View File

@ -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}