def should_update_data(self, time_frame, symbol): smallest_time_frame = TimeFrameManager.find_min_time_frame( self.config_time_frames) if smallest_time_frame == time_frame: # always True: refresh smallest timeframe systematically when possible return True else: smallest_time_frame_sec = TimeFramesMinutes[smallest_time_frame] smallest_time_frame_updated_times = self.time_frame_get_times[ symbol][smallest_time_frame.value] # - 1 because smallest timeframe is the 1st to be updated: always return true for it but others need not to # be biased by the previous + 1 from current timeframe update wave smallest_time_frame_updated_times_to_compare = smallest_time_frame_updated_times - 1 \ if smallest_time_frame_updated_times > 0 else 0 current_time_frame_sec = TimeFramesMinutes[time_frame] current_time_frame_updated_times = self.time_frame_get_times[ symbol][time_frame.value] try: smallest_time_frame_timestamp = self._get_current_timestamp( smallest_time_frame, symbol, 1) wanted_time_frame_timestamp = self._get_current_timestamp( time_frame, symbol) return wanted_time_frame_timestamp <= smallest_time_frame_timestamp + ( smallest_time_frame_sec / 2) except IndexError: return False
def _extract_data_with_limit(self, symbol, time_frame): if not self.min_time_frames_offset: self.min_time_frames_offset = TimeFrameManager.find_min_time_frame( self.time_frames_offset[symbol].keys()) to_use_time_frame = time_frame.value or self.min_time_frames_offset.value return self._extract_from_indexes( self.get_ohlcv(symbol)[to_use_time_frame], self._get_candle_index(to_use_time_frame, symbol), symbol)
def __init__(self, run_profitabilities, trades_counts, risk, time_frames, evaluators, strategy): self.run_profitabilities = run_profitabilities self.trades_counts = trades_counts self.risk = risk self.time_frames = time_frames self.min_time_frame = TimeFrameManager.find_min_time_frame(self.time_frames) self.evaluators = evaluators self.strategy = strategy
def _set_config_time_frame(self): for time_frame in TimeFrameManager.get_config_time_frame(self.config): if self.time_frame_exists(time_frame.value): self.time_frames.append(time_frame) # add shortest timeframe for realtime evaluators client_shortest_time_frame = TimeFrameManager.find_min_time_frame(self.client_time_frames, MIN_EVAL_TIME_FRAME) if client_shortest_time_frame not in self.time_frames: self.time_frames.append(client_shortest_time_frame)
def set_default_config(self): time_frames = self.exchange.get_exchange_manager().get_config_time_frame() min_time_frame = TimeFrameManager.find_min_time_frame(time_frames, MIN_EVAL_TIME_FRAME) refresh_rate = DEFAULT_WEBSOCKET_REAL_TIME_EVALUATOR_REFRESH_RATE_SECONDS if \ self.exchange.get_exchange_manager().websocket_available() \ else DEFAULT_REST_REAL_TIME_EVALUATOR_REFRESH_RATE_SECONDS self.specific_config = { CONFIG_TIME_FRAME: min_time_frame, CONFIG_REFRESH_RATE: refresh_rate, }
def get_recent_trades(self, symbol, limit=50): self._ensure_available_data(symbol) time_frame_to_use = TimeFrameManager.find_min_time_frame( self._get_used_time_frames(symbol)) index = 0 if symbol in self.time_frames_offset and time_frame_to_use.value in self.time_frames_offset[symbol] \ and time_frame_to_use.value in self.time_frame_get_times[symbol]: # -2 because take into account the +1 in self.time_frame_get_times and the fact that it's an index index = self.time_frames_offset[symbol][time_frame_to_use.value] \ + self.time_frame_get_times[symbol][time_frame_to_use.value] \ - 2 trades = self._create_recent_trades(symbol, time_frame_to_use, index) self.get_symbol_data(symbol).update_recent_trades(trades)
def should_update_data(self, time_frame, symbol): smallest_time_frame = TimeFrameManager.find_min_time_frame(self.config_time_frames) if smallest_time_frame == time_frame: # always True: refresh smallest timeframe systematically when possible return True else: smallest_time_frame_sec = TimeFramesMinutes[smallest_time_frame] try: smallest_time_frame_timestamp = self._get_current_timestamp(smallest_time_frame, symbol, 1) wanted_time_frame_timestamp = self._get_current_timestamp(time_frame, symbol) return wanted_time_frame_timestamp <= smallest_time_frame_timestamp + (smallest_time_frame_sec / 2) except IndexError: return False
def _find_min_time_frame_to_consider(self, time_frames, symbol): time_frames_to_consider = copy.copy(time_frames) self.min_time_frame_to_consider[symbol] = None while not self.min_time_frame_to_consider[symbol] and time_frames_to_consider: potential_min_time_frame_to_consider = TimeFrameManager.find_min_time_frame(time_frames_to_consider).value if potential_min_time_frame_to_consider in self.data[symbol]: self.min_time_frame_to_consider[symbol] = potential_min_time_frame_to_consider else: time_frames_to_consider.remove(potential_min_time_frame_to_consider) if self.min_time_frame_to_consider[symbol]: return self.data[symbol][self.min_time_frame_to_consider[symbol]][self.MIN_LIMIT] \ [PriceIndexes.IND_PRICE_TIME.value] else: self.logger.error(f"No data for the timeframes: {time_frames} in loaded backtesting file.") if Backtesting.enabled(self.config): self.backtesting.end(symbol)
def __init__(self, config, exchange_type, exchange_manager): super().__init__(config, exchange_type) self.initializing = True self.exchange_manager = exchange_manager if CONFIG_BACKTESTING not in self.config: raise Exception("Backtesting config not found") self.symbols = None self.data = None self._get_symbol_list() self.config_time_frames = TimeFrameManager.get_config_time_frame( self.config) # set exchange manager attributes self.exchange_manager.client_symbols = self.symbols self.exchange_manager.client_time_frames = self.get_available_timeframes( ) self.exchange_manager.time_frames = self.config_time_frames self.time_frame_get_times = {} self.time_frames_offset = {} self.min_time_frame_to_consider = {} self.min_time_frames_offset = None self.DEFAULT_LIMIT = 100 self.MIN_LIMIT = 30 # used to force price movement self.recent_trades_multiplier_factor = 1 self.MIN_ENABLED_TIME_FRAME = TimeFrameManager.find_min_time_frame( self.config_time_frames) self.DEFAULT_TIME_FRAME_RECENT_TRADE_CREATOR = self.MIN_ENABLED_TIME_FRAME self.DEFAULT_TIME_FRAME_TICKERS_CREATOR = self.MIN_ENABLED_TIME_FRAME self.RECENT_TRADES_TO_CREATE = max(SIMULATOR_LAST_PRICES_TO_CHECK, ORDER_CREATION_LAST_TRADES_TO_USE) self.backtesting = Backtesting(self.config, self) self._prepare() self.initializing = False
def get_number_of_candles(file_path): try: content = read_data_file(file_path) if content: candles_info = [] min_time_frame = TimeFrameManager.find_min_time_frame( content.keys()) additional_time_frames = [min_time_frame.value] for tf in TIME_FRAMES_TO_DISPLAY: if tf not in additional_time_frames: additional_time_frames.append(tf) for time_frame in additional_time_frames: if time_frame in content: tf_content = content[time_frame] candles_info.append( f"{time_frame}: {len(tf_content[0]) if tf_content else 0}" ) return ", ".join(candles_info) return 0 except Exception as e: return f"Impossible to read datafile: {e}"
def get_number_of_candles(file_path): try: content = read_data_file(file_path) if content: candles_info = [] time_frames = get_time_frames(file_path, content) min_time_frame = TimeFrameManager.find_min_time_frame(time_frames) additional_time_frames = [min_time_frame.value] for tf in TIME_FRAMES_TO_DISPLAY: if tf not in additional_time_frames: additional_time_frames.append(tf) ohlcv_per_tf = get_ohlcv_per_timeframe(file_path, content) for time_frame in additional_time_frames: if time_frame in ohlcv_per_tf: tf_content = ohlcv_per_tf[time_frame] candles_count = get_candles_count(file_path, tf_content) if tf_content else 0 candles_info.append(f"{time_frame}: {candles_count}") return ", ".join(candles_info) return 0 except Exception as e: return f"Impossible to read datafile: {e}"
def _extract_data_with_limit(self, symbol, time_frame): to_use_time_frame = time_frame.value if time_frame is not None \ else TimeFrameManager.find_min_time_frame(self.time_frames_offset[symbol].keys()).value return self._extract_from_indexes( self.data[symbol][to_use_time_frame], self._get_candle_index(to_use_time_frame, symbol), symbol)