def dprint_last_candles(self, tf, lookback): if lookback > len(self.candles[tf]): lookback = len(self.candles[tf]) for ts in range(-lookback, 0): candle = self.candles[tf][ts] self.debug( "CANDLES(%s), T: %s, O: %.2f, H: %2.f, L: %.2f, C: %.2f, V: %.2f" % (tf, utilities.ts2label(candle[0]), candle[1], candle[2], candle[3], candle[4], candle[5]))
def update_candles(self, tf, lookback=100): self.debug("Update candles for %s, lookback %d" % (tf, lookback)) if (not tf in self.candles.keys()): self.debug("tf %s not in candles keys" % tf) elif len(self.candles[tf]) < lookback: self.debug("current candles length %d less than lookback %d" % (len(self.candles[tf]), lookback)) if (not tf in self.candles.keys()) or len(self.candles[tf]) < lookback: self.preload_candles(tf, lookback) self.debug("Preloading candles for tf %s, lookback %d" % (tf, lookback)) else: self.debug("updating candles for %s, lookback %d" % (tf, lookback)) last_ts = self.get_last_ts(tf) self.debug("Last ts is %d" % last_ts) lag = time.time() - last_ts / 1000. self.debug("Lag is %d" % lag) currlen = len(self.candles[tf]) self.debug("current length for tf %s is %d" % (tf, currlen)) candles = self.fetch_candles( tf, start=((time.time() - (lag + self.tf_seconds[tf])) * 1000)) self.debug("Candles length is %d" % len(candles)) if lag > self.tf_seconds[tf]: self.debug("Fetching fresh data for lag %d greater than %d" % (lag, self.tf_seconds[tf])) it = 0 while it < len(candles) and candles[it][0] < last_ts: self.debug("it %d, ts %d" % (it, candles[it][0])) it = it + 1 if it < len(candles): self.debug("Old candles last ts now %s" % utilities.ts2label(self.get_last_ts(tf))) self.candles[tf] = self.candles[tf][-currlen:-1] self.debug("Old candles last ts now %s" % utilities.ts2label(self.get_last_ts(tf))) self.candles[tf].extend(candles[it:]) self.debug("Old candles last tses now %s, %s" % (utilities.ts2label(self.candles[tf][-2][0]), utilities.ts2label(self.get_last_ts(tf)))) trimlength = currlen if (lookback > trimlength): trimlength = lookback self.debug("Resizing candles to %d" % trimlength) self.candles[tf] = self.candles[tf][ -trimlength:] # prevent indefinite expansion self.debug("New last timestamp is %d" % self.get_last_ts(tf)) else: self.candles[tf] = self.candles[tf][-currlen:-1] self.debug("Old candles last ts now %s" % utilities.ts2label(self.get_last_ts(tf))) self.debug("Refreshing last candle for lag %d less than %d" % (lag, self.tf_seconds[tf])) self.candles[tf].append(candles[-1]) self.debug("Update candles last ts now %s" % utilities.ts2label(self.get_last_ts(tf)))
def fetch_candles(self, tf, start=None, end=None): rawdata = None apitry = 0 if not start: start = (time.time() - self.tf_seconds[tf] * 100) * 1000 if not end: end = time.time() * 1000 start = start - (start % self.tf_seconds[tf]) limit = math.ceil((end - start) / 1000. / self.tf_seconds[tf]) # start = decimal.Decimal(str(start)) # limit = decimal.Decimal(str(limit)) start = int(start) limit = int(limit) self.debug("Limit %d candles from start %d to end %d" % (limit, start, end)) self.debug(type(start)) while not rawdata and apitry < self.apitrylimit: try: self.debug("Fetching %s candles with start ts %d, limit %d" % (tf, start, limit)) rawdata = self.exchange.fetch_ohlcv(self.symbol, tf, start, limit) except (ccxt.ExchangeError, ccxt.DDoSProtection, ccxt.AuthenticationError, ccxt.ExchangeNotAvailable, ccxt.RequestTimeout) as error: self.debug( "failed to connect to api to fetch candles, sleeping for %d seconds, try %d of %d" % (self.apitrysleep + apitry * 2, apitry, self.apitrylimit)) self.debug(error) time.sleep(self.apitrysleep + apitry * 2) apitry = apitry + 1 self.debug("Last candle ts: %s" % utilities.ts2label(rawdata[-1][0])) # if time.time()*1000 - rawdata[-1][0] < self.tf_seconds[tf]: # self.debug("Last candle is not complete with ts %s, dropping" % utilities.ts2label(rawdata[-1][0])) self.debug("Fetched %d candles" % len(rawdata)) if (len(rawdata) < limit - 1): self.logger.debug("Asked for %d candles but received %d" % (limit, len(rawdata))) return rawdata