async def _check_backtesting_results(backtesting1, backtesting2): if backtesting1 is not None and backtesting2 is not None: exchange_manager_1 = get_exchange_manager_from_exchange_id( get_independent_backtesting_exchange_manager_ids(backtesting1)[0]) exchange_manager_2 = get_exchange_manager_from_exchange_id( get_independent_backtesting_exchange_manager_ids(backtesting2)[0]) _, previous_profitability, previous_market_profitability, _, _ = get_profitability_stats(exchange_manager_1) _, current_profitability, current_market_profitability, _, _ = get_profitability_stats(exchange_manager_2) trades = get_trade_history(exchange_manager_1) open_orders = get_open_orders(exchange_manager_1) # ensure at least one order is either open or got filled assert trades + open_orders trades = open_orders = exchange_manager_1 = exchange_manager_2 = None # prevent memory leak # ensure no randomness in backtesting assert previous_profitability == current_profitability assert current_profitability != 0 assert previous_profitability != 0 assert previous_market_profitability == current_market_profitability backtestings = tuple(b for b in (backtesting1, backtesting2) if b is not None) for backtesting in backtestings: await stop_independent_backtesting(backtesting, memory_check=True, should_raise=True) await asyncio.wait_for(backtesting.post_backtesting_task, 5) for backtesting in backtestings: asyncio.get_event_loop().call_soon(check_independent_backtesting_remaining_objects, backtesting)
def get_trades_history(bot_api=None, symbol=None, independent_backtesting=None, since=None, as_dict=False): simulated_trades_history = [] real_trades_history = [] for exchange_manager in get_exchange_managers( bot_api=bot_api, independent_backtesting=independent_backtesting): if is_trader_enabled(exchange_manager): if is_trader_simulated(exchange_manager): simulated_trades_history += get_trade_history( exchange_manager, symbol, since, as_dict) else: real_trades_history += get_trade_history( exchange_manager, symbol, since, as_dict) return real_trades_history, simulated_trades_history
async def run_independent_backtestings_with_memory_check( config, tentacles_setup_config, backtesting_count=3): """ Will raise an error of an object is not deleted by garbage collector at the end of the backtesting process :param config: the global config to use in backtesting :param tentacles_setup_config: the tentacles setup config to use (with the tentacles to be tested) :param backtesting_count: number of backtestings to run to ensure no side effects, default is 3 :return: """ backtesting = None try: config[commons_constants.CONFIG_SIMULATOR][ commons_constants.CONFIG_STARTING_PORTFOLIO]["USDT"] = 10000 config[commons_constants.CONFIG_SIMULATOR][ commons_constants.CONFIG_STARTING_PORTFOLIO]["ETH"] = 20 for _ in range(backtesting_count): error_container = ErrorContainer() asyncio.get_event_loop().set_exception_handler( error_container.exception_handler) # enabling loggers is slowing down backtesting but can display useful debug info # from octobot.logger import init_logger # init_logger() backtesting = await _run_backtesting(config, tentacles_setup_config) exchange_manager = get_exchange_manager_from_exchange_id( get_independent_backtesting_exchange_manager_ids(backtesting) [0]) trades = get_trade_history(exchange_manager) open_orders = get_open_orders(exchange_manager) # ensure at least one order is either open or got filled assert trades + open_orders trades = open_orders = exchange_manager = None # prevent memory leak await stop_independent_backtesting(backtesting, memory_check=True) await asyncio.wait_for(backtesting.post_backtesting_task, 5) asyncio.get_event_loop().call_soon( check_independent_backtesting_remaining_objects, backtesting) await asyncio.create_task(error_container.check()) except Exception as e: if backtesting is not None: # do not get stuck in running backtesting await stop_independent_backtesting(backtesting, memory_check=False) await asyncio.wait_for(backtesting.post_backtesting_task, 5) raise e