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

sell a position after 2 days



  • I want to buy a position and sell it after 2 days and I've tried to return the day I opened the position into init but it gives me

    TypeError: 'GapUp' object is not an iterator
    

    I just started with Backtrader an I have no clue on how to solve this issue, thanks in advance to whoever can give me some hint.

    import backtrader as bt
    from datetime import datetime, timedelta, date
    #datetime.datetime(year, month, day, hour=0, minute=0, second=0, microsecond=0, tzinfo=None, *, fold=0)
    
    class GapUp(bt.Strategy):
        
        def __init__(self):
            self.change = bt.ind.PctChange()
            self.dataclose = self.datas[0].close
            self.currdate = self.datas[0].datetime.date(0)
            position_date = next(self)
            
    
        def next(self):
            if self.change >= 0.05:
                self.buy(size=1)
                print(self.datas[0].datetime.date(0))
                print(self.datas[0].close[0])
                return self.datas[0].datetime.date(0)
            #if self.currdate >= self.position_date + datetime.timedelta(days=2):
            #    close()
            
    
    
    
    cerebro = bt.Cerebro()
    cerebro.addstrategy(GapUp)
    
    data = bt.feeds.YahooFinanceCSVData(dataname='^GSPC.csv', fromdate=datetime(2018,1,1), todate=datetime(2019,11,1))
    cerebro.adddata(data)
    cerebro.broker.setcash(100000.0)
    cerebro.run()
    cerebro.plot()
    


  • __init__() is called once at the very beginning of the run. I doubt that you will be able to return something from the following run to the __init()__.

    If you want to exit after N bars, than:

    • in notify_order() get order execution bar
    self.bar_executed = len(self)
    
    • in the next() calculate position duration based on current strategy length
    self.duration = len(self) - self.bar_executed + 1
    
    • if it is 2, then issue the order to close position
    if self.duration == 2:
        self.close()
    

  • administrators

    @PatrikMuniak said in sell a position after 2 days:

    I want to buy a position and sell it after 2 days

    Notice that using anything which is datetime related won't usually work unless you don't mind weekends and trading holidays adding days to the count.



  • @ab_trader
    Thanks a lot for replying, I've tried to implement what you've said and I managed to make it work until the graph. The issue is that even if I don't get any error the sell is not working, i.e the plot() shows just buys but not sells.

    This is how I tried to implement you answer:

    import backtrader as bt
    from datetime import datetime, timedelta, date
    
    class GapUp(bt.Strategy):
    
        
        def __init__(self):
            self.change = bt.ind.PctChange()
            self.dataclose = self.datas[0].close
            self.currdate = self.datas[0].datetime.date(0)
            
        def notify_order(self, order):
            self.bar_executed = len(self)
    
        def next(self):
            if self.change >= 0.05:
                self.buy(size=1)
    
            self.notify_order(self)
            self.duration = len(self) - self.bar_executed + 1
    
            if self.duration == 2:
                self.close()
    
    
    cerebro = bt.Cerebro()
    cerebro.addstrategy(GapUp)
    
    data = bt.feeds.YahooFinanceCSVData(dataname='^GSPC.csv', fromdate=datetime(2018,1,1), todate=datetime(2019,11,1))
    cerebro.adddata(data)
    cerebro.broker.setcash(100000.0)
    cerebro.run()
    cerebro.plot()
    


  • @PatrikMuniak every next() you call notify_order() and set your self.bar_executed to length of the data. So your self.duration vaule is equal to 1 on every next() call. No surprise you have no sells.


Log in to reply
 

});