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/

    OLS_Slope_InterceptN

    General Discussion
    3
    12
    3524
    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.
    • J
      jirathh last edited by

      Could you please give an example on how to use 'OLS_Slope_InterceptN' class?

      Thank you.

      1 Reply Last reply Reply Quote 0
      • J
        jirathh last edited by

        from datetime import datetime
        import backtrader as bt

        class TestStrategy(bt.Strategy):
        params = (
        ('period', 14),
        ('sma_atr', 5),
        ('ols_length',15),
        ('macd1', 12),
        ('macd2', 26),
        ('macdsig', 9),
        )

        def log(self, txt, dt=None):
            ''' Logging function fot this strategy'''
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
        
        def __init__(self):
            # Keep a reference to the "close" line in the data[0] dataseries
            self.dataclose = self.datas[0].close
        
            # To keep track of pending orders and buy price/commission
            self.order = None
            self.buyprice = None
            self.buycomm = None
        
            # Add ATR Indicator
            self.atr = bt.indicators.ATR(
                self.datas[0], period=self.params.period)
            self.sma_atr = bt.indicators.SMA(
                self.atr, period=self.params.sma_atr)
            self.my_macd = bt.indicators.MACD(
                self.datas[0], period_me1=self.p.macd1, period_me2=self.p.macd2, period_signal=self.p.macdsig)
        
            self.my_ols1, self.my_ols2 = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close)
        
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                return
        
            # Check if an order has been completed
            # Attention: broker could reject order if not enougth cash
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log(
                        'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                        (order.executed.price,
                         order.executed.value,
                         order.executed.comm))
        
                    self.buyprice = order.executed.price
                    self.buycomm = order.executed.comm
                else:  # Sell
                    self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                             (order.executed.price,
                              order.executed.value,
                              order.executed.comm))
        
                self.bar_executed = len(self)
        
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Canceled/Margin/Rejected')
        
            self.order = None
        
        def notify_trade(self, trade):
            if not trade.isclosed:
                return
        
            self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                     (trade.pnl, trade.pnlcomm))
        
        def next(self):
        
            # Simply log the closing price of the series from the reference
            self.log('Close, %.2f' % self.dataclose[0])
            self.log('ATR, %.2f' % self.atr[0])
            self.log('SMA_ATR, %.2f' % self.sma_atr[0])
            self.log('MACD, %.2f' % self.my_macd.macd[0])
            self.log('SIGNAL, %.2f' % self.my_macd.signal[0])
        
        
            # Check if an order is pending ... if yes, we cannot send a 2nd one
            if self.order:
                return
        
            # Check if we are in the market
            if not self.position:
        
                # Not yet ... we MIGHT BUY if ...
                if (self.atr[0] > self.sma_atr[0]) and (self.my_macd.macd[0] > 0) and ((self.my_macd.signal[0] > 0) and (self.my_macd.macd[0] > self.my_macd.signal[0])):
        
                    # BUY, BUY, BUY!!! (with all possible default parameters)
                    self.log('BUY CREATE, %.2f' % self.dataclose[0])
        
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.order_target_percent(target=0.9)
        
            else:
        
                if self.atr[0] < self.sma_atr[0]:
                    # SELL, SELL, SELL!!! (with all possible default parameters)
                    self.log('SELL CREATE, %.2f' % self.dataclose[0])
        
                    # Keep track of the created order to avoid a 2nd order
                    self.order = self.order_target_percent(target=0)
        

        if name == 'main':
        cerebro = bt.Cerebro()
        # Add a strategy
        cerebro.addstrategy(TestStrategy, period=14, sma_atr=3, ols_length=15)

        # Basic Setup of the trade
        cerebro.broker.setcash(1000000.0)
        # Set the commission - 0.1% ... divide by 100 to remove the %
        cerebro.broker.setcommission(commission=0.001)
        # Add a FixedSize sizer according to the stake
        cerebro.addsizer(bt.sizers.FixedSize, stake=100)
        
        #https://community.backtrader.com/topic/279/don-t-understand-buy-amount/6
        cerebro.broker.set_coc(True)
        
        data = bt.feeds.YahooFinanceData(dataname='IBM', fromdate=datetime(2017, 1, 1),
                                         todate=datetime(2017, 11, 27))
        cerebro.adddata(data)
        
        # Print out the starting conditions
        print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.run()
        # Print out the final result
        print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
        cerebro.plot()
        1 Reply Last reply Reply Quote 0
        • J
          jirathh last edited by jirathh

          C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
          Starting Portfolio Value: 1000000.00
          C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
          from pandas.core import datetools
          Traceback (most recent call last):
          File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 133, in <module>
          cerebro.run()
          File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
          runstrat = self.runstrategies(iterstrat)
          File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1229, in runstrategies
          strat = stratcls(*sargs, **skwargs)
          File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\metabase.py", line 88, in call
          _obj, args, kwargs = cls.doinit(_obj, *args, **kwargs)
          File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\metabase.py", line 78, in doinit
          _obj.init(*args, **kwargs)
          File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 36, in init
          self.my_ols1, self.my_ols2, self.ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close)
          ValueError: need more than 0 values to unpack

          Process finished with exit code 1

          Please any one suggest above error.

          P 1 Reply Last reply Reply Quote 0
          • P
            Paska Houso @jirathh last edited by

            @jirathh said in OLS_Slope_InterceptN:

            self.my_ols1, self.my_ols2, self.ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0].close, self.datas[0].close)
            ValueError: need more than 0 values to unpack

            Obviously there is only 1 return value there.

            1 Reply Last reply Reply Quote 0
            • J
              jirathh last edited by

              I used this one:

              self.my_ols = bt.indicators.OLS_Slope_InterceptN(self.datas[0], self.datas[0], period=30)

              but still got this error

              C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
              Starting Portfolio Value: 1000000.00
              C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
              from pandas.core import datetools
              Traceback (most recent call last):
              File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 133, in <module>
              cerebro.run()
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
              runstrat = self.runstrategies(iterstrat)
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1305, in runstrategies
              self._runonce(runstrats)
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1663, in _runonce
              strat._once()
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 292, in _once
              indicator._once()
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 313, in _once
              self.once(self._minperiod, self.buflen())
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicator.py", line 136, in once_via_next
              self.next()
              File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicators\ols.py", line 52, in next
              slope, intercept = sm.OLS(p0, p1).fit().params
              ValueError: need more than 1 value to unpack

              Process finished with exit code 1

              P 1 Reply Last reply Reply Quote 0
              • A
                ab_trader last edited by

                I didn't dig deeply, but looks like by default bt script requires 2 data feeds for this indicator. Maybe this is a problem. I would add 2nd data feed and call indicator as follows:

                self.my_ols = bt.indicators.OLS_Slope_InterceptN(period=whatever_period_you_want)
                

                Default period is 10.
                Otherwise you can write your own implementation.

                1 Reply Last reply Reply Quote 0
                • J
                  jirathh last edited by

                  thank you @ab_trader . I tried but still got this error.

                  self.my_ols = bt.indicators.OLS_Slope_InterceptN(period=30)


                  C:\Users\jirath\Anaconda2\python.exe C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py
                  Starting Portfolio Value: 1000000.00
                  C:\Users\jirath\Anaconda2\lib\site-packages\statsmodels\compat\pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead.
                  from pandas.core import datetools
                  Traceback (most recent call last):
                  File "C:/Users/jirath/PycharmProjects/BackTrader.com/atr_trade.py", line 151, in <module>
                  cerebro.run()
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1142, in run
                  runstrat = self.runstrategies(iterstrat)
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1305, in runstrategies
                  self._runonce(runstrats)
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\cerebro.py", line 1663, in _runonce
                  strat._once()
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 292, in _once
                  indicator._once()
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 312, in _once
                  self.oncestart(self._minperiod - 1, self._minperiod)
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicator.py", line 124, in oncestart_via_nextstart
                  self.nextstart()
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineiterator.py", line 342, in nextstart
                  self.next()
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\indicators\ols.py", line 50, in next
                  p1 = pd.Series(self.data1.get(size=self.p.period))
                  File "C:\Users\jirath\Anaconda2\lib\site-packages\backtrader\lineseries.py", line 461, in getattr
                  return getattr(self.lines, name)
                  AttributeError: 'Lines_LineSeries_LineIterator_DataAccessor_Indicat' object has no attribute 'data1'

                  Process finished with exit code 1

                  1 Reply Last reply Reply Quote 0
                  • A
                    ab_trader last edited by

                    Did you add second data feed in cerebro?

                    1 Reply Last reply Reply Quote 0
                    • P
                      Paska Houso @jirathh last edited by Paska Houso

                      @jirathh said in OLS_Slope_InterceptN:

                      slope, intercept = sm.OLS(p0, p1).fit().params
                      ValueError: need more than 1 value to unpack
                      

                      This is a clear indication that the version of sm.OLS you are using is not compatible with the code in that indicator. The statsmodels API changes overtime. See this:

                      • https://stackoverflow.com/questions/20701484/why-do-i-get-only-one-parameter-from-a-statsmodels-ols-fit
                      1 Reply Last reply Reply Quote 0
                      • J
                        jirathh last edited by

                        @Paska-Houso , thank you so much for your information.

                        In this case, I need to modify and run ols algorithm locally.

                        Could you please suggest how can I run backtrader locally?

                        I think we need to set something like interpreter or structure the project correctly. I use PyCharm on Windows. Please make suggestions. Thank you.

                        P 1 Reply Last reply Reply Quote 0
                        • P
                          Paska Houso @jirathh last edited by

                          I suggest you look at the many samples ... the blog is full of them. For example:

                          • https://www.backtrader.com/blog/posts/2015-07-18-developing-an-indicator/developing-an-indicator.html
                          1 Reply Last reply Reply Quote 0
                          • J
                            jirathh last edited by

                            Thank you so much, @Paska-Houso .
                            I managed to create a new indicator of OLS to be used in my strategy! :)

                            Here is the code:

                            class TORO_OLS_Slope_InterceptN(bt.Indicator):
                            packages = (
                            ('pandas', 'pd'),
                            ('sklearn.linear_model', 'lm'),
                            )
                            lines = ('slope', 'intercept',)
                            params = (
                            ('period', 10),
                            )
                            def init(self):
                            self.addminperiod(self.params.period)

                            def next(self):
                                p0 = pd.Series(self.data.close.get(size=self.p.period))
                                p1 = np.arange(self.p.period).reshape(-1, 1)
                                p1 = sm.add_constant(p1, prepend=True)
                                slope, intercept = sm.OLS(p0, p1).fit().params
                                self.lines.slope[0] = slope
                                self.lines.intercept[0] = intercept
                            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(); }); }