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



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



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



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



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


  • administrators

    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.



  • @ab_trader thanks ill do it to see if it works


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.