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

Help with simple strategy position size always 0



  • Hi! im new with backtrader and im traying to implement a simple strategy were it buys on SMA cross and sell on market close on an APPLE intraday data.

    My problem is that there is not seems to be buy execution... self.position is always 0. (im using 10% of my portfoltio on every trader, at least that is the intention)

    But on market close it seem to close the position and it gets negative values..

    can you help me? i cant find whats missing...

    here is the code for the strategy

    class smacross(bt.Strategy):
        # list of parameters which are configurable for the strategy
        params = dict(pfast = 20, pslow=200)
        
        def __init__(self):
            sma1 = bt.ind.SMA(period=self.params.pfast) # fast moving average
            sma2 = bt.ind.SMA(period=self.params.pslow) # slow moving average
            self.crossover = bt.ind.CrossOver(sma1, sma2)  # crossover signal
        
        
        def next(self):
            if not self.position: # not in the market
                if self.crossover > 0:  # if fast crosses slow to the upside
                    size= int(self.broker.getcash() / self.data)
                    self.buy(size=size)  # enter long
                    print(self.position)
    
            elif self.data.datetime.time() >= datetime.time(16,50):
                  #self.crossover < 0:  # in the market & cross to the downside
                self.close()  # close long position
    

    and this is the general code

    from estrategia import smacross
    import estrategia
    import pandas as pd
    
    # Create a cerebro entity
    cerebro = bt.Cerebro()
    
    # Add a strategy
    cerebro.addstrategy(estrategia.smacross)
    
    # Create a Data Feed
    data = bt.feeds.GenericCSVData(
            dataname= "intra_AAPL_short.csv",
            datetime=0,
            timeframe=bt.TimeFrame.Minutes,
            dtformat=('%Y-%m-%d %H:%M:%S'),
            open=1,
            high=2,
            low=3,
            close=4,
            volume=5,
            openinterest=-1,)
    
    # Add the Data Feed to Cerebro
    cerebro.adddata(data)
    
    # Set our desired cash start
    cerebro.broker.setcash(60000)
    
    # Print out the starting conditions
    print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
    
    cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='mysharpe')
    
    thestrats = cerebro.run()
    thestrat = thestrats[0]
    
    print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
    print('Sharpe Ratio:', thestrat.analyzers.mysharpe.get_analysis())
    
    cerebro.plot()
    

    The results are the following... i printed position.size an it always is in 0 size, position is closed and it get negative value...

    Starting Portfolio Value: 60000.00
    --- Position Begin

    • Size: 0
    • Price: 0.0
    • Price orig: 0.0
    • Closed: 0
    • Opened: 0
    • Adjbase: None
      --- Position End
      --- Position Begin
    • Size: 0
    • Price: 0.0
    • Price orig: 42.1594074358
    • Closed: -1423
    • Opened: 0
    • Adjbase: 41.949416179
      --- Position End
      --- Position Begin
    • Size: 0
    • Price: 0.0
    • Price orig: 42.1178975362
    • Closed: -1417
    • Opened: 0
    • Adjbase: 42.6428756781

    thanks in advanced, any help will be great!!



  • @Ramacap

    Hi Ramacap,

    i think this forum would be more fitting for such a question:
    https://community.backtrader.com/category/7/general-code-help

    Nonetheless, I think you should try to better understand whats going on by printing out each part of that statement

    size= int(self.broker.getcash() / self.data)
    

    A better way to get where you want is:

                percent = 0.95
                self.order = self.order_target_percent(target=percent)
    
    


  • You are printing the position right after the buy method is called. The position is not updated at this point - it will get it value only after the buy order will be completed.

    I've updated your code with:

        def notify_order(self, order):
            print('{}: Order ref: {} / Type {} / Status {}'.format(
                self.data.datetime.date(0),
                order.ref, 'Buy' * order.isbuy() or 'Sell',
                order.getstatusname()))
    
            if order.status == order.Completed:
                print(self.position)
    

    and the output is now:

    Starting Portfolio Value: 60000.00
    1999-09-16: Order ref: 1 / Type Buy / Status Submitted
    1999-09-16: Order ref: 1 / Type Buy / Status Accepted
    1999-09-16: Order ref: 1 / Type Buy / Status Completed
    --- Position Begin
    - Size: 1478
    - Price: 40.53125
    - Price orig: 0.0
    - Closed: 0
    - Opened: 1478
    - Adjbase: 40.859375
    --- Position End
    ...
    

    ( I was running your code on some yhoo-1996-2015 sample data)


Log in to reply
 

});