AttributeError:“回测”对象没有属性“数据”,熊猫,SMA交叉

时间:2019-10-04 09:55:57

标签: python pandas moving-average algorithmic-trading

试图使此代码正常工作,但不确定我是否正确传递了父类,那么self.data的使用是否正确?可以使用更简洁的方式来编写此代码...

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import pandas_datareader.data as web
import os
import pandas_datareader as pdr

start = pd.to_datetime("Jan 1st 2013")
end = pd.to_datetime("Dec 31st 2018")

class StockData:
    ticker = []
    def stock(self,symbol):
        self.ticker.clear()
        self.ticker.append(symbol)
        self.data= web.DataReader(self.ticker,"yahoo", start, end)

class Backtest(StockData):
    def prepare_indicators(self):
        self.data['SMA1'] = self.data[self.symbol].rolling(self.SMA1).mean()
        self.data['SMA2'] = self.data[self.symbol].rolling(self.SMA2).mean()
        self.data['SMA_1'] = self.data[self.symbol].rolling(self.SMA1).mean().shift(1)
        self.data['SMA_2'] = self.data[self.symbol].rolling(self.SMA2).mean().shift(1)
    def backtest_strategy(self, SMA1, SMA2):
        self.SMA1 = SMA1
        self.SMA2 = SMA2
        self.prepare_indicators()
        print(self.data)
        self.data['Signal'] = np.where((self.data['SMA1'] > self.data['SMA2']) & (self.data['SMA_1'] < self.data['SMA_2']), 1, 0)
        self.data['Signal'] = np.where((self.data['SMA1'] < self.data['SMA2']) & (self.data['SMA_1'] > self.data['SMA_2']), 0, self.data['Signal'])
        self.data['Sell'] = self.data.apply(lambda x : x['Adj Close'] if x['SMA1'] > x['SMA2'] and x['SMA_1'] < x['SMA_2'] else 0, axis=1)
        self.data['Buy'] = self.data.apply(lambda y : y['Adj Close'] if y['SMA1'] < y['SMA2'] and y['SMA_1'] > y['SMA_2'] else 0, axis=1)
        self.data['TP'] = self.data['Buy'] + self.data['Sell']
        self.data['TP'] = self.data['TP'].replace(to_replace=0, method='ffill')
        self.data['Position'] = self.data['Signal'].replace(to_replace=0, method= 'ffill')
        self.data['Buy & Hold Returns'] = np.log(self.data['Adj Close'] / self.data['Adj Close'].shift(1))
        self.data['Strategy Returns'] = self.data['Buy & Hold Returns'] * Self.data['Position'].shift(1)
        self.data[['Buy & Hold Returns', 'Strategy Returns']].cumsum().plot(grid=True, figsize=(9,5))

  
    

sma = Backtest()

  

  
    

sma.backtest_strategy(50,200)

  

AttributeError:“回测”对象没有属性“数据”

1 个答案:

答案 0 :(得分:0)

如何在类中定义变量的模式如下:

class Xxxx:
    staticVar = ...

    def __init__(self):
        self.instanceVar = ...

因此,应该定义类中使用的每个变量:

  • 作为静态变量(不属于任何特定实例的“所有者”) 此类),在任何方法之外的此类中创建,
  • 或作为实例变量(由特定实例拥有),由 构造函数。

也可以在此类中的其他方法中定义类变量。

您的代码包含一个分配了 self.data 的位置, 在 StockData.stock 方法中,但从不调用此方法。

您引用 self.data 的其他地方的形式为:

 self.data[...] =  self.data[...]...

因此,此时,此变量必须更早创建。

一种可能的解决方案是添加一个构造函数(也许添加到 StockData ) 并将此变量设置为所需的任何值。

还是您应该在代码中的某个位置调用 stock

另一个概念是:

  • 将此函数转换为构造函数(保留 symbol 参数)
  • 在调用 sma = Backtest()时,请为此参数传递一些值。

但是可能您应该将 append 更改为 extend 。原因是 如果您将字符串作为 symbol 传递,则它实际上也是一个字符列表, 因此 ticker 将包含单个字符。 但是,如果更改为 extend ,则整个字符串将作为一个字符串添加 元素。