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 type(entry_funcs) is not list: entry_funcs = [entry_funcs]
    if type(exit_funcs) is not list: exit_funcs = [exit_funcs]

    print '[Market analysis]: ' + market + '\n'

    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 xrange(len(data) - 50):
        start_time = time()
        #print data_init.Last.iloc[i]
        if not aux_buy:
            if is_time_to_buy(data[i:i + 50], entry_funcs, smas, emas):

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

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

                if exit_funcs:
                    aux_buy = True

                print str(data_init.time.iloc[i + 49 + date[0]]) + \
                    ' [BUY] @ ' + str(data_init.Ask.iloc[i + 49 + date[0]]) + '\n'

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

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

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

                aux_buy = False

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

                print str(data_init.time.iloc[i + 49 + date[0]]) + \
                    ' [SELL]@ ' + str(data_init.Bid.iloc[i + 49 + date[0]]) + '\n'

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

        #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
def backtest_market(entry_funcs, exit_funcs, interval, _date, smas, emas,
                    from_file, to_file, plot, 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)

    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 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), 0, log_level)
            log('[ERROR] Can\'t find ' + market + ' in BD.', 0, log_level)
            return 0
            #continue

    aux_buy = False
    buy_price = 0
    high_price = 0

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

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

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

                if exit_funcs:
                    aux_buy = True

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

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

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

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

                aux_buy = False

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

                full_log += str(data_init.time.iloc[i + 49 + date[0]]) + \
                    ' [SELL]@ ' + str(data_init.Bid.iloc[i + 49 + 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=[],
                      entry_points=(entry_points_x, entry_points_y),
                      exit_points=(exit_points_x, exit_points_y),
                      show_smas=True,
                      show_emas=False,
                      show_bbands=True,
                      to_file=to_file)

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

    del data
    #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): return 0

    return total