def __init__(self, config, exchange_type): self.config = config 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( config) self.time_frame_get_times = {} self.tickers = {} self.fetched_trades = {} self.fetched_trades_counter = {} self.DEFAULT_LIMIT = 100 self.MIN_LIMIT = 20 self.MIN_ENABLED_TIME_FRAME = TimeFrameManager.find_config_min_time_frame( self.config_time_frames) self.DEFAULT_TIME_FRAME_RECENT_TRADE_CREATOR = self.MIN_ENABLED_TIME_FRAME self.CREATED_TRADES_BY_TIME_FRAME = 50 self.DEFAULT_TIME_FRAME_TICKERS_CREATOR = self.MIN_ENABLED_TIME_FRAME self.CREATED_TICKER_BY_TIME_FRAME = 1 self.backtesting = Backtesting(config, self) self._prepare() super().__init__(config, exchange_type, connect_to_online_exchange=False)
def __init__(self, config, exchange_type): self.config = config 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(config) self.time_frame_get_times = {} self.tickers = {} self.fetched_trades = {} self.fetched_trades_counter = {} self.DEFAULT_LIMIT = 100 self.MIN_LIMIT = 20 self.MIN_ENABLED_TIME_FRAME = TimeFrameManager.find_config_min_time_frame(self.config_time_frames) self.DEFAULT_TIME_FRAME_RECENT_TRADE_CREATOR = self.MIN_ENABLED_TIME_FRAME self.CREATED_TRADES_BY_TIME_FRAME = 50 self.DEFAULT_TIME_FRAME_TICKERS_CREATOR = self.MIN_ENABLED_TIME_FRAME self.CREATED_TICKER_BY_TIME_FRAME = 1 self.backtesting = Backtesting(config, self) self._prepare() super().__init__(config, exchange_type, connect_to_online_exchange=False)
def get_required_time_frames(cls, config): if CONFIG_FORCED_TIME_FRAME in config: return TimeFrameManager.parse_time_frames(config[CONFIG_FORCED_TIME_FRAME]) strategy_config = cls.get_specific_config() if STRATEGIES_REQUIRED_TIME_FRAME in strategy_config: return TimeFrameManager.parse_time_frames(strategy_config[STRATEGIES_REQUIRED_TIME_FRAME]) else: raise Exception(f"'{STRATEGIES_REQUIRED_TIME_FRAME}' is missing in {cls.get_config_file_name()}")
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 _init_time_frames(self): # Init time frames using enabled strategies EvaluatorCreator.init_time_frames_from_strategies(self.octobot.get_config()) self.time_frames = copy.copy(TimeFrameManager.get_config_time_frame(self.octobot.get_config())) # Init display time frame config_time_frames = TimeFrameManager.get_config_time_frame(self.octobot.get_config()) if TimeFrames.ONE_HOUR not in config_time_frames and not backtesting_enabled(self.octobot.get_config()): config_time_frames.append(TimeFrames.ONE_HOUR) TimeFrameManager.sort_config_time_frames(self.octobot.get_config())
def get_required_time_frames(cls, config): if CONFIG_FORCED_TIME_FRAME in config: return TimeFrameManager.parse_time_frames( config[CONFIG_FORCED_TIME_FRAME]) strategy_config = cls.get_evaluator_config() if STRATEGIES_REQUIRED_TIME_FRAME in strategy_config: return TimeFrameManager.parse_time_frames( strategy_config[STRATEGIES_REQUIRED_TIME_FRAME]) else: raise Exception("'{0}' is missing in {1}".format( STRATEGIES_REQUIRED_TIME_FRAME, cls.get_config_file_name()))
def __init__(self, config): self.start_time = time.time() self.config = config self.startup_config = copy.deepcopy(config) self.edited_config = copy.deepcopy(config) self.ready = False self.watcher = None # tools: used for alternative operations on a bot on the fly (ex: backtesting started from web interface) self.tools = { BOT_TOOLS_BACKTESTING: None, BOT_TOOLS_STRATEGY_OPTIMIZER: None, BOT_TOOLS_RECORDER: None, } # Logger self.logger = get_logger(self.__class__.__name__) # Advanced AdvancedManager.init_advanced_classes_if_necessary(self.config) # Debug tools self.performance_analyser = None if CONFIG_DEBUG_OPTION_PERF in self.config and self.config[ CONFIG_DEBUG_OPTION_PERF]: self.performance_analyser = PerformanceAnalyser() # Init time frames using enabled strategies EvaluatorCreator.init_time_frames_from_strategies(self.config) self.time_frames = TimeFrameManager.get_config_time_frame(self.config) # Init relevant evaluator names list using enabled strategies self.relevant_evaluators = EvaluatorCreator.get_relevant_evaluators_from_strategies( self.config) # Backtesting self.backtesting_enabled = Backtesting.enabled(self.config) # Add services to self.config[CONFIG_CATEGORY_SERVICES] ServiceCreator.create_services(self.config, self.backtesting_enabled) # Notifier self.config[CONFIG_NOTIFICATION_INSTANCE] = Notification(self.config) # Notify starting if self.config[CONFIG_NOTIFICATION_INSTANCE].enabled( CONFIG_NOTIFICATION_GLOBAL_INFO): self.config[CONFIG_NOTIFICATION_INSTANCE].notify_with_all( NOTIFICATION_STARTING_MESSAGE, False) self.symbol_threads_manager = {} self.exchange_traders = {} self.exchange_trader_simulators = {} self.trading_mode = None self.exchange_trading_modes = {} self.exchanges_list = {} self.symbol_evaluator_list = {} self.crypto_currency_evaluator_list = {} self.dispatchers_list = [] self.symbol_time_frame_updater_threads = []
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 __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 init_time_frames_from_strategies(config): time_frame_list = set() for strategies_eval_class in AdvancedManager.create_advanced_evaluator_types_list(StrategiesEvaluator, config): if strategies_eval_class.is_enabled(config, False): for time_frame in strategies_eval_class.get_required_time_frames(config): time_frame_list.add(time_frame) time_frame_list = TimeFrameManager.sort_time_frames(time_frame_list) config[CONFIG_TIME_FRAME] = time_frame_list
def set_default_config(self): time_frames = self.exchange.get_config_time_frame() min_time_frame = TimeFrameManager.find_config_min_time_frame(time_frames) self.specific_config = { CONFIG_TIME_FRAME: min_time_frame, CONFIG_REFRESH_RATE: TimeFramesMinutes[min_time_frame] / 6 * MINUTE_TO_SECONDS, }
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)
async def start_update_loop(self): error = None try: time_frames = self.evaluator_task_manager_by_time_frame_by_symbol.keys( ) # sort time frames to update them in order of accuracy time_frames = TimeFrameManager.sort_time_frames(time_frames) if time_frames and self.symbols: self.in_backtesting = self._init_backtesting_if_necessary( time_frames) # init refreshed_times at 0 for each time frame self.refreshed_times = { key: {symbol: 0 for symbol in self.symbols} for key in time_frames } # init last refresh times at 0 for each time frame self.time_frame_last_update = { key: {symbol: 0 for symbol in self.symbols} for key in time_frames } while self.keep_running: try: await self._trigger_update(time_frames) except CancelledError: self.logger.info("Update tasks cancelled.") except Exception as e: self.logger.error( f"exception when triggering update: {e}") self.logger.exception(e) else: self.logger.warning( "No time frames to monitor, going to sleep. " "This is normal if you did not activate any technical analysis evaluator." ) except Exception as e: self.logger.exception(e) if self.watcher is not None: error = e finally: if self.in_backtesting \ and self.symbols is not None \ and not self.exchange.get_exchange().get_backtesting().get_is_finished(self.symbols): if error is None: error = "backtesting did not finish properly." if self.watcher is not None: self.watcher.set_error(error) self.logger.error(error)
def __init__(self, config): self.start_time = time.time() self.config = config self.startup_config = copy.deepcopy(config) self.edited_config = copy.deepcopy(config) self.ready = False self.watcher = None self.current_loop_thread = None # tools: used for alternative operations on a bot on the fly (ex: backtesting started from web interface) self.tools = { BOT_TOOLS_BACKTESTING: None, BOT_TOOLS_STRATEGY_OPTIMIZER: None, BOT_TOOLS_RECORDER: None, } # Logger self.logger = get_logger(self.__class__.__name__) # Advanced AdvancedManager.init_advanced_classes_if_necessary(self.config) # Debug tools self.performance_analyser = None if CONFIG_DEBUG_OPTION_PERF in self.config and self.config[ CONFIG_DEBUG_OPTION_PERF]: self.performance_analyser = PerformanceAnalyser() # Init time frames using enabled strategies EvaluatorCreator.init_time_frames_from_strategies(self.config) self.time_frames = TimeFrameManager.get_config_time_frame(self.config) # Init relevant evaluator names list using enabled strategies self.relevant_evaluators = EvaluatorCreator.get_relevant_evaluators_from_strategies( self.config) # Backtesting self.backtesting_enabled = Backtesting.enabled(self.config) # Notifier self.config[CONFIG_NOTIFICATION_INSTANCE] = Notification(self.config) self.symbol_tasks_manager = {} self.exchange_traders = {} self.exchange_trader_simulators = {} self.trading_mode = None self.exchange_trading_modes = {} self.exchanges_list = {} self.symbol_evaluator_list = {} self.crypto_currency_evaluator_list = {} self.dispatchers_list = [] self.global_updaters_by_exchange = {} self.async_loop = None self.social_eval_tasks = [] self.real_time_eval_tasks = [] self.main_task_group = None
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 set_default_config(self): time_frames = self.exchange.get_config_time_frame() min_time_frame = TimeFrameManager.find_config_min_time_frame( time_frames) self.specific_config = { CONFIG_TIME_FRAME: min_time_frame, CONFIG_REFRESH_RATE: TimeFramesMinutes[min_time_frame] / 6 * MINUTE_TO_SECONDS, }
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 should_update_data(self, time_frame): previous_time_frame = TimeFrameManager.get_previous_time_frame(self.config_time_frames, time_frame, time_frame) previous_time_frame_sec = TimeFramesMinutes[previous_time_frame] previous_time_frame_updated_times = self.time_frame_get_times[previous_time_frame.value] current_time_frame_sec = TimeFramesMinutes[time_frame] current_time_frame_updated_times = self.time_frame_get_times[time_frame.value] if previous_time_frame_updated_times - ( current_time_frame_updated_times * (current_time_frame_sec / previous_time_frame_sec)) >= 0: return True else: return False
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 run(self): exchange = None symbol = None error = None try: time_frames = self.evaluator_threads_manager_by_time_frame.keys() # sort time frames to update them in order of accuracy time_frames = TimeFrameManager.sort_time_frames(time_frames) if time_frames: # figure out from an evaluator if back testing is running for this symbol evaluator_thread_manager = next( iter( self.evaluator_threads_manager_by_time_frame.values())) symbol = evaluator_thread_manager.get_symbol() # test if we need to initialize backtesting features backtesting_enabled = Backtesting.enabled( evaluator_thread_manager.get_evaluator().get_config()) if backtesting_enabled: exchange = evaluator_thread_manager.exchange.get_exchange() exchange.init_candles_offset(time_frames, symbol) # init refreshed_times at 0 for each time frame self.refreshed_times = {key: 0 for key in time_frames} # init last refresh times at 0 for each time frame self.time_frame_last_update = {key: 0 for key in time_frames} while self.keep_running: self._execute_update(symbol, exchange, time_frames, backtesting_enabled) else: self.logger.warning( "no time frames to monitor, going to sleep.") except Exception as e: self.logger.exception(e) if self.watcher is not None: error = e finally: if exchange is not None and symbol is not None and not exchange.get_backtesting( ).get_is_finished(symbol): if error is None: error = "backtesting did not finish properly." self.watcher.set_error(error)
def get_first_symbol_data(): bot = get_bot() exchanges = bot.get_exchanges_list() try: if exchanges: exchange = next(iter(exchanges.values())) evaluators = bot.get_symbol_evaluator_list() if evaluators: symbol_evaluator = _find_symbol_evaluator_with_data(evaluators, exchange) time_frame = TimeFrameManager.get_display_time_frame(bot.get_config()) return _get_candles_reply(exchange, symbol_evaluator, time_frame) except KeyError: return {} return {}
def __init__(self, config): self.start_time = time.time() self.config = config self.ready = False # Logger self.logger = logging.getLogger(self.__class__.__name__) # Advanced AdvancedManager.create_class_list(self.config) # Debug tools self.performance_analyser = None if CONFIG_DEBUG_OPTION_PERF in self.config and self.config[ CONFIG_DEBUG_OPTION_PERF]: self.performance_analyser = PerformanceAnalyser() # Init time frames using enabled strategies EvaluatorCreator.init_time_frames_from_strategies(self.config) self.time_frames = TimeFrameManager.get_config_time_frame(self.config) # Init relevant evaluator names list using enabled strategies self.relevant_evaluators = EvaluatorCreator.get_relevant_evaluators_from_strategies( self.config) # Add services to self.config[CONFIG_CATEGORY_SERVICES] ServiceCreator.create_services(self.config) # Notifier self.config[CONFIG_NOTIFICATION_INSTANCE] = Notification(self.config) # Notify starting if self.config[CONFIG_NOTIFICATION_INSTANCE].enabled( CONFIG_NOTIFICATION_GLOBAL_INFO): self.config[CONFIG_NOTIFICATION_INSTANCE].notify_with_all( NOTIFICATION_STARTING_MESSAGE) # Backtesting self.backtesting_enabled = None self.symbol_threads_manager = {} self.exchange_traders = {} self.exchange_trader_simulators = {} self.exchanges_list = {} self.symbol_evaluator_list = {} self.crypto_currency_evaluator_list = {} self.dispatchers_list = [] self.symbol_time_frame_updater_threads = []
def get_watched_symbol_data(symbol): bot = get_bot() exchanges = bot.get_exchanges_list() symbol = parse_get_symbol(symbol) try: if exchanges: exchange = next(iter(exchanges.values())) evaluators = bot.get_symbol_evaluator_list() if evaluators and symbol in evaluators: symbol_evaluator = evaluators[symbol] time_frame = TimeFrameManager.get_display_time_frame(bot.get_config()) return _get_candles_reply(exchange, symbol_evaluator, time_frame) except KeyError: return {} return {}
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 should_update_data(self, time_frame): previous_time_frame = TimeFrameManager.get_previous_time_frame( self.config_time_frames, time_frame, time_frame) previous_time_frame_sec = TimeFramesMinutes[previous_time_frame] previous_time_frame_updated_times = self.time_frame_get_times[ previous_time_frame.value] current_time_frame_sec = TimeFramesMinutes[time_frame] current_time_frame_updated_times = self.time_frame_get_times[ time_frame.value] if previous_time_frame_updated_times - ( current_time_frame_updated_times * (current_time_frame_sec / previous_time_frame_sec)) >= 0: return True else: return False
def start_optimizer(strategy, time_frames, evaluators, risks): tools = get_bot().get_tools() tools[BOT_TOOLS_STRATEGY_OPTIMIZER] = StrategyOptimizer( get_bot().get_config(), strategy) optimizer = tools[BOT_TOOLS_STRATEGY_OPTIMIZER] backtester = tools[BOT_TOOLS_BACKTESTING] if optimizer.get_is_computing(): return False, "Optimizer already running" elif backtester and backtester.get_is_computing(): return False, "A backtesting is already running" else: formatted_time_frames = TimeFrameManager.parse_time_frames(time_frames) float_risks = [float(risk) for risk in risks] thread = threading.Thread(target=optimizer.find_optimal_configuration, args=(evaluators, formatted_time_frames, float_risks)) thread.start() return True, "Optimizer started"
def should_update_data(self, symbol, time_frame, trader): previous_time_frame = TimeFrameManager.get_previous_time_frame( self.config_time_frames, time_frame, time_frame) previous_time_frame_sec = TimeFramesMinutes[previous_time_frame] previous_time_frame_updated_times = self.time_frame_get_times[ previous_time_frame.value] current_time_frame_sec = TimeFramesMinutes[time_frame] current_time_frame_updated_times = self.time_frame_get_times[ time_frame.value] time_refresh_condition = ( previous_time_frame_updated_times - (current_time_frame_updated_times * (current_time_frame_sec / previous_time_frame_sec)) >= 0) recent_trades_condition = trader.get_open_orders() and ( self.fetched_trades_counter[symbol] > current_time_frame_updated_times) return time_refresh_condition and (not trader.get_open_orders() or recent_trades_condition)
def __init__(self, config): self.start_time = time.time() self.config = config self.ready = False # Logger self.logger = logging.getLogger(self.__class__.__name__) # Advanced AdvancedManager.create_class_list(self.config) # Debug tools self.performance_analyser = None if CONFIG_DEBUG_OPTION_PERF in self.config and self.config[CONFIG_DEBUG_OPTION_PERF]: self.performance_analyser = PerformanceAnalyser() self.time_frames = TimeFrameManager.get_config_time_frame(self.config) # Add services to self.config[CONFIG_CATEGORY_SERVICES] ServiceCreator.create_services(self.config) # Notifier self.config[CONFIG_NOTIFICATION_INSTANCE] = Notification(self.config) # Notify starting self.config[CONFIG_NOTIFICATION_INSTANCE].notify_with_all(NOTIFICATION_STARTING_MESSAGE) # Backtesting self.backtesting_enabled = None self.symbol_threads_manager = {} self.exchange_traders = {} self.exchange_trader_simulators = {} self.exchanges_list = {} self.symbol_evaluator_list = {} self.crypto_currency_evaluator_list = {} self.dispatchers_list = [] self.symbol_time_frame_updater_threads = []
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)
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)
def run(self): exchange = None symbol = None error = None try: time_frames = self.evaluator_threads_manager_by_time_frame.keys() # sort time frames to update them in order of accuracy time_frames = TimeFrameManager.sort_time_frames(time_frames) if time_frames: # figure out from an evaluator if back testing is running for this symbol evaluator_thread_manager = next(iter(self.evaluator_threads_manager_by_time_frame.values())) symbol = evaluator_thread_manager.get_symbol() # test if we need to initialize backtesting features backtesting_enabled = Backtesting.enabled(evaluator_thread_manager.get_evaluator().get_config()) if backtesting_enabled: exchange = evaluator_thread_manager.exchange.get_exchange() exchange.init_candles_offset(time_frames, symbol) # init refreshed_times at 0 for each time frame self.refreshed_times = {key: 0 for key in time_frames} # init last refresh times at 0 for each time frame self.time_frame_last_update = {key: 0 for key in time_frames} while self.keep_running: now = time.time() for time_frame in time_frames: # backtesting doesn't need to wait a specific time frame to end to refresh data if backtesting_enabled: try: if exchange.should_update_data(time_frame, symbol): self._refresh_data(time_frame) except BacktestingEndedException as e: self.logger.info(e) self.keep_running = False exchange.end_backtesting(symbol) break # if data from this time frame needs an update elif now - self.time_frame_last_update[time_frame] \ >= TimeFramesMinutes[time_frame] * MINUTE_TO_SECONDS: try: self._refresh_data(time_frame) except Exception as e: self.logger.error(f" when refreshing data for time frame {time_frame} for {symbol}: " f"{e}") self.logger.exception(e) self.time_frame_last_update[time_frame] = time.time() self._update_pause(backtesting_enabled, now) else: self.logger.warning("no time frames to monitor, going to sleep.") except Exception as e: self.logger.exception(e) if self.watcher is not None: error = e finally: if exchange is not None and symbol is not None and not exchange.get_backtesting().get_is_finished(symbol): if error is None: error = "backtesting did not finish properly." self.watcher.set_error(error)