AttributeError: у объекта 'Backtest' нет атрибута 'data', Pandas, пересечение SMA - PullRequest
0 голосов
/ 04 октября 2019

Попытка заставить этот код работать, но я не уверен, правильно ли я передаю родительский класс, также правильно ли использовать 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: у объекта 'Backtest' нет атрибута 'data'

1 Ответ

0 голосов
/ 04 октября 2019

Шаблон для определения переменных в классах выглядит следующим образом:

class Xxxx:
    staticVar = ...

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

Таким образом, каждая переменная, используемая в классе, должна быть определена:

  • либо как статическая переменная (не "принадлежащая" какому-либо конкретному экземпляру этого класса), созданная в этом классе вне какого-либо метода,
  • или как экземпляр переменная (принадлежит конкретномуinstance), созданный конструктором.

Переменная класса также может быть определена в другом методе этого класса.

Ваш код содержит единственное место, где self. данные назначаются в StockData.stock методе, но этот метод вызывается никогда .

Другие места, где вы ссылаетесь на self.data имеют вид:

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

, поэтому на данный момент эта переменная должна быть создана раньше.

Одним из возможных решений является добавление конструктора (возможно, к StockData ) и установите эту переменную в любое значение по вашему желанию.

Или, может быть, выдолжен вызывать stock где-нибудь в вашем коде?

Другая концепция заключается в следующем:

  • превратить эту функцию в конструктор (оставив параметр symbol ),
  • когда вы вызываете sma = Backtest () , передайте некоторое значение для этого параметра.

Но, вероятно, вам следует изменить append до расширить . Причина в том, что если вы передадите строку как символ , на самом деле это также список символов, поэтому тикер будет содержать отдельные символы . Но если вы измените на extension , вся строка будет добавлена ​​как один элемент.

...