For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

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: to_BT_forum.png

    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.

    6542e877-fce6-4584-9061-7b89fb665248-image.png



  • @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


Log in to reply
 

});