简体   繁体   中英

TypeError: 'numpy.ndarray' object is not callable. Strange error

full code is here: https://colab.research.google.com/drive/1OrtnNwAb9e1-F5f9fqI1x11fiws-GD3y?usp=sharing more details can be seen there.

edited version: https://colab.research.google.com/drive/1CHrtsOlTPsWNrva7bKtS6iIoMZPzymSl?usp=sharing

code of the main class: (this is a stripped down version)


class Strategies(object):
    """
    basic class for PatternFinder.

    """

    def __init__(self,
                 ticker='AAPL',
                 days_undo=100,
                 df=np.nan,
                 interval='1m',
                 *args,
                 **kwargs):
        self.ticker = ticker
        self.days_undo = days_undo
        self.drop = 0
        self.interval = interval
        if df is np.nan:
            data = get_data(ticker, days_undo)
            self.df = data.reset_index()
        else:
            self.df = df.reset_index()
        self.df = self.df[self.drop:].reset_index()
        if interval == '1m':
            self.profit_calculate_coef = 1 / 60 / 24 / 365
        elif interval == '1d':
            self.profit_calculate_coef = 1 / 365
        else:
            raise ValueError('I N C O R R E C T   I N T E R V A L')

    def __repr__(self):
        return 'trader'

    def __iter__(self):
        try:
            return iter(list(self.backtest_out.values))
        except AttributeError:
            raise ValueError('D O   B A C K T E S T')

    def kalman_filter(self, iters=40, plot=True, *args, **kwargs):
        k_filter = KalmanFilter()
        filtered = k_filter.filter(np.array(self.df['Close']))[0]
        for i in range(iters):
            filtered = k_filter.smooth(filtered)[0]
        if plot:
            self.fig.add_trace(
                go.Line(
                    name='kalman filter',
                    y=filtered,
                    line=dict(width=SUB_LINES_WIDTH)), 1, 1)
        return pd.DataFrame(filtered)

    

    def linear_(self, dataset):
        """
        linear data. mean + (mean diff * n)

        """
        data = pd.DataFrame(dataset)

        mean = float(data.mean())
        mean_diff = float(data.diff().mean())
        start = mean - (mean_diff * (len(data) / 2))
        end = start + (mean - start) * 2

        length = len(data)
        ret = []
        mean_diff = (end - start) / length
        for i in range(length):
            ret.append(start + mean_diff * i)
        return np.array(ret)

    def get_stop_take(self, sig):
        """
        calculating stop loss and take profit.


        sig:        |     int     |  signsl to sell/buy/exit:
            2 -- exit.
            1 -- buy.
            0 -- sell.

        """

        if self.stop_loss is not np.inf:
            _stop_loss = self.stop_loss / 10_000 * self.open_price
        else:
            _stop_loss = np.inf
        if self.take_profit is not np.inf:
            take = self.take_profit / 10_000 * self.open_price
        else:
            take = np.inf

        if sig == 1:
            _stop_loss = self.open_price - _stop_loss
            take = self.open_price + take
        elif sig == 0:
            take = self.open_price - take
            _stop_loss = self.open_price + _stop_loss
        else:
            if self.take_profit is not np.inf:
                take = self.open_price
            if self.stop_loss is not np.inf:
                _stop_loss = self.open_price

        return {'stop': _stop_loss, 'take': take}

    def strategy_parabolic_SAR(self, plot=True, *args, **kwargs):
        ret = []
        sar = ta.trend.PSARIndicator(self.df['High'], self.df['Low'],
                                     self.df['Close'])
        sardown = sar.psar_down()[self.drop:].values
        sarup = sar.psar_up()[self.drop:].values

        if plot:
            for SAR_ in (sarup, sardown):
                self.fig.add_trace(
                    go.Line(
                        name='SAR', y=SAR_, line=dict(width=SUB_LINES_WIDTH)),
                    1, 1)
        for price, up, down in zip(
                list(self.df['Close'].values), list(sarup), list(sardown)):
            numup = np.nan_to_num(up, nan=-9999)
            numdown = np.nan_to_num(down, nan=-9999)
            if numup != -9999:
                ret.append(1)
            elif numdown != -9999:
                ret.append(0)
            else:
                ret.append(2)
        self.returns = ret
        return ret

    

    def basic_backtest(self,
                       deposit=10_000,
                       credit_leverage=1,
                       bet=None,
                       commission=0,
                       stop_loss=None,
                       take_profit=None,
                       plot=True,
                       print_out=True,
                       column='Close',
                       *args,
                       **kwargs):
        """
        testing the strategy.


        deposit:         | int, float. | start deposit.
        -----------------+-------------+--------------------------------------
        credit_leverage: | int, float. | tradeing leverage. 1 = none
        -----------------+-------------+--------------------------------------
        bet:             | int, float, | fixed bet to trade. None = all moneys
        -----------------+-------------+--------------------------------------
        commission:      | int, float. | percentage commission (0 -- 100)
        -----------------+-------------+--------------------------------------
        stop_loss:       | int, float. | stop loss in points
        -----------------+-------------+--------------------------------------
        take_profit:     | int, float. | take profit in points
        -----------------+-------------+--------------------------------------
        plot:            |    bool.    | plotting
        -----------------+-------------+--------------------------------------
        print_out:       |    bool.    | printing
        -----------------+-------------+--------------------------------------
        column:          |     str     | column of dataframe to becktest



        returns: pd.DataFrame with data of:
            signals,
            deposit'
            stop loss,
            take profit,
            linear deposit,
            <<column>> price,
            open bet\lot\deal price.


        """

        if stop_loss is None:
            self.stop_loss = np.inf
        else:
            self.stop_loss = stop_loss
        if take_profit is None:
            self.take_profit = np.inf
        else:
            self.take_profit = take_profit

        saved_del = self.returns[len(self.returns) - 1]

        if set_(self.returns)[len(self.returns) - 1] is np.nan:
            self.returns[len(self.returns) - 1] = 'r'

        loc = list(self.df[column][self.drop:].values)

        if plot:
            self.fig.add_candlestick(
                close=self.df['Close'],
                high=self.df['High'],
                low=self.df['Low'],
                open=self.df['Open'],
                row=1,
                col=1,
                name=self.ticker)

        __predictions = {}
        for e, i in enumerate(set_(self.returns)):
            if i is not np.nan:
                __predictions[e] = i
            # marker's 'y' cordinate on real price of stock/forex
            if plot:
                if i == 0:
                    self.fig.add_scatter(
                        name='Sell',
                        y=[loc[e]],
                        x=[e],
                        row=1,
                        col=1,
                        line=dict(color='#FF0000'),
                        marker=dict(
                            symbol='triangle-down',
                            size=SCATTER_SIZE,
                            opacity=SCATTER_ALPHA))
                elif i == 1:
                    self.fig.add_scatter(
                        name='Buy',
                        y=[loc[e]],
                        x=[e],
                        row=1,
                        col=1,
                        line=dict(color='#00FF00'),
                        marker=dict(
                            symbol='triangle-up',
                            size=SCATTER_SIZE,
                            opacity=SCATTER_ALPHA))
                elif i == 2:
                    self.fig.add_scatter(
                        name='Exit',
                        y=[loc[e]],
                        x=[e],
                        row=1,
                        col=1,
                        line=dict(color='#2a00ff'),
                        marker=dict(
                            symbol='triangle-left',
                            size=SCATTER_SIZE,
                            opacity=SCATTER_ALPHA))

        sigs = list(__predictions.values())
        vals = list(__predictions.keys())

        self.moneys = deposit
        leverage = credit_leverage
        rate = bet
        commission = commission

        money_start = self.moneys
        resur = [self.moneys]
        self.losses = 0
        self.trades = 0
        self.open_lot_prices = []
        stop_losses = []
        take_profits = []
        exit = False

        e = 0
        for enum, (val, val2, sig) in enumerate(
                zip(vals[:len(vals) - 1], vals[1:], sigs[:len(sigs) - 1])):
            mons = self.moneys
            coef = self.moneys / loc[val]
            self.open_price = loc[val]

            _rate = self.moneys if rate is None else rate
            if rate is not None:
                if _rate >= rate:
                    _rate = self.moneys
            _rate -= _rate * (commission / 100)

            for i in (
                    pd.DataFrame(loc).diff().values * coef)[val + 1:val2 + 1]:

                min_price = self.df['Low'][self.drop:][e]
                max_price = self.df['High'][self.drop:][e]
                self.open_lot_prices.append(self.open_price)

                take_stop = self.get_stop_take(sig)
                _stop_loss = take_stop['stop']
                take = take_stop['take']

                stop_losses.append(_stop_loss)
                take_profits.append(take)

                cond = min(_stop_loss, take) < loc[e] < max(_stop_loss, take)

                if cond and not exit:

                    if sig == 0:
                        self.moneys -= i[0] * leverage * (_rate / mons)
                        resur.append(self.moneys)
                    elif sig == 1:
                        self.moneys += i[0] * leverage * (_rate / mons)
                        resur.append(self.moneys)
                    elif sig == 2:
                        resur.append(self.moneys)
                else:
                    exit = True
                    resur.append(self.moneys)

                e += 1

            self.trades += 1
            if self.moneys < mons:
                self.losses += 1
            exit = False

        if plot:
            if self.take_profit != np.inf:
                self.fig.add_trace(
                    go.Line(
                        y=take_profits,
                        line=dict(width=TAKE_STOP_OPN_WIDTH, color=G),
                        opacity=STOP_TAKE_OPN_ALPHA,
                        name='take profit'), 1, 1)
            if self.stop_loss != np.inf:
                self.fig.add_trace(
                    go.Line(
                        y=stop_losses,
                        line=dict(width=TAKE_STOP_OPN_WIDTH, color=R),
                        opacity=STOP_TAKE_OPN_ALPHA,
                        name='stop loss'), 1, 1)

            self.fig.add_trace(
                go.Line(
                    y=self.open_lot_prices,
                    line=dict(width=TAKE_STOP_OPN_WIDTH, color=B),
                    opacity=STOP_TAKE_OPN_ALPHA,
                    name='open lot'), 1, 1)

        self.returns[len(self.returns) - 1] = saved_del
        if set_(self.returns)[len(self.returns) - 1] is np.nan:
            stop_losses.append(_stop_loss)
            take_profits.append(take)
            self.open_lot_prices.append(self.open_price)
        else:
            sig = sigs[len(sigs) - 1]
            take_stop = self.get_stop_take(sig)
            _stop_loss = take_stop['stop']
            take = take_stop['take']
            stop_losses.append(_stop_loss)
            take_profits.append(take)
            self.open_lot_prices.append(loc[len(loc) - 1])

        linear_dat = self.linear_(resur)
        if plot:
            self.fig.add_trace(
                go.Line(
                    y=resur,
                    line=dict(color=COLOR_DEPOSIT),
                    name=f'D E P O S I T  (S T A R T: ${money_start})'), 2, 1)
            self.fig.add_trace(go.Line(y=linear_dat, name='L I N E A R'), 2, 1)
            for e, i in enumerate(resur):
                if i < 0:
                    self.fig.add_scatter(
                        y=[i],
                        x=[e],
                        row=2,
                        col=1,
                        line=dict(color=R),
                        marker=dict(
                            symbol='triangle-down',
                            size=SCATTER_SIZE,
                            opacity=SCATTER_DEPO_ALPHA))

        start = linear_dat[0]
        end = linear_dat[len(linear_dat) - 1]
        self.year_profit = (end - start) / start * 100
        self.year_profit /= len(resur) * self.profit_calculate_coef
        if start < 0 < end:
            self.year_profit = -self.year_profit
        elif start > end and self.year_profit > 0:
            self.year_profit = -self.year_profit
        elif start < end and self.year_profit < 0:
            self.year_profit = -self.year_profit
        self.linear = linear_dat
        self.profits = self.trades - self.losses
        if print_out:
            print(f'L O S S E S: {self.losses}')
            print(f'T R A D E S: {self.trades}')
            print(f'P R O F I T S: {self.profits}')
            print(
                'M E A N   P E R C E N T A G E   Y E A R   P R O F I T: ',
                self.year_profit,
                '%',
                sep='')
        if plot:
            self.fig.show()
        self.stop_losses = stop_losses
        self.take_profits = take_profits
        self.backtest_out = pd.DataFrame(
            (resur, stop_losses, take_profits, self.returns,
             self.open_lot_prices, loc, self.linear),
            index=[
                f'deposit ({column})', 'stop loss', 'take profit',
                'predictions', 'open deal/lot', column,
                f"linear deposit data ({column})"
            ]).T.dropna()
        return self.backtest_out

The error occurs while using basic_backtest a second time. I tried using this:

rets = self.returns
fig = self.fig
self = PatternFinder(self.ticker,
                     self.days_undo,
                     self.df,
                     self.interval,
                     self.rounding)
self.returns = rets
self.fig = fig
self = copy.deepcopy(self)

But it doesn't work if used as a function. And it raises this exception all the time.

<ipython-input-40-e9c111bf303a> in <module>
   1287     #trader.inverse_strategy()
   1288     trader.log_data()
-> 1289     resur1 = trader.backtest()

1 frames
<ipython-input-40-e9c111bf303a> in backtest(self, deposit, credit_leverage, bet, commission, stop_loss, take_profit, plot, print_out, *args, **kwargs)
   1106                                           plot=False,
   1107                                           print_out=False,
-> 1108                                           column=column)
   1109             ret_frame[f'deposit ({column})'] = returns[f'deposit ({column})']
   1110             ret_frame[column] = returns[column]

<ipython-input-40-e9c111bf303a> in basic_backtest(self, deposit, credit_leverage, bet, commission, stop_loss, take_profit, plot, print_out, column, *args, **kwargs)
    774 
    775 
--> 776         linear_dat = self.linear(resur)
    777         if plot:
    778             self.fig.add_trace(

TypeError: 'numpy.ndarray' object is not callable

Looks like you replaced the function in the self scope by a numpy array. Doing a quick analysis of the occurrences of self.linear I would guess that the following line is the one causing this problem:

self.linear = linear_dat

It's located in the definition of the basic_backtest function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM