Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    I cannot modify bt.feeds.PandasData!

    General Code/Help
    2
    5
    59
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      hyee last edited by

      I have checked that I can change the class name and parameter thanks to the help here. However, I fronted another obstacle...

      class Stock_Data(bt.feeds.PandasData):
          linesoveride=True
          lines=(
              ('datetime', None),
              ('open', -1),
              ('high', -1),
              ('low', -1),
              ('close',-1),
              ('volume',-1),
              ('adj_close',-1)
      )
          
      

      Then I get the below error.


      TypeError                                 Traceback (most recent call last)
      <ipython-input-35-4dab99469e78> in <module>
      ----> 1 class Stock_Data(bt.feeds.PandasData):
            2     linesoverrid=True
            3     lines=(
            4         ('datetime', None),
            5         ('open', -1),
      
      C:\anaconda\envs\backtest\lib\site-packages\backtrader\lineseries.py in __new__(meta, name, bases, dct)
          383             [x.plotlines for x in bases[1:] if hasattr(x, 'plotlines')]
          384         cls.plotlines = plotlines._derive(
      --> 385             'pl_' + name, newplotlines, morebasesplotlines, recurse=True)
          386 
          387         # create declared class aliases (a subclass with no modifications)
      
      C:\anaconda\envs\backtest\lib\site-packages\backtrader\metabase.py in _derive(cls, name, info, otherbases, recurse)
          143         for infoname, infoval in info2add.items():
          144             if recurse:
      --> 145                 recursecls = getattr(newcls, infoname, AutoInfoClass)
          146                 infoval = recursecls._derive(name + '_' + infoname,
          147                                              infoval,
      
      TypeError: getattr(): attribute name must be string
      

      As far as I know, the person who posted at "https://community.backtrader.com/topic/2728/pandas-data-feed-extension-issue" seems to succeed to use the class, but I can't.

      Could you explain me...?

      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @hyee last edited by

        @hyee Hard to figure out with this amount of information. Can you kindly include all of your code and a sample of the data you are using? Thanks.

        H 1 Reply Last reply Reply Quote 0
        • H
          hyee @run-out last edited by

          @run-out Yeap The below is my code.

          import backtrader as bt 
          import backtrader.feeds as feeds
          import pandas as pd
          import matplotlib
          import matplotlib.pyplot as plt
          import numpy as np
          import selenium
          
          from selenium import webdriver
          from pandas_datareader import data as pdr
          from pandas import DataFrame as DF
          from datetime import datetime as dt 
          from yahoofinance import IncomeStatement
          from bs4 import BeautifulSoup
          
          ### Global ###
          driver=webdriver.Chrome(executable_path=r'C:\chromedriver\chromedriver.exe')
          
          
          def stock_data(start, end, instrument):
              start_time = dt(*start) #* : 튜플 -> dt.datetime 형태로 만듬 
              end_time = dt(*end) 
          
              df = pdr.get_data_yahoo(instrument, start_time, end_time)
              df.columns=['high', 'low','open','close','volume','adj_close']
              
              return df
          
          
          
          def BS_data(symbol):
              headers=[]
              contents=[]
              temp=[]
              
              # ex: https://finance.yahoo.com/quote/NXPI/balance-sheet?p=NXPI
              url= 'https://finance.yahoo.com/quote/' + symbol + '/balance-sheet?p=' + symbol
              driver.get(url)
              
              table_html=driver.execute_script('return document.body.innerHTML;')
              soup=BeautifulSoup(table_html, 'lxml')
              table_list=soup.find_all('div', class_='D(tbr)') #all of the rows
               
              for num, row in enumerate(table_list):
                  if num==0:
                      for item in row.find_all('div', class_='D(ib)'):
                          headers.append(item.text)
                  
                  else:
                      x=row.find_all('div', class_='D(tbc)') # 숫자가 적힌 부분이 생소한 형태이긴 한데 tbc가 맞음 (주의사항)
                      for line in x:
                          temp.append(line.text)
                      contents.append(temp)
                      temp=[]
          #     print(headers)
          #     print(contents)
              
              df=pd.DataFrame(contents)
              df.columns=headers
              
              return df
          
          ....
          
          
          
          class Stock_Data(bt.feeds.PandasData):
              linesoveride=True
              lines=(
                  ('datetime', None),
                  ('open', -1),
                  ('high', -1),
                  ('low', -1),
                  ('close',-1),
                  ('volume',-1),
                  ('adj_close',-1)
              )
              
          class Financial_Data(bt.feeds.PandasData):
              linesoverride=True
              recent_year=int(dt.today().year-1)
              first="12/30/"+str(recent_year)
              second="12/30/"+str(recent_year-1)
              third="12/30/"+str(recent_year-2)
              
              lines=(
                  ('Breakdown', None),
                  (first, -1),
                  (second, -1),
                  (third, -1)
              )
          
          
          
          start = (2018, 1, 1)  # 2000-01-01 
          end = (2020, 12, 31) # 2020-12-31
          symbol='103140.KS'
          
          ST=stock_data(start, end, symbol)
          
          BS=BS_data(symbol)
          
          ...
          
          
          run-out 1 Reply Last reply Reply Quote 0
          • run-out
            run-out @hyee last edited by

            @hyee Still a bit hard to tell. It would be easier to help you if you include all of your code, in particular where you add in your feeds to cerebro, and a sample of each or your data files.

            H 1 Reply Last reply Reply Quote 1
            • H
              hyee @run-out last edited by

              @run-out Oh...Okay I got it!

              import backtrader as bt 
              import backtrader.feeds as feeds
              import pandas as pd
              import matplotlib
              import matplotlib.pyplot as plt
              import numpy as np
              import selenium
              
              from selenium import webdriver
              from pandas_datareader import data as pdr
              from pandas import DataFrame as DF
              from datetime import datetime as dt 
              from yahoofinance import IncomeStatement
              from bs4 import BeautifulSoup
              
              
              ### Global ###
              driver=webdriver.Chrome(executable_path=r'C:\chromedriver\chromedriver.exe')
              #path='C:\Users\USER\Desktop\Stock\Backtest\Data\'
              
              def stock_data(start, end, instrument):
                  start_time = dt(*start) #* : 튜플 -> dt.datetime 형태로 만듬 
                  end_time = dt(*end) 
              
                  df = pdr.get_data_yahoo(instrument, start_time, end_time)
                  df.columns=['high', 'low','open','close','volume','adj_close']
                  
                  return df
              
              def BS_data(symbol):
                  headers=[]
                  contents=[]
                  temp=[]
                  
                  # ex: https://finance.yahoo.com/quote/NXPI/balance-sheet?p=NXPI
                  url= 'https://finance.yahoo.com/quote/' + symbol + '/balance-sheet?p=' + symbol
                  driver.get(url)
                  
                  table_html=driver.execute_script('return document.body.innerHTML;')
                  soup=BeautifulSoup(table_html, 'lxml')
                  table_list=soup.find_all('div', class_='D(tbr)') #all of the rows
                   
                  for num, row in enumerate(table_list):
                      if num==0:
                          for item in row.find_all('div', class_='D(ib)'):
                              headers.append(item.text)
                      
                      else:
                          x=row.find_all('div', class_='D(tbc)') # 숫자가 적힌 부분이 생소한 형태이긴 한데 tbc가 맞음 (주의사항)
                          for line in x:
                              temp.append(line.text)
                          contents.append(temp)
                          temp=[]
              #     print(headers)
              #     print(contents)
                  
                  df=pd.DataFrame(contents)
                  df.columns=headers
                  
                  return df
              
              
              def IS_data(instrument):
                  headers=[]
                  temp=[]
                  contents=[]
                  
                  url="https://finance.yahoo.com/q/is?s="+instrument+"&annual" 
                  driver.get(url)
                  
                  table_html=driver.execute_script('return document.body.innerHTML;')
                  soup=BeautifulSoup(table_html, 'lxml')
                  row_list=soup.find_all('div', class_='D(tbr)')
                  
                  for num, row in enumerate(row_list):
                      if (num==0):
                          for item in row.find_all('div', class_='D(ib)'):
                              headers.append(item.text)
                      else:
                          for item in row.find_all('div', class_='D(tbc)'):
                              temp.append(item.text)
                          contents.append(temp)
                          temp=[]
              #     print(headers)
              #     print(contents)
                  
                  df=pd.DataFrame(contents)
                  df.columns=headers
                  
                  return df
              
              
              def CF_data(symbol):
                  url="https://finance.yahoo.com/quote/"+symbol+"/cash-flow?p="+symbol+"NXPI"
                  driver.get(url)
                  
                  table_html=driver.execute_script("return document.body.innerHTML;")
                  soup=BeautifulSoup(table_html, 'html.parser')
                  row_list=soup.find_all('div', class_='D(tbr)')
                  
                  headers=[]
                  temp=[]
                  contents=[]
                  
                  for num, row in enumerate(row_list):
                      if num==0:
                          for item in row.find_all('div', class_="D(ib)"):
                              headers.append(item.text)
                      else:
                          for item in row.find_all('div', class_='D(tbc)'):
                              temp.append(item.text)
                          contents.append(temp)
                          temp=[]
                  print(contents)
                  df=pd.DataFrame(contents)
                  df.columns=headers
                  
                  return df
                              
                  
              class Stock_Data(bt.feeds.PandasData):
                  linesoveride=True
                  lines=(
                      ('datetime', None),
                      ('open', -1),
                      ('high', -1),
                      ('low', -1),
                      ('close',-1),
                      ('volume',-1),
                      ('adj_close',-1)
                  )
                  
              class Financial_Data(bt.feeds.PandasData):
                  linesoverride=True
                  recent_year=int(dt.today().year-1)
                  first="12/30/"+str(recent_year)
                  second="12/30/"+str(recent_year-1)
                  third="12/30/"+str(recent_year-2)
                  
                  lines=(
                      ('Breakdown', None),
                      (first, -1),
                      (second, -1),
                      (third, -1)
                  )
              
              
              start = (2018, 1, 1)  # 2000-01-01 
              end = (2020, 12, 31) # 2020-12-31
              symbol='103140.KS'
              
              ST=stock_data(start, end, symbol)
              
              BS=BS_data(symbol)
              IS=IS_data(symbol)
              CF=CF_data(symbol)
              # BS_path=path+symbol+"_BS.csv" #C:\Users\USER\Desktop\Stock\Backtest\Data\숫자.KS_BS.csv
              # BS.to_csv(BS_path, mode="w")
              
              ST=bt.feeds.PandasData(dataname=ST, timeframe=1, openinterest=None)
              BS=bt.feeds.PandasData(dataname=BS)
              IS=bt.feeds.Financial_Data(dataname=IS)
              CF=bt.feeds.Financial_Data(dataname=CF)
              
              class (bt.Strategy):
                  params=dict(
                      short=20,
                      mid=60,
                      long=120
                  )
                  
                  def __init__(self):
                      """
                      self.datas : st, bs, is_data, cf
                      """
                      for num, data in enumerate(self.datas):
                          print('{}th data: {}'.format(num,data._name))
                          name=data._name
                          self.name=data
                          
                  def anal_cash(self):
                      #1. 대놓고 있는 현금 흐름
                      cf=self.cf
                      final_cf=cf.loc[['Free Cash Flow'],['TTM']]
                      
                      #2. 은밀한 현금 흐름
                      #아;;  이 전략 폐기. 생각해보니 크롤링으론 파일 다운이 안돼서 공시 자료 못 받음;;
                  
                  
                      
                  def next(self):
                      curr_stock_price=self.data.close[0]
                      
                      if not self.position: #not in market
                          self.cross0=curr_stock_price-self.sma_short
                          #print(self.cross0)
                          if ((self.cross0>0)and(self.cross1>0)):
                              size=int((self.broker.getcash())*0.1/self.data.close[0])#how many stocks?
                              self.buy(size=size) #살 때는 size가 있는 게 나음.
                              print("Buy")
                      
                      elif ((self.cross1<0)):#already in market
                          #size=int((self.broker.getcash())*0.1/self.data.close[0])#how many stocks?
                          self.sell() #팔 때는 사이즈 없는 게 수익률 나음. 
                          print("Sell")
              
              cerebro=bt.Cerebro()
              
              cerebro.adddata(ST, name=st)
              cerebro.adddata(BS, name=bs)
              cerebro.adddata(IS, name=is_data)
              cerebro.adddata(CF, name=cf)
              
              investment=1000000000
              cerebro.broker.setcash(investment) #10억으로 초기 자본 설정
              cerebro.broker.setcommission(commission=0.0025) #세금을 수수료로 간주, 0.25%
              cerebro.addstrategy(Array_analysis)
              cerebro.run()
              
              

              Here!

              1 Reply Last reply Reply Quote 0
              • 1 / 1
              • First post
                Last post
              Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
              $(document).ready(function () { app.coldLoad(); }); }