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/

    Why is the self.position always zero ?

    General Discussion
    3
    6
    1057
    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.
    • S
      songcl last edited by

      Dear friend, I use a minute level data to backtest , I set the buy condition: if not self.position , but the position is always zero,but if I use the dayly level data, there are no problem. The data is from the sample . I can 't find the cause. can you help me? Thanks a lot.

      from __future__ import (absolute_import, division, print_function,unicode_literals)
      import backtrader as bt
      import backtrader.indicators as btind
      import backtrader.feeds as btfeeds
      
      import datetime
      import os.path
      import sys
      
      class Mytest(bt.Strategy):
          params = (('fast',5),('slow',20),)
          lines = ('fast','slow',)
      
          def log(self,txt,dt = None):
              '''log function for this strategy'''
              dt = dt or self.data.datetime[0]
              if isinstance(dt,float):
                  dt = bt.num2date(dt)
              print('%s %s' % (dt.isoformat(),txt))
          def __init__(self):
               # To control operation entries
              self.order = None
       
              self.lines.fast = btind.SimpleMovingAverage(period = self.p.fast)
              self.lines.slow = btind.SimpleMovingAverage( period = self.p.slow)
      
              self.buysig = btind.CrossOver(self.lines.fast,self.lines.slow)
      
          def notify_order(self,order):
              if order.status in [order.Submitted, order.Accepted]:
                  #buy/sell order have been submitted, nothing to do 
                  return 
              self.order = None
      
          def next(self):
              if self.order:
                  return  # if an order is active, no new orders are allowed
              
              self.log(self.getposition().size)# always get the zero result. why?
              if not self.position:
                  if self.buysig[0] > 0:
                          self.order = self.buy(size = 100)
                          self.log('buy')
                  
              else: 
                   if self.buysig[0] < 0:
                      self.order = self.sell(size = 100)
                      self.log('sell')
      
      def runstrategy():
          #args = parse_args()
      
          #create a cerebro
          cerebro = bt.Cerebro()
      
          #get the dates from the args
          #fromdate = datetime.datetime.striptime(args.fromdate,'%Y-%m-%d')
          fromdate = datetime.datetime(2006,1,2)
          #today = datetime.datetime.striptime(args.today,'%Y-%m-%d')
          today = datetime.datetime(2006,2,10)
      
          modpath=os.path.dirname(os.path.abspath(sys.argv[0]))
          datapath = os.path.join(modpath,'datas/2006-01-02-volume-min-001.txt')
          #datapath = os.path.join(modpath,'datas/yhoo-1996-2015.txt')
      
      
          data = btfeeds.BacktraderCSVData(
              dataname = datapath,
              frmodate = fromdate,
              today = today,
              timeframe=bt.TimeFrame.Minutes,
              compression = 1
              )
      
          #cerebro.adddata(data)
          cerebro.resampledata(data,
                               timeframe =  bt.TimeFrame.Minutes,
                               compression = 60,
                               )
      
          cerebro.addstrategy(Mytest)
      
          cerebro.broker.setcash(10000)
          cerebro.broker.setcommission(0.01)
          #cerebro.addsizer(bt.sizers.FixedSize,stake = 100)
      
          cerebro.run()
      
          cerebro.plot()
      
      if __name__ == '__main__':
          runstrategy()
      
      1 Reply Last reply Reply Quote 0
      • A
        ab_trader last edited by

        self.position is always zero because the position is never open. it can be variety of reasons: you can't buy/sell 100 shares due to lack of funds, SMA don't cross etc. Get more outputs and check what is going on.

        • 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
        1 Reply Last reply Reply Quote 0
        • S
          songcl last edited by

          I changed the cash 100000. and the log is :
          2006-01-06T12:00:00 buy
          2006-01-06T12:00:00 0
          2006-01-09T22:00:00 buy
          2006-01-09T22:00:00 0
          2006-01-11T11:00:00 buy
          2006-01-11T11:00:00 0
          2006-01-12T18:00:00 buy
          2006-01-12T18:00:00 0
          2006-01-16T14:00:00 buy
          2006-01-16T14:00:00 0
          2006-01-19T12:00:00 buy
          2006-01-19T12:00:00 0
          2006-01-24T11:00:00 buy
          2006-01-24T11:00:00 0
          2006-01-31T19:00:00 buy
          2006-01-31T19:00:00 0
          2006-02-03T21:00:00 buy
          2006-02-03T21:00:00 0
          2006-02-08T17:00:00 buy
          2006-02-08T17:00:00 0
          2006-02-13T18:00:00 buy
          2006-02-13T18:00:00 0
          2006-02-15T17:00:00 buy
          2006-02-15T17:00:00 0
          2006-02-16T13:00:00 buy
          2006-02-16T13:00:00 0
          2006-02-20T20:00:00 buy
          2006-02-20T20:00:00 0
          2006-02-22T15:00:00 buy
          2006-02-22T15:00:00 0

          1 Reply Last reply Reply Quote 0
          • run-out
            run-out last edited by

            Your trying to buy 100 shares at 3,600 per share with $10,000. That's always going to be a problem. Try using 1 share or putting a lot of money in the account.

            Try adding in these to get more information:

                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.Canceled, order.Margin]:
                        if order.isbuy():
                            self.log("BUY FAILED, Cancelled or Margin")
                        self.log
                    if order.status in [order.Completed, order.Canceled, order.Margin]:
                        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)
            
                    # 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))
            

            Also maybe print out a OHLC log like this:

            self.log(
                        "o {:5.2f}\th {:5.2f}\tl {:5.2f}\tc {:5.2f}\tv {:5.0f}".format(
                            self.datas[0].open[0],
                            self.datas[0].high[0],
                            self.datas[0].low[0],
                            self.datas[0].close[0],
                            self.datas[0].volume[0],
                        )
                    )
            

            Finally, if you just want to close out your long position, use self.close, not self.sell.

            RunBacktest.com

            1 Reply Last reply Reply Quote 0
            • S
              songcl last edited by

              Thank You ! I got it .
              I run as your code , the log is :
              2006-01-06T12:00:00 buy
              2006-01-06T13:00:00 Buy Execute, Price: 3670,Cost:3670,Comm 36.70 ,position 1
              2006-01-09T22:00:00 Sell Execute, Price: 3684,Cost:3670,Comm 36.84 position 0
              2006-01-09T22:00:00 OPERATION PROFIT ,GROSS 14.00,Net -59.54
              2006-01-09T22:00:00 buy
              2006-01-10T10:00:00 Buy Execute, Price: 3676,Cost:3676,Comm 36.76 ,position 1
              2006-01-10T11:00:00 Sell Execute, Price: 3663,Cost:3676,Comm 36.63 position 0
              2006-01-10T11:00:00 OPERATION PROFIT ,GROSS -13.00,Net -86.39
              2006-01-11T11:00:00 buy
              2006-01-11T12:00:00 Buy Execute, Price: 3677,Cost:3677,Comm 36.77 ,position 1
              2006-01-12T15:00:00 Sell Execute, Price: 3670,Cost:3677,Comm 36.70 position 0
              2006-01-12T15:00:00 OPERATION PROFIT ,GROSS -7.00,Net -80.47
              2006-01-12T18:00:00 buy
              2006-01-12T19:00:00 Buy Execute, Price: 3687,Cost:3687,Comm 36.87 ,position 1
              2006-01-13T10:00:00 Sell Execute, Price: 3666,Cost:3687,Comm 36.66 position 0
              2006-01-13T10:00:00 OPERATION PROFIT ,GROSS -21.00,Net -94.53
              2006-01-16T14:00:00 buy
              2006-01-16T15:00:00 Buy Execute, Price: 3647,Cost:3647,Comm 36.47 ,position 1
              2006-01-17T13:00:00 Sell Execute, Price: 3624,Cost:3647,Comm 36.24 position 0
              2006-01-17T13:00:00 OPERATION PROFIT ,GROSS -23.00,Net -95.71
              2006-01-19T12:00:00 buy
              2006-01-19T13:00:00 Buy Execute, Price: 3597,Cost:3597,Comm 35.97 ,position 1
              2006-01-20T17:00:00 Sell Execute, Price: 3592,Cost:3597,Comm 35.92 position 0
              2006-01-20T17:00:00 OPERATION PROFIT ,GROSS -5.00,Net -76.89

              1 Reply Last reply Reply Quote 0
              • run-out
                run-out last edited by

                Awesome!

                RunBacktest.com

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