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!
-
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...?
-
@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.
-
@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) ...
-
@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.
-
@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!