def __init__(self, strategy_trader, timeframe, depth, history, params=None): self.strategy_trader = strategy_trader # parent strategy-trader object params = params or {} self.tf = timeframe self.depth = depth # min samples size needed for processing self.history = history # sample history size self.last_timestamp = 0.0 self.next_timestamp = 0.0 # next waiting, to be processed ohlc timestamp self._update_at_close = params.get('update-at-close', False) self._signal_at_close = params.get('signal-at-close', False) self.candles_gen = CandleGenerator(self.strategy_trader.base_timeframe, self.tf) self._last_closed = False # last generated candle closed self.last_signal = None
def __init__(self, strategy_trader, timeframe, parent_timeframe, depth, history): self.strategy_trader = strategy_trader # parent strategy-trader object self.tf = timeframe self.parent_tf = parent_timeframe self.depth = depth # min samples size needed for processing self.history = history # sample history size self.profiling = False # profiling mean store the states of the indicators for any signals self.next_timestamp = 0 # next waiting, to be processed ohlc timestamp self.candles_gen = CandleGenerator(self.strategy_trader.base_timeframe, self.tf) # @todo do we distinct entry from exit signal (last) ? self.last_signal = None self.trend = 0 self.can_long = False self.can_short = False
def fetch_and_generate(self, market_id, timeframe, from_date=None, to_date=None, n_last=1000, fetch_option="", cascaded=None): if timeframe > 0 and timeframe not in self.GENERATED_TF: logger.error("Timeframe %i is not allowed !" % (timeframe, )) return generators = [] from_tf = timeframe self._last_ticks = [] self._last_ohlcs = {} if not from_date and n_last: # compute a from date today = datetime.now().astimezone(UTC()) if timeframe >= Instrument.TF_MONTH: from_date = ( today - timedelta(months=int(timeframe / Instrument.TF_MONTH) * n_last)).replace(day=1).replace(hour=0).replace( minute=0).replace(second=0) elif timeframe >= Instrument.TF_1D: from_date = (today - timedelta( days=int(timeframe / Instrument.TF_1D) * n_last)).replace( hour=0).replace(minute=0).replace(second=0) elif timeframe >= Instrument.TF_1H: from_date = (today - timedelta( hours=int(timeframe / Instrument.TF_1H) * n_last)).replace( minute=0).replace(second=0) elif timeframe >= Instrument.TF_1M: from_date = ( today - timedelta(minutes=int(timeframe / Instrument.TF_1M) * n_last)).replace(second=0) elif timeframe >= Instrument.TF_1S: from_date = (today - timedelta( seconds=int(timeframe / Instrument.TF_1S) * n_last)) from_date = from_date.replace(microsecond=0) if not to_date: today = datetime.now().astimezone(UTC()) if timeframe == Instrument.TF_MONTH: to_date = today + timedelta(months=1) else: to_date = today + timedelta(seconds=timeframe) to_date = to_date.replace(microsecond=0) # cascaded generation of candles if cascaded: for tf in Fetcher.GENERATED_TF: if tf > timeframe: # from timeframe greater than initial if tf <= cascaded: # until max cascaded timeframe generators.append(CandleGenerator(from_tf, tf)) from_tf = tf # store for generation self._last_ohlcs[tf] = [] else: from_tf = tf if timeframe > 0: self._last_ohlcs[timeframe] = [] n = 0 t = 0 if timeframe == 0: for data in self.fetch_trades(market_id, from_date, to_date, None): # store (int timestamp in ms, str bid, str ofr, str volume) Database.inst().store_market_trade( (self.name, market_id, data[0], data[1], data[2], data[3])) if generators: self._last_ticks.append( (float(data[0]) * 0.001, float(data[1]), float(data[2]), float(data[3]))) # generate higher candles for generator in generators: if generator.from_tf == 0: candles = generator.generate_from_ticks( self._last_ticks) if candles: for c in candles: self.store_candle(market_id, generator.to_tf, c) self._last_ohlcs[generator.to_tf] += candles # remove consumed ticks self._last_ticks = [] else: candles = generator.generate_from_candles( self._last_ohlcs[generator.from_tf]) if candles: for c in candles: self.store_candle(market_id, generator.to_tf, c) self._last_ohlcs[generator.to_tf] += candles # remove consumed candles self._last_ohlcs[generator.from_tf] = [] n += 1 t += 1 if n == 10000: n = 0 Terminal.inst().info("%i trades for %s..." % (t, market_id)) # calm down the storage of tick, if parsing is faster while Database.inst().num_pending_ticks_storage( ) > Fetcher.MAX_PENDING_TICK: time.sleep(Fetcher.TICK_STORAGE_DELAY ) # wait a little before continue logger.info("Fetched %i trades for %s" % (t, market_id)) elif timeframe > 0: for data in self.fetch_candles(market_id, timeframe, from_date, to_date, None): # store (int timestamp ms, str open bid, high bid, low bid, close bid, open ofr, high ofr, low ofr, close ofr, volume) Database.inst().store_market_ohlc( (self.name, market_id, data[0], int(timeframe), data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9])) if generators: candle = Candle(float(data[0]) * 0.001, timeframe) candle.set_bid_ohlc(float(data[1]), float(data[2]), float(data[3]), float(data[4])) candle.set_ofr_ohlc(float(data[5]), float(data[6]), float(data[7]), float(data[8])) candle.set_volume(float(data[9])) candle.set_consolidated(True) self._last_ohlcs[timeframe].append(candle) # generate higher candles for generator in generators: candles = generator.generate_from_candles( self._last_ohlcs[generator.from_tf]) if candles: for c in candles: self.store_candle(market_id, generator.to_tf, c) self._last_ohlcs[generator.to_tf].extend(candles) # remove consumed candles self._last_ohlcs[generator.from_tf] = [] n += 1 t += 1 if n == 1000: n = 0 Terminal.inst().info( "%i candles for %s in %s..." % (t, market_id, timeframe_to_str(timeframe))) logger.info("Fetched %i candles for %s in %s" % (t, market_id, timeframe_to_str(timeframe)))
def fetch_and_generate(self, market_id, timeframe, n_last=1, cascaded=None): """ For initial fetching of the current OHLC. """ if timeframe > 0 and timeframe not in self.GENERATED_TF: logger.error("Timeframe %i is not allowed !" % (timeframe, )) return generators = [] from_tf = timeframe if not market_id in self._last_ohlc: self._last_ohlc[market_id] = {} # compute a from date today = datetime.now().astimezone(UTC()) from_date = today - timedelta(seconds=timeframe * n_last) to_date = today last_ohlcs = {} # cascaded generation of candles if cascaded: for tf in Watcher.GENERATED_TF: if tf > timeframe: # from timeframe greater than initial if tf <= cascaded: # until max cascaded timeframe generators.append(CandleGenerator(from_tf, tf)) from_tf = tf # store for generation last_ohlcs[tf] = [] else: from_tf = tf if timeframe > 0: last_ohlcs[timeframe] = [] n = 0 for data in self.fetch_candles(market_id, timeframe, from_date, to_date, None): # store (int timestamp in ms, str bid, str ofr, str volume) if not self._read_only: Database.inst().store_market_trade( (self.name, market_id, data[0], data[1], data[2], data[3])) candle = Candle(float(data[0]) * 0.001, timeframe) candle.set_bid_ohlc(float(data[1]), float(data[2]), float(data[3]), float(data[4])) candle.set_ofr_ohlc(float(data[5]), float(data[6]), float(data[7]), float(data[8])) candle.set_volume(float(data[9])) if candle.timestamp >= Instrument.basetime(timeframe, time.time()): candle.set_consolidated(False) # current last_ohlcs[timeframe].append(candle) # only the last self._last_ohlc[market_id][timeframe] = candle # generate higher candles for generator in generators: candles = generator.generate_from_candles( last_ohlcs[generator.from_tf], False) if candles: if not self._read_only: for c in candles: self.store_candle(market_id, generator.to_tf, c) last_ohlcs[generator.to_tf].extend(candles) # only the last as current self._last_ohlc[market_id][generator.to_tf] = candles[-1] elif generator.current: self._last_ohlc[market_id][ generator.to_tf] = generator.current # remove consumed candles last_ohlcs[generator.from_tf] = [] n += 1 for k, ohlc in self._last_ohlc[market_id].items(): if ohlc: ohlc.set_consolidated(False)
def do_rebuilder(options): Terminal.inst().info("Starting SIIS rebuilder using %s identity..." % options['identity']) Terminal.inst().flush() # database manager Database.create(options) Database.inst().setup(options) timeframe = -1 cascaded = None if not options.get('timeframe'): timeframe = 60 # default to 1min else: if options['timeframe'] in TIMEFRAME_FROM_STR_MAP: timeframe = TIMEFRAME_FROM_STR_MAP[options['timeframe']] else: try: timeframe = int(options['timeframe']) except: pass if not options.get('cascaded'): cascaded = None else: if options['cascaded'] in TIMEFRAME_FROM_STR_MAP: cascaded = TIMEFRAME_FROM_STR_MAP[options['cascaded']] else: try: cascaded = int(options['cascaded']) except: pass if timeframe < 0: logger.error("Invalid timeframe") sys.exit(-1) from_date = options.get('from') to_date = options.get('to') if not to_date: today = datetime.now().astimezone(UTC()) if timeframe == Instrument.TF_MONTH: to_date = today + timedelta(months=1) else: to_date = today + timedelta(seconds=timeframe) to_date = to_date.replace(microsecond=0) if timeframe > 0 and timeframe not in GENERATED_TF: logger.error("Timeframe %i is not allowed !" % (timeframe,)) return for market in options['market'].split(','): if market.startswith('!') or market.startswith('*'): continue timestamp = from_date.timestamp() to_timestamp = to_date.timestamp() progression = 0.0 prev_update = timestamp count = 0 total_count = 0 progression_incr = (to_timestamp - timestamp) * 0.01 tts = 0.0 prev_tts = 0.0 generators = [] from_tf = timeframe last_ticks = [] last_ohlcs = {} if timeframe == Instrument.TF_TICK: tick_streamer = Database.inst().create_tick_streamer(options['broker'], market, from_date=from_date, to_date=to_date) else: ohlc_streamer = Database.inst().create_ohlc_streamer(options['broker'], market, timeframe, from_date=from_date, to_date=to_date) # cascaded generation of candles if cascaded: for tf in GENERATED_TF: if tf > timeframe: # from timeframe greater than initial if tf <= cascaded: # until max cascaded timeframe generators.append(CandleGenerator(from_tf, tf)) from_tf = tf # store for generation last_ohlcs[tf] = [] else: from_tf = tf if timeframe > 0: last_ohlcs[timeframe] = [] if timeframe == 0: while not tick_streamer.finished(): ticks = tick_streamer.next(timestamp + Instrument.TF_1M) count = len(ticks) total_count += len(ticks) for data in ticks: if data[0] > to_timestamp: break if generators: last_ticks.append(data) # generate higher candles for generator in generators: if generator.from_tf == 0: candles = generator.generate_from_ticks(last_ticks) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf] += candles # remove consumed ticks last_ticks = [] else: candles = generator.generate_from_candles(last_ohlcs[generator.from_tf]) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf] += candles # remove consumed candles last_ohlcs[generator.from_tf] = [] if timestamp - prev_update >= progression_incr: progression += 1 Terminal.inst().info("%i%% on %s, %s ticks/trades for 1 minute, current total of %s..." % (progression, format_datetime(timestamp), count, total_count)) prev_update = timestamp count = 0 if timestamp > to_timestamp: break timestamp += Instrument.TF_1M # by step of 1m # calm down the storage of tick, if parsing is faster while Database.inst().num_pending_ticks_storage() > TICK_STORAGE_DELAY: time.sleep(TICK_STORAGE_DELAY) # wait a little before continue elif timeframe > 0: while not ohlc_streamer.finished(): ohlcs = ohlc_streamer.next(timestamp + timeframe * 100) # per 100 count = len(ohlcs) total_count += len(ohlcs) for data in ohlcs: if data.timestamp > to_timestamp: break if generators: last_ohlcs[timeframe].append(candle) # generate higher candles for generator in generators: candles = generator.generate_from_candles(last_ohlcs[generator.from_tf]) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf].extend(candles) # remove consumed candles last_ohlcs[generator.from_tf] = [] prev_tts = tts timestamp = tts if timestamp - prev_update >= progression_incr: progression += 1 Terminal.inst().info("%i%% on %s, %s ticks/trades for 1 minute, current total of %s..." % (progression, format_datetime(timestamp), count, total_count)) prev_update = timestamp count = 0 if timestamp > to_timestamp: break if total_count == 0: timestamp += timeframe * 100 if progression < 100: Terminal.inst().info("100%% on %s, %s ticks/trades for 1 minute, current total of %s..." % (format_datetime(timestamp), count, total_count)) Terminal.inst().info("Flushing database...") Terminal.inst().flush() Database.terminate() Terminal.inst().info("Rebuild done!") Terminal.inst().flush() Terminal.terminate() sys.exit(0)
def do_rebuilder(options): Terminal.inst().info("Starting SIIS rebuilder using %s identity..." % options['identity']) Terminal.inst().flush() # database manager Database.create(options) Database.inst().setup(options) timeframe = -1 cascaded = None if not options.get('timeframe'): timeframe = 60 # default to 1min else: if options['timeframe'] in TIMEFRAME_FROM_STR_MAP: timeframe = TIMEFRAME_FROM_STR_MAP[options['timeframe']] else: try: timeframe = int(options['timeframe']) except: pass if not options.get('cascaded'): cascaded = None else: if options['cascaded'] in TIMEFRAME_FROM_STR_MAP: cascaded = TIMEFRAME_FROM_STR_MAP[options['cascaded']] else: try: cascaded = int(options['cascaded']) except: pass if timeframe < 0: logger.error("Invalid timeframe") sys.exit(-1) from_date = options.get('from') to_date = options.get('to') if not to_date: today = datetime.now().astimezone(UTC()) if timeframe == Instrument.TF_MONTH: to_date = today + timedelta(months=1) else: to_date = today + timedelta(seconds=timeframe) to_date = to_date.replace(microsecond=0) timeframe = options['timeframe'] if timeframe > 0 and timeframe not in GENERATED_TF: logger.error("Timeframe %i is not allowed !" % (timeframe,)) return for market in options['market'].split(','): if market.startswith('!') or market.startswith('*'): continue generators = [] from_tf = timeframe last_ticks = [] last_ohlcs = {} if timeframe == Instrument.TF_TICK: tick_streamer = Database.inst().create_tick_streamer(options['broker'], market, from_date=from_date, to_date=to_date) else: ohlc_streamer = Database.inst().create_ohlc_streamer(options['broker'], market, timeframe, from_date=from_date, to_date=to_date) # cascaded generation of candles if cascaded: for tf in GENERATED_TF: if tf > timeframe: # from timeframe greater than initial if tf <= cascaded: # until max cascaded timeframe generators.append(CandleGenerator(from_tf, tf)) from_tf = tf # store for generation last_ohlcs[tf] = [] else: from_tf = tf if timeframe > 0: last_ohlcs[timeframe] = [] n = 0 t = 0 timestamp = from_date.timestamp() + Instrument.TF_1M if timeframe == 0: while not tick_streamer.finished(): ticks = tick_streamer.next(timestamp) timestamp += Instrument.TF_1M # by step of 1M for data in ticks: if generators: last_ticks.append((float(data[0]) * 0.001, float(data[1]), float(data[2]), float(data[3]))) # generate higher candles for generator in generators: if generator.from_tf == 0: candles = generator.generate_from_ticks(last_ticks) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf] += candles # remove consumed ticks last_ticks = [] else: candles = generator.generate_from_candles(last_ohlcs[generator.from_tf]) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf] += candles # remove consumed candles last_ohlcs[generator.from_tf] = [] n += 1 t += 1 if n == 1000: n = 0 Terminal.inst().info("%i..." % t) Terminal.inst().flush() # calm down the storage of tick, if parsing is faster while Database.inst().num_pending_ticks_storage() > TICK_STORAGE_DELAY: time.sleep(TICK_STORAGE_DELAY) # wait a little before continue logger.info("Read %i trades" % t) elif timeframe > 0: while not ohlc_streamer.finished(): ohlcs = ohlc_streamer.next(timestamp) timestamp += Instrument.TF_1M # by step of 1M for data in ohlcs: if generators: candle = Candle(float(data[0]) * 0.001, timeframe) candle.set_bid_ohlc(float(data[1]), float(data[2]), float(data[3]), float(data[4])) candle.set_ofr_ohlc(float(data[5]), float(data[6]), float(data[7]), float(data[8])) candle.set_volume(float(data[9])) candle.set_consolidated(True) last_ohlcs[timeframe].append(candle) # generate higher candles for generator in generators: candles = generator.generate_from_candles(last_ohlcs[generator.from_tf]) if candles: for c in candles: store_ohlc(options['broker'], market, generator.to_tf, c) last_ohlcs[generator.to_tf].extend(candles) # remove consumed candles last_ohlcs[generator.from_tf] = [] n += 1 t += 1 if n == 1000: n = 0 Terminal.inst().info("%i..." % t) logger.info("Read %i candles" % t) Terminal.inst().info("Flushing database...") Terminal.inst().flush() Database.terminate() Terminal.inst().info("Rebuild done!") Terminal.inst().flush() Terminal.terminate() sys.exit(0)