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/

    simple momentum strategy

    General Code/Help
    3
    6
    1896
    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.
    • F
      feiz last edited by feiz

      hey everyone
      i have problem with the code i have written for a simple momentum strategy. i would be thankful if someone helps.
      i have fed cerebro with 4 data feeds and re sampled them to monthly. the code is supposed to calculate monthly returns and buy the stock with largest return and sell the one with the least return and keep this position till next month. heres the code:

                       from __future__ import (absolute_import, division, print_function,
                          unicode_literals)
                             import datetime  # For datetime objects
                            import os.path  # To manage paths
         import sys  # To find out the script name (in argv[0])
         # Import the backtrader platform
         import backtrader as bt
         # Create a Stratey
                class TestStrategy(bt.Strategy):
                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.dataone=self.datas[0]
          self.datatwo=self.datas[1] 
          self.datathree=self.datas[2]  
          self.datafour=self.datas[3]
      
          # To keep track of pending orders and buy price/commission
          self.order = None
          self.buyprice = None
          self.buycomm = None
                  
      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 enough 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')
      
          # Write down: no pending order
          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):
          
          def maxchoice(datas, i):
              for i in self.datas[i]:
                  self.rtrn[i]=bt.indicators.PercentChange(self.datas[i])
                  return self.bt.indicators.Highest(self.rtrn[i])  
                           
                  
          def minchoice(datas, i):
              for i in self.datas[i]:
                  self.rtrn[i]=bt.indicators.PercentChange(self.datas[i])
                  return self.bt.indicators.Lowest(self.rtrn[i]) 
          # Simply log the closing price of the series from the reference
          self.log('Close, %.2f' % self.data[i])
      
          # 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:
              for i in self.datas[i]:
                  if maxchoice(datas, i) != 0:
      
                              # BUY, BUY, BUY!!! (with all possible default parameters)
                      self.log('BUY CREATE, %.2f' % self.datas[i])
      
                              # Keep track of the created order to avoid a 2nd order
                      self.order = self.buy()
      
          else:
              for i in self.datas[i]:
                  if minchoice(datas, i) != 0:
                          
                              # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % self.datas[i])
      
                              # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell()
      
      
        if __name__ == '__main__':
        # Create a cerebro entity
         cerebro = bt.Cerebro()
      
      # Add a strategy
      cerebro.addstrategy(TestStrategy)
      
      # Datas are in a subfolder of the samples. Need to find where the script is
      # because it could have been called from anywhere
      modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
      datapathone = os.path.join(modpath, 'C:\\Users\\Queen\\gc1.csv')
      datapathtwo = os.path.join(modpath, 'C:\\Users\\Queen\\gc2.csv')
      datapaththree = os.path.join(modpath, 'C:\\Users\\Queen\\gc3.csv')
      datapathfour = os.path.join(modpath, 'C:\\Users\\Queen\\gc4.csv')
      
      
      # Create a Data Feed
      dataone = bt.feeds.YahooFinanceCSVData(
          dataname=datapathone,
          # Do not pass values before this date
          fromdate=datetime.datetime(2014, 2, 9),
          # Do not pass values before this date
          todate=datetime.datetime(2018, 2, 15),
          # Do not pass values after this date
          reverse=False)
      datatwo = bt.feeds.YahooFinanceCSVData(
          dataname=datapathtwo,
          # Do not pass values before this date
          fromdate=datetime.datetime(2014, 2, 9),
          # Do not pass values before this date
          todate=datetime.datetime(2018, 2, 15),
          # Do not pass values after this date
          reverse=False)
      datathree = bt.feeds.YahooFinanceCSVData(
          dataname=datapaththree,
          # Do not pass values before this date
          fromdate=datetime.datetime(2014, 2, 9),
          # Do not pass values before this date
          todate=datetime.datetime(2018, 2, 15),
          # Do not pass values after this date
          reverse=False)
      datafour = bt.feeds.YahooFinanceCSVData(
          dataname=datapathfour,
          # Do not pass values before this date
          fromdate=datetime.datetime(2014, 2, 9),
          # Do not pass values before this date
          todate=datetime.datetime(2018, 2, 15),
          # Do not pass values after this date
          reverse=False)
      
      # Add the Data Feed to Cerebro
      cerebro.resampledata(dataone, timeframe = bt.TimeFrame.Months)
      cerebro.resampledata(datatwo, timeframe = bt.TimeFrame.Months)
      cerebro.resampledata(datathree, timeframe = bt.TimeFrame.Months)
      cerebro.resampledata(datafour, timeframe = bt.TimeFrame.Months)
      
      # Set our desired cash start
      cerebro.broker.setcash(100000000.0)
      
      # Add a FixedSize sizer according to the stake
      cerebro.addsizer(bt.sizers.FixedSize, stake=100)
      
      # Set the commission
      cerebro.broker.setcommission(commission=0.007575)
      
      # Print out the starting conditions
      print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      # Run over everything
      cerebro.run()
      
      # Print out the final result
      print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
      # Plot the result
      cerebro.plot()
      

      after running this code i get this error:
      UnboundLocalError: local variable 'i' referenced before assignment
      do you know what should i do?

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

        The way you use i in your for loop doesn't make any sense. i cannot be on both sides of the loop.

        • If my answer helped, hit reputation up arrow at lower right corner of the post.
        • Python Debugging With Pdb
        • New to python and bt - check this out
        F 1 Reply Last reply Reply Quote 1
        • F
          feiz @ab_trader last edited by

          @ab_trader
          could you please show me the right way of using it?

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

            Use different indexing variables in different loops. Also right now your i looks like a data object, and you use it as index of the list. Might be a source of errors later.

            • If my answer helped, hit reputation up arrow at lower right corner of the post.
            • Python Debugging With Pdb
            • New to python and bt - check this out
            F 1 Reply Last reply Reply Quote 1
            • B
              backtrader administrators last edited by

              Let me be blunt. It will hopefully save you time and money with algotrading:

              • You need to learn Python.
              • You need to properly format your code

              If you cannot understand the error and why it is produced and cannot properly put code in a text field (and read the notice above about the ``` for code blocks) is because you are really far away from doing algotrading.

              for i in self.datas[i]
              

              which is repeated several times in the code is wrong. And not only in Python, but the equivalent in several programming languages would also be a disaster.

              Let me repeat myself: learn Python properly.

              1 Reply Last reply Reply Quote 0
              • F
                feiz @ab_trader last edited by

                @ab_trader thanks ill do it to see if it works

                1 Reply Last reply Reply Quote 0
                • 1 / 1
                • First post
                  Last post
                Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors