How to get the data as array of the sma1 and sma2
-
HI BT community,
I need sma1 and sma2 and date and closing price of a stock. I tried all my best to extract this data from the code below but somehow could not get the final data in a dataframe. Can someone help with this please? All I need is a dataframe with columns: DateTime, Closing Price, SMA1(which is 10 SMA) and SMA2(which is 30SMA). Any help is much appreciated.import backtrader as bt class SmaCross(bt.SignalStrategy): def __init__(self): sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30) crossover = bt.ind.CrossOver(sma1, sma2) self.signal_add(bt.SIGNAL_LONG, crossover) cerebro = bt.Cerebro() cerebro.addstrategy(SmaCross) data0 = bt.feeds.YahooFinanceData(dataname='MSFT', fromdate=datetime(2011, 1, 1), todate=datetime(2012, 12, 31)) cerebro.adddata(data0) cerebro.run() cerebro.plot()
-
Below is the complete and correct code:
The code works I am looking to get a dataframe with data as below:
class SmaCross(bt.SignalStrategy): def __init__(self): sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30) crossover = bt.ind.CrossOver(sma1, sma2) self.signal_add(bt.SIGNAL_LONG, crossover) cerebro = bt.Cerebro() cerebro.addstrategy(SmaCross) store = alpaca_backtrader_api.AlpacaStore(key_id=ALPACA_API_KEY,secret_key=ALPACA_SECRET_KEY,paper=ALPACA_PAPER) DataFactory = store.getdata data0 = DataFactory( dataname=symbol_to_check, timeframe=bt.TimeFrame.TFrame("Minutes"), fromdate=pd.Timestamp('2019-11-15'),compression =1, # todate=pd.Timestamp('2018-11-17'), historical=True) cerebro.adddata(data0) cerebro.run() cerebro.plot()
-
Maybe try something list this.. Initialize empty list during init, and add to it during next(). Finally, during stop(), combine into a df and export/use for your own purposes.
@Ronan-Dunham said in How to get the data as array of the sma1 and sma2:
class SmaCross(bt.SignalStrategy): def __init__(self): sma1, sma2 = bt.ind.SMA(period=10), bt.ind.SMA(period=30) crossover = bt.ind.CrossOver(sma1, sma2) self.signal_add(bt.SIGNAL_LONG, crossover) self.ma1 = [] # Initialize empty lists to hold indicator values self.ma2 = [] # Initialize empty lists to hold indicator values def next(self): # Create data frame columns here by appending data to a list self.ma1.append(sma1) self.ma2.append(sma2) def stop(self): # Combine and export pandas DataFrame here cerebro = bt.Cerebro() cerebro.addstrategy(SmaCross) store = alpaca_backtrader_api.AlpacaStore(key_id=ALPACA_API_KEY,secret_key=ALPACA_SECRET_KEY,paper=ALPACA_PAPER) DataFactory = store.getdata data0 = DataFactory( dataname=symbol_to_check, timeframe=bt.TimeFrame.TFrame("Minutes"), fromdate=pd.Timestamp('2019-11-15'),compression =1, # todate=pd.Timestamp('2018-11-17'), historical=True) cerebro.adddata(data0) cerebro.run() cerebro.plot()
-
Hi @stochastick thank you so much for the reply. I am super new to object oriented programming. How do i combine in df after stop() and how to call this data in the main program outside the class? Also how about the stock closing price and date.
Sorry for the silly ask but as you can tell I am embarrassingly new to OOP. -
There is most certainly a more efficient way to accomplish what you seek, but nonetheless here is a working sample that accomplishes I believe what you are searching for. The data frame is simply saved to CSV here, but you could do whatever you want with it. Data is loaded from my own sources, but just substitute with yours.
import backtrader as bt import pandas as pd class SmaCross(bt.SignalStrategy): # Global Parameters globalParams = {'symbols': ['EUR_USD'], 'startDate': '01-01-2018', 'endDate': '01-05-2018'} def __init__(self): self.sma1 = bt.ind.SMA(period=10) self.sma2 = bt.ind.SMA(period=30) self.crossover = bt.ind.CrossOver(self.sma1, self.sma2) self.signal_add(bt.SIGNAL_LONG, self.crossover) # Initialize empty lists to hold values self.date_time = [] self.close_px = [] self.ma1 = [] self.ma2 = [] def log(self, txt, dt=None): """ Logging function """ dt = dt or self.datas[0].datetime.datetime() print('%s, %s' % (dt.isoformat(), txt)) def next(self): """Log data to console and save to lists""" self.log('%s ' '| O %.5f ' '| H %.5f ' '| L %.5f ' '| C %.5f ' '| SMA1 %.5f ' '| SMA2 %.5f ' % (self.datas[0]._name, self.datas[0].open[0], self.datas[0].high[0], self.datas[0].low[0], self.datas[0].close[0], self.sma1[0], self.sma2[0])) self.date_time.append(self.datas[0].datetime.datetime()) self.close_px.append(self.datas[0].close[0]) self.ma1.append(self.sma1[0]) self.ma2.append(self.sma2[0]) def stop(self): df = pd.DataFrame(index=self.date_time) df['Close'] = self.close_px df['SMA1'] = self.ma1 df['SMA2'] = self.ma2 df.to_csv('trade_history.csv', sep='\t') cerebro = bt.Cerebro() cerebro.addstrategy(SmaCross) symbols = SmaCross.globalParams['symbols'] for symbol in symbols: mktData = pd.read_json('../sample-data/FX/training_' + symbol + '.json') mktData['time'] = pd.to_datetime(mktData['time']) timeSlice = ((mktData['time'] > SmaCross.globalParams['startDate']) & (mktData['time'] < SmaCross.globalParams['endDate'])) mktData = mktData.loc[timeSlice] mktData = bt.feeds.PandasData(dataname=mktData, timeframe=bt.TimeFrame.Minutes, datetime='time', close='close') cerebro.resampledata(mktData, timeframe=bt.TimeFrame.Minutes, compression=5, name=symbol) cerebro.run()
This creates a CSV file formatted as such.
-
@stochastick Thank you so much. I got the data that I wanted:
```
Date Time Close SMA1 SMA2 0 2019-11-15 13:15:00 351.8501 351.34751 350.981837 1 2019-11-15 13:16:00 351.8500 351.44551 351.036837 2 2019-11-15 13:18:00 351.6800 351.51351 351.091170 3 2019-11-15 13:19:00 351.6000 351.57351 351.117837 4 2019-11-15 13:20:00 351.7000 351.62351 351.181170 ... ... ... ... ... 15809 2019-12-28 00:50:00 430.7600 430.72199 430.634997 15810 2019-12-28 00:53:00 430.5000 430.70199 430.634997 15811 2019-12-28 00:56:00 430.3300 430.65499 430.635663 15812 2019-12-28 00:57:00 430.8000 430.66499 430.648997 15813 2019-12-28 00:59:00 430.7500 430.66999 430.654663 15814 rows × 4 columns
Now all i need is this data without a text file. Just as a dataframe to use it in Jupyter cell. I donot need to make any strategy at all (again all i need is data from this specific source, other source like api.get_barset was missing a lot of data for me and this seem to work.)
Is there a way that is efficient to get this done without having to read from a csv file and directly use df in the cell?
Thanks a lot again.
-
Hi All,
Can you help me get the dataframe df from stop(self) to be used in a jupyter cell without having to write in a csv file? Any help is greatly appreciated.
-
Got it it works with SmaCross.df =df.
Thank you