首页 > 解决方案 > AttributeError:“Lines_LineSeries_LineIterator_DataAccessor_Strateg”对象没有属性“日志”

问题描述

我试图复制其中一种策略只是为了练习目的。我收到上述关于我的交叉指标的消息。你能帮忙看看可能出了什么问题吗?非常感谢!

我想在 rsi 小于 30 时买入,在 rsi 高于 55 时卖出

哪一行“日志”是错误的,我该如何解决?

请看下面我的代码:

import FinanceDataReader as fdr
import backtrader as bt


# Create a Stratey
class TestStrategy(bt.Strategy):
    params = (
        ('maperiod', 200),
        ('rsi_period', 4),
        ('rsi_entry', 30),
        ('rsi_exit', 55),
    )

    def __init__(self):
        # Keep a reference to the "close" line in the data[0] dataseries
        self.dataclose = self.datas[0].close

        # To keep track of pending orders and buy price/commission
        self.order = None

        # Add a MovingAverageSimple indicator
        self.sma = bt.indicators.SimpleMovingAverage(self.datas[0], period=self.params.maperiod)
        self.rsi = bt.indicators.RSI_Safe(self.datas[0], period=self.params.rsi_period)

        self.n_wins = 0
        self.n_losses = 0
        self.profits = 0
        self.losses = 0

    def notify_trade(self, trade):
        if not trade.isclosed:
            return

        self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                 (trade.pnl, trade.pnlcomm))

        if trade.pnl > 0:
            self.n_wins += 1
            self.profits += trade.pnl
        else:
            self.n_losses += 1
            self.losses += trade.pnl

    def next(self):
        # Simply log the closing price of the series from the reference
        self.log('Close, %.2f' % self.dataclose[0])

        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return

        # Check if we are in the market
        if not self.position:

            # Not yet ... we MIGHT BUY if ...
            if self.dataclose[0] > self.sma[0] and self.rsi[0] <= self.p.rsi_entry:
                # 2003-05-19, BUY CREATE, 92.65
                # BUY, BUY, BUY!!! (with all possible default parameters)
                self.log('BUY CREATE, %.2f' % self.dataclose[0])

                # Keep track of the created order to avoid a 2nd order
                self.order = self.buy()

        else:
            if self.rsi[0] >= self.p.rsi_exit:
                # SELL, SELL, SELL!!! (with all possible default parameters)
                self.log('SELL CREATE, %.2f' % self.dataclose[0])

                # Keep track of the created order to avoid a 2nd order
                self.order = self.sell()

    def stop(self):
        win_ratio = self.n_wins / (self.n_wins + self.n_losses)
        avg_profit = self.profits / self.n_wins
        avg_loss = self.losses / self.n_losses
        profit_loss_ratio = avg_profit / avg_loss
        expected_profit_per_trade = win_ratio * avg_profit + (1-win_ratio) * avg_loss
        print(f"win_ratio: {win_ratio:.2f}, "
              f"profit_loss_ratio: {profit_loss_ratio:.2f}, "
              f"expected_profit_per_trade: {expected_profit_per_trade:.2f}")


if __name__ == '__main__':
    cerebro = bt.Cerebro()
    cerebro.addstrategy(TestStrategy)

    # spy = fdr.DataReader('SPY', '2000-01-01', '2005-05-30')
    spy = fdr.DataReader('SPY', '2000-01-01', '2010-12-31')
    # spy = fdr.DataReader('SPY', '1990-01-01', "1999-12-31")
    data = bt.feeds.PandasData(dataname=spy)
    cerebro.adddata(data)

    # Set our desired cash start
    cerebro.broker.setcash(10000.0)

    # Add a FixedSize sizer according to the stake
    cerebro.addsizer(bt.sizers.PercentSizer, percents=90)

    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())

    # Run over everything
    cerebro.run()

    # Print out the final result
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

    cerebro.plot(style='candlestick', barup="red", bardown="blue")

    # 1993-11-12 ~ 2021-07-30
    # win_ratio: 0.81, profit_loss_ratio: -0.71, expected_profit_per_trade: 166.32

    # 1993-11-12 ~ 1999-12-31
    # win_ratio: 0.84, profit_loss_ratio: -1.04, expected_profit_per_trade: 151.02

    # 2000-01-01 ~ 2010-12-31
    # win_ratio: 0.78, profit_loss_ratio: -0.91, expected_profit_per_trade: 69.30

    # 2011-01-01 ~ 2021-07-30
    # win_ratio: 0.79, profit_loss_ratio: -0.75, expected_profit_per_trade: 75.95

标签: pythonfinancetradingbacktrader

解决方案


推荐阅读