def backtest(markets, entry_funcs, exit_funcs=[], _date=[0, 0], smas=var.default_smas, emas=var.default_emas, interval=var.default_interval, plot=False, to_file=True, from_file=False, exchange="bittrex", base_market='BTC', log_level=1, mp_level="medium"): ''' Backtests strategies. Args: markets(list): list with markets to backtest or empty to test all available markets. entry_funcs(list): list of entry functions to test. exit_funcs(list): list of entry functions to test. _date(list): init and end point to backtest. Ex: '1-1-2017 11:10' smas(list): list of SMA values to use. emas(list): list of EMA values to use. interval(string): time between measures. plot(bool): plot data. to_file(bool): plot to file. from_file(bool): get data from file. base_market(string): base market to use. log_level(int): log level - 0-2. mp_level(string): multiprocessing level - [low, medium, high]. Returns: bool: returns True in case of success. log_level: 0 - Only presents total. 1 - Writes logs to file. 2 - Writes logs to file and prints on screen. Default is 2. ''' signal.signal(signal.SIGINT, signal_handler) #global cached if not from_file: # Connects to DB. try: db_client = connect_db() except Exception as e: log(str(e), 0, log_level) sys.exit(1) else: db_client = 0 # For all markets. if not len(markets): y = 'y' #raw_input("Want to run all markets? ") if y == 'y': if from_file: markets = get_markets_on_files(interval, base=base_market) else: markets = get_markets_list(base_market, exchange) else: log("Without files to analyse.", 0, log_level) # Prevents errors from markets and funcs as str. if not isinstance(markets, list): markets = [markets] if not isinstance(entry_funcs, list): entry_funcs = [entry_funcs] if not isinstance(exit_funcs, list): exit_funcs = [exit_funcs] # For selected markets. if from_file: markets = manage_files(markets, interval=interval) log(str(len(markets)) + " files/chunks to analyse...", 1, log_level) # Create a multiprocessing Pool pool = Pool(num_processors(mp_level)) # Display information about pool. total = pool.map( partial(backtest_market, entry_funcs, exit_funcs, interval, _date, smas, emas, from_file, to_file, plot, exchange, db_client, log_level), markets) pool.close() pool.join() log(" Total > " + str(sum(total)), 1, log_level) for k in cached.keys(): if cached[k]['last'] < 1: del cached[k] else: cached[k]['last'] = cached[k]['last'] - 1 return sum(total)
def test_num_processors(self): self.assertEqual(aux.num_processors("low"), 1) self.assertEqual(aux.num_processors(2), 2)
def backtest(markets, entry_funcs, exit_funcs=None, _date=None, smas=var.default_smas, emas=var.default_emas, interval=var.default_interval, plot=False, to_file=True, from_file=False, exchange="bittrex", base_market='BTC', mp_level="medium"): """ Backtests strategies. Args: markets(list): list with markets to backtest or empty to test all available markets. entry_funcs(list): list of entry functions to test. exit_funcs(list): list of entry functions to test. _date(list): init and end point to backtest. Ex: '1-1-2017 11:10' smas(list): list of SMA values to use. emas(list): list of EMA values to use. interval(string): time between measures. plot(bool): plot data. to_file(bool): plot to file. from_file(bool): get data from file. exchange(string): Defines exchange. base_market(string): base market to use. mp_level(string): multiprocessing level - [low, medium, high]. Returns: bool: returns True in case of success. """ if _date is None: _date = [0, 0] if exit_funcs is None: exit_funcs = [] signal.signal(signal.SIGINT, signal_handler) if not from_file: # Tries connection to DB. try: db_client = connect_db() except Exception as e: log.exception(e) sys.exit(1) finally: db_client.close() # For all markets. if not len(markets): y = 'y' # raw_input("Want to run all markets? ") if y == 'y': if from_file: markets = get_markets_on_files(interval, base=base_market) else: markets = get_markets_list(base_market, exchange) else: log.error("Without files to analyse.") # Prevents errors from markets and funcs as str. if not isinstance(markets, list): markets = [markets] if not isinstance(entry_funcs, list): entry_funcs = [entry_funcs] if not isinstance(exit_funcs, list): exit_funcs = [exit_funcs] # For selected markets. if from_file: markets = manage_files(markets, interval=interval) log.debug(f"{str(len(markets))} files/chunks to analyse...") # Create a multiprocessing Pool pool = Pool(num_processors(mp_level)) # Display information about pool. total = pool.map( partial(backtest_market, entry_funcs, exit_funcs, interval, _date, smas, emas, from_file, to_file, plot, exchange), markets) pool.close() pool.join() log.info(f' Total > {sum(total)}') if var.desktop_info: desktop_notification({ 'type': 'backtest', 'title': "Backtest completed", 'message': f'Result: {sum(total)}' }) for k in cached.keys(): if cached[k]['last'] < 1: del cached[k] else: cached[k]['last'] = cached[k]['last'] - 1 return sum(total)