Exemplo n.º 1
0
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)
Exemplo n.º 2
0
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)