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

A day buy and close trade with cheat on open and stop loss



  • I am trying to backtest a strategy in which I enter at current open and exit at current close itself. That is I buy the share at start of the trading time and exit when the trading day ends. Doesn't carry forward the trade or worry about what happens in between the start and end of a trading day.

    An example would be this

                      high         low        open       close      volume
    Date                                                                  
    2019-05-23  180.539993  177.809998  179.800003  179.660004  36501400.0
    ___________________________________________________________________________
    
    STRATEGY:
    
    Entry:  open price (179.80)
    
    Stop_Loss(1% open): 178.01
    
    if Stop_Loss > low:
        Exit at Stop_Loss (178.01)
    else:
        Exit at close (179.66)
    

    I tried to first understand the cheat on open sample code in the docs but I didn't get it so went this way to code without the stop loss logic.

    cerebro = bt.Cerebro(cheat_on_open=True)
    
     def next(self):
         #order to sell at close price
         self.order = self.close(coo=False, coc=True)
    
     def next_open(self):
        # order to buy at open price
         self.order=self.buy(coo=True, coc=False)
    

    The log shows that its buying and selling the stocks at the same opening price which does nothing and incur me commission charges.

    2019-05-21, BUY EXECUTED, Price: 185.22, Cost: -185.22, Comm 9.26
    2019-05-21, OPERATION PROFIT, GROSS 0.00, NET -18.52
    2019-05-22, SELL EXECUTED, Price: 184.66, Cost: -184.66, Comm 9.23
    2019-05-22, BUY EXECUTED, Price: 184.66, Cost: -184.66, Comm 9.23
    2019-05-22, OPERATION PROFIT, GROSS 0.00, NET -18.47
    2019-05-23, SELL EXECUTED, Price: 179.80, Cost: -179.80, Comm 8.99
    2019-05-23, BUY EXECUTED, Price: 179.80, Cost: -179.80, Comm 8.99
    2019-05-23, OPERATION PROFIT, GROSS 0.00, NET -17.98
    

    Can you give a hint where I am making a mistake? In this strategy how can I add the stop loss to backtrader similar to this idea.

    if Stop_Loss > low:
        exit at Stop_Loss (178.01)
    else:
        exit at close (179.66)
    

    I assume self.buy(exectype=bt.Order.Stop, price=self.data.open[0]) will not work with my above stop loss condition.



  • Try this script -

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    
    import backtrader as bt
    
    class TestStrategy(bt.Strategy):
    
        def __init__(self):
            pass
    
    
        def next_open(self):
            self.buy(coc=False)
    
    
        def next(self):
            pos = self.getposition()
            if pos:
                self.sell()
    
    
    if __name__ == '__main__':
    
        cerebro = bt.Cerebro(cheat_on_open=True)
        cerebro.addstrategy(TestStrategy)
        data = <put your data feed here>
        cerebro.adddata(data)
        cerebro.broker.set_coc(True)
        cerebro.run()
        cerebro.plot()
    

    Should buy at open and sell at close on daily bars.



  • Another solution that does not use cheat on open. It is a cheat-on-close broker and you buy on open by disabling the coc and sell on close by enabling it.

    class TestStrategy(bt.Strategy):
    
        def next(self):
            order1 = self.close(self.datas[0], coc=True)
            order2 = self.buy(self.datas[0], coc=False)
    
    if __name__ == '__main__':
        cerebro = bt.Cerebro()
        cerebro.broker.set_coc(True)
        ....
    


  • @ab_trader @momentum thank you both for the answers, I was searching for a solution for past two days. If possible can you explain the execution logic here. I want to understand how this works? Docs dont contain much information.

    • Whats really is happening when we enable cheat on open or cheat on close
    • cerebro.broker.set_coc(True) what is this do?
    • self.buy(self.datas[0], coc=False) whats happening here?

    Is there any way to put my custom stop loss with the logic I mentioned in post. Will this work?

    stop_loss=self.data.open[0]*99/100 # 1% open
    
    if stop_loss > self.data.low[0]:
        self.close(price=stop_loss)
    else:
        self.close()
    


  • @backtrader14 said in A day buy and close trade with cheat on open and stop loss:

    Whats really is happening when we enable cheat on open or cheat on close

    Docs - Cheat-on-open
    Docs - Broker



  • @backtrader14 said in A day buy and close trade with cheat on open and stop loss:

    Is there any way to put my custom stop loss with the logic I mentioned in post. Will this work?

    You want to make 3 decisions per day: go long at open, issue stop order at open and, if this order was not executed, sell on close. Use of intraday time frames is the best and correct way to achieve this.

    If you still want to make it with daily bars, than I can see 2 options:

    • make an indicator which calculates your exit price for each bar (stop order price or close price). Then at each open issue stop or limit (maybe stop-limit) order along with the entry order.

    • use DaySplitter_Close filter to split bar in two bars. Then during first bar you issue stop order and entry order. And during second bar you cancel stop order if it was not executed and issue sell order. Link to docs - link

    I've used approach similar to my first option, but second approach looks better, but I didn't check if it works or not.



  • Thank you for the ideas. The DaySplitter_Close is little complex for me I will first try out with the first suggestion and build a custom indicator with stop loss. Lastly I really appreciate for replying to my posts :).



  • Your choice. Be accurate with the first approach, it has look-ahead bias in it. So if your results will be very optimistic, than check them carefully.


Log in to reply
 

});