예제 #1
0
def tick_by_tick(market,
                 entry_funcs,
                 exit_funcs,
                 interval=var.default_interval,
                 smas=var.default_smas,
                 emas=var.default_emas,
                 refresh_interval=1,
                 from_file=True,
                 plot=False,
                 log_level=2):
    '''
    Simulates a working bot, in realtime or in faster speed,
     using pre own data from DB or file,
     to test an autonomous bot on a specific market.

    Args:
        markets(string): list with markets to backtest or
            empty to run all available markets.
        entry_funcs(list): list of entry functions to test.
        exit_funcs(list): list of entry functions to test.
        interval(string): time between measures.
        smas(list): list of SMA values to use.
        emas(list): list of EMA values to use.
        refresh_interval(int): Refresh rate.
        main_coins(list):
    '''
    #log_level:
    #   0 - Only presents total.
    #   1 - Writes logs to file.
    #   2 - Writes logs to file and prints on screen.
    #   Default is 2.

    #plt.ion()

    var.global_log_level = log_level

    signal.signal(signal.SIGINT, signal_handler)

    date = [0, 0]

    total = 0

    #market = check_market_name(market)

    entry_points_x = []
    entry_points_y = []

    exit_points_x = []
    exit_points_y = []

    if not isinstance(entry_funcs, list): entry_funcs = [entry_funcs]
    if not isinstance(exit_funcs, list): exit_funcs = [exit_funcs]

    print(f'[Market analysis]: {market}')

    if from_file:
        try:
            data = get_data_from_file(market, interval=interval)
        except Exception as e:
            log(str(e), 1)
            log('[ERROR] Can\'t find ' + market + ' in files.', 1)
            return 0

        data_init = data

        #if type(_date[0]) is str:
        #    date[0], date[1] = time_to_index(data, _date)

        #if date[1] == 0:
        #    data = data[date[0]:]

        #else:
        #    data = data[date[0]:date[1]]

    else:
        try:
            data = get_historical_data(market,
                                       interval=interval,
                                       init_date=_date[0],
                                       end_date=_date[1])
            date[0], date[1] = 0, len(data)
            data_init = data

        except Exception as e:
            log(str(e), 1)
            log('[ERROR] Can\'t find ' + market + ' in BD.', 1)
            return 0
            #continue

    aux_buy = False
    buy_price = 0
    high_price = 0

    #plt.show()

    #Tests several functions.
    for i in range(len(data) - 110):
        start_time = time()
        #print(data_init.Last.iloc[i])
        if not aux_buy:
            if is_time_to_buy(data[i:i + 110], entry_funcs, smas, emas):

                buy_price = data_init.Ask.iloc[i + 109 + date[0]]
                high_price = buy_price

                entry_points_x.append(i + 109)
                entry_points_y.append(data_init.Ask.iloc[i + 109 + date[0]])

                if exit_funcs:
                    aux_buy = True

                print(f'''{data_init.time.iloc[i + 109 + date[0]]} \
                     [BUY] @ {data_init.Ask.iloc[i + 109 + date[0]]}''')

        else:
            # Used for trailing stop loss.
            if data_init.Last.iloc[i + 109 + date[0]] > high_price:
                high_price = data_init.Last.iloc[i + 109 + date[0]]

            if is_time_to_exit(data[i:i + 110],
                               exit_funcs,
                               smas,
                               emas,
                               stop=0,
                               bought_at=buy_price,
                               max_price=high_price):

                exit_points_x.append(i + 109)
                exit_points_y.append(data_init.Bid.iloc[i + 109 + date[0]])

                aux_buy = False

                total += round(
                    ((data_init.Bid.iloc[i + 109 + date[0]] - buy_price) /
                     buy_price) * 100, 2)

                print(f'''{data_init.time.iloc[i + 109 + date[0]]} \
                     [SELL]@ {data_init.Bid.iloc[i + 109 + date[0]]}''')

                print(f'[P&L] > {total}%.')

        #plt.plot(data.Last.iloc[i:i+50])
        #plt.draw()
        #plt.clf()

        # In case of processing time is bigger than *refresh_interval* doesn't sleep.
        if refresh_interval - (time() - start_time) >= 0:
            sleep(refresh_interval - (time() - start_time))

    return total
예제 #2
0
def backtest_market(entry_funcs, exit_funcs, interval, _date, smas, emas,
                    from_file, to_file, plot, exchange, db_client, log_level,
                    market):
    '''
    Backtests strategies for a specific market.

    Args:
        entry_funcs(list): list of entry functions to test.
        exit_funcs(list): list of entry functions to test.
        interval(string): time between measures.
        _date(list): init and end point to backtest.
        smas(list): list of SMA values to use.
        emas(list): list of EMA values to use.
        to_file(bool): plot to file.
        from_file(bool): get data from file.
        plot(bool): plot data.
        markets(string): list with markets to backtest or empty to test all available markets.

    Returns:
        float: returns backtests profit & loss value for applied strategies.
    '''

    date = [0, 0]

    total = 0

    #market = check_market_name(market)
    #global cached
    is_cached = False

    entry_points_x = []
    entry_points_y = []

    exit_points_x = []
    exit_points_y = []

    full_log = '[Market analysis]: ' + market + '\n'

    if from_file:
        try:
            data = get_data_from_file(market, interval=interval)
        except Exception as e:
            log(str(e), 0, log_level)
            log('[ERROR] Can\'t find ' + market + ' in files.', 0, log_level)
            return 0

        data_init = data

        if isinstance(_date[0], str):
            date[0], date[1] = time_to_index(data, _date)
        else:
            date = _date

        if date[1] == 0:
            data = data[date[0]:]
        else:
            data = data[date[0]:date[1]]

    else:
        if market in cached and \
           cached[market]['interval'] == interval and \
           cached[market]['init_date'] == _date[0] and \
           cached[market]['end_date'] == _date[1]:
            # Check if cached data is the same as you want.
            data = cached[market]['data']
            cached[market]['last'] = 2
            is_cached = True
        else:
            try:
                data = get_historical_data(market,
                                           interval=interval,
                                           init_date=_date[0],
                                           end_date=_date[1],
                                           exchange=exchange)
                date[0], date[1] = 0, len(data)
            except Exception as e:
                log(str(e), 0, log_level)
                log('[ERROR] Can\'t find ' + market + ' in BD.', 0, log_level)
                return 0
            #continue

        data_init = data

    aux_buy = False
    buy_price = 0
    high_price = 0

    #    # Test for volume.
    #    if data.BaseVolume.mean() < 20:
    #        log(full_log, 1, log_level)
    #        del data
    #        del data_init
    #        return 0

    #Tests several functions.
    for i in range(len(data) - 110):
        if not aux_buy:
            if is_time_to_buy(data[i:i + 110], entry_funcs, smas, emas):

                buy_price = data_init.Ask.iloc[i + 109 + date[0]]
                high_price = buy_price

                entry_points_x.append(i + 109)
                entry_points_y.append(data_init.Ask.iloc[i + 109 + date[0]])

                if exit_funcs:
                    aux_buy = True

                full_log += str(data_init.time.iloc[i + 109 + date[0]]) + \
                    ' [BUY] @ ' + str(data_init.Ask.iloc[i + 109 + date[0]]) + '\n'

        else:
            # Used for trailing stop loss.
            if data_init.Last.iloc[i + 109 + date[0]] > high_price:
                high_price = data_init.Last.iloc[i + 109 + date[0]]

            if is_time_to_exit(data[i:i + 110],
                               exit_funcs,
                               smas,
                               emas,
                               stop=0,
                               bought_at=buy_price,
                               max_price=high_price):

                exit_points_x.append(i + 109)
                exit_points_y.append(data_init.Bid.iloc[i + 109 + date[0]])

                aux_buy = False

                total += round(
                    ((data_init.Bid.iloc[i + 109 + date[0]] - buy_price) /
                     buy_price) * 100, 2)

                full_log += str(data_init.time.iloc[i + 109 + date[0]]) + \
                    ' [SELL]@ ' + str(data_init.Bid.iloc[i + 109 + date[0]]) + '\n'

                full_log += '[P&L] > ' + str(total) + '%.' + '\n'

    del data_init

    # Use plot_data for just a few markets. If you try to run plot_data for several markets,
    # computer can start run really slow.
    try:
        if plot:
            plot_data(data,
                      name=market,
                      date=[0, 0],
                      smas=smas,
                      emas=None,
                      entry_points=(entry_points_x, entry_points_y),
                      exit_points=(exit_points_x, exit_points_y),
                      show_smas=True,
                      show_emas=True,
                      show_bbands=False,
                      to_file=to_file)

    except Exception as e:
        log("[ERROR] Ploting data: " + str(e), 0, log_level)

    if not is_cached:
        cached[market] = {
            'interval': interval,
            'init_date': _date[0],
            'end_date': _date[1],
            'data': data,
            'last': 2
        }

    #if len(exit_points_x):
    #    log(market + ' > ' + str(total), log_level)

    log('[' + market + '][TOTAL]> ' + str(total) + '%.', 0, log_level)

    log(full_log, 1, log_level)

    if isnan(total):
        log("[ERROR] Total is isnan", 0, log_level)
        return 0

    return total
예제 #3
0
def tick_by_tick(
    market,
    entry_funcs,
    exit_funcs,
    interval=var.default_interval,
    smas=var.default_smas,
    emas=var.default_emas,
    refresh_interval=1,
    from_file=True,
    # plot=False
):
    """
    Simulates a working bot, in realtime or in faster speed,
     using pre own data from DB or file,
     to test an autonomous bot on a specific market.

    Args:
        market(string): list with markets to backtest or
            empty to run all available markets.
        entry_funcs(list): list of entry functions to test.
        exit_funcs(list): list of entry functions to test.
        interval(string): time between measures.
        smas(list): list of SMA values to use.
        emas(list): list of EMA values to use.
        refresh_interval(int): Refresh rate.
        from_file(bool): Select the origin of data.
        # plot(bool: plots data.
    """

    # plt.ion()

    signal.signal(signal.SIGINT, signal_handler)

    date = [0, 0]

    total = 0

    # market = check_market_name(market)

    entry_points_x = []
    entry_points_y = []

    exit_points_x = []
    exit_points_y = []

    if not isinstance(entry_funcs, list):
        entry_funcs = [entry_funcs]
    if not isinstance(exit_funcs, list):
        exit_funcs = [exit_funcs]

    log.info(f"[Market analysis]: {market}")

    if from_file:
        try:
            data = get_data_from_file(market, interval=interval)
        except Exception as e:
            log.error(f"Unable to get data from file: {e}")
            log.error(f"Unable to find {market} in files.")
            return 0

        data_init = data

        # if type(_date[0]) is str:
        #    date[0], date[1] = time_to_index(data, _date)

        # if date[1] == 0:
        #    data = data[date[0]:]

        # else:
        #    data = data[date[0]:date[1]]

    else:
        try:
            data = get_historical_data(market, interval=interval)
            date[0], date[1] = 0, len(data)
            data_init = data

        except Exception as e:
            log.error(f"Unable to get data from file: {e}")
            log.error(f"Unable to find {market} in DB.")
            return 0

    aux_buy = False
    buy_price = 0
    high_price = 0

    # plt.show()

    # Tests several functions.
    for i in range(len(data) - 110):
        start_time = time()
        # print(data_init.Last.iloc[i])
        if not aux_buy:
            if is_time_to_buy(data[i:i + 110], entry_funcs, smas, emas):

                buy_price = data_init.Ask.iloc[i + 109 + date[0]]
                high_price = buy_price

                entry_points_x.append(i + 109)
                entry_points_y.append(data_init.Ask.iloc[i + 109 + date[0]])

                if exit_funcs:
                    aux_buy = True

                log.info(f'''{data_init.time.iloc[i + 109 + date[0]]} \
                     [BUY] @ {data_init.Ask.iloc[i + 109 + date[0]]}''')

        else:
            # Used for trailing stop loss.
            if data_init.Last.iloc[i + 109 + date[0]] > high_price:
                high_price = data_init.Last.iloc[i + 109 + date[0]]

            if is_time_to_exit(data[i:i + 110],
                               exit_funcs,
                               smas,
                               emas,
                               stop=var.stop_type,
                               bought_at=buy_price,
                               max_price=high_price):

                exit_points_x.append(i + 109)
                exit_points_y.append(data_init.Bid.iloc[i + 109 + date[0]])

                aux_buy = False

                total += round(
                    ((data_init.Bid.iloc[i + 109 + date[0]] - buy_price) /
                     buy_price) * 100, 2)

                log.info(f'''{data_init.time.iloc[i + 109 + date[0]]} \
                     [SELL]@ {data_init.Bid.iloc[i + 109 + date[0]]}''')

                log.info(f'[P&L] > {total}%.')

        # plt.plot(data.Last.iloc[i:i+50])
        # plt.draw()
        # plt.clf()

        # In case of processing time is bigger than *refresh_interval* doesn't sleep.
        if refresh_interval - (time() - start_time) >= 0:
            sleep(refresh_interval - (time() - start_time))

    return total