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

Cheat on order execution price



  • There're cheat on open / close flag at cerebro / broker level. However, their execution behavior is still not that flexible, plus the interference if both are set to be true.

    Take the documentation example for cheat on open (https://www.backtrader.com/docu/cerebro/cheat-on-open/cheat-on-open.html?highlight=next_open), if cheat_on_open=False, the order get sent on 2005-04-08 and executed at close price 3088.47 on 2005-04-11. if cheat_on_open=True, the order get sent on 2005-04-11, but it still executed at same price. So the cheat on open doesn't have the influence on the execution price, which may be what we wanted depends on the scenario.

    But it can be quite helpful if we want to simulate certain order execution given specific data frequency. For example, I find it hard to implement a simulated strategy which simply buy on open, and sell on close on a daily data.

    So can we have a "complete" cheating order execution, which we can specify the execution price. In the reasonable hand, this could be very helpful and make certain strategy easy to simulate given specific data restriction.


  • administrators

    @aris-l said in Cheat on order execution price and time:

    So the cheat on open doesn't have the influence on the execution price, which may be what we wanted depends on the scenario.

    You cannot influence the price if you send a Market order. The matching logic (in backtrader and in the exchange) will give you what's at hand.

    The major use case about cheat-on-open is, for many people, to be able to calculate stakes accurately with the opening price because they want to go all-in (or near to all-in) and price differences between the previous close and the current open are sometimes the cause for order rejection, because the stake calculated with the previous close price is too large for the current open (and matching) price.

    @aris-l said in Cheat on order execution price and time:

    I find it hard to implement a simulated strategy which simply buy on open, and sell on close on a daily data.

    It's easy.

    Option 1

    • Activate cheat-on-close
    • Issue a sell Market order during next to sell at the closing price
    • Issue then a buy Market (in the same next) and it will buy you the opening price

    Ok, this may not be your logic

    Option 2

    • Activate cheat-on-open and cheat-on-close
    • Issue a buy Market in next_open and it will buy you the opening price
    • Issue a sell Market order during next to sell at the closing price and the position will be closed


  • @backtrader

    I have activated coo and coc as you described.

    cerebro.broker.set_coo(True)
    cerebro.broker.set_coc(True)
    

    the problem is that both of them wont work together. The last one takes priority. How do you properly do it?



  • Could someone please answer @Traderone3 ? His remark is indeed correct, there seems to be no way to buy at Open price AND sell at Close price.

    I did try the solution given 'Option 2' but it does not work, as the order issued during next is only executed the following bar (the following day) which is, from what i gather, what it is expected to do.

    There has to be a way to Buy at Open AND sell at Close on the same day, isn't there ?


  • administrators

    @cerberos said in Cheat on order execution price:

    Could someone please answer @Traderone3 ? His remark is indeed correct, there seems to be no way to buy at Open price AND sell at Close price.

    I thin you are mistaken. Let me quote from the other post

    @traderone3 said in Cheat on order execution price:

    I have activated coo and coc as you described.

    cerebro.broker.set_coo(True)
    cerebro.broker.set_coc(True)
    

    the problem is that both of them wont work together. The last one takes priority

    Priority over what? Orders are executed evaluated in FIFO order. cheat-on-close or cheat-on-open do only allow to take the prices which some shouldn't be able to take.

    @cerberos said in Cheat on order execution price:

    I did try the solution given 'Option 2' but it does not work, as the order issued during next is only executed the following bar (the following day) which is, from what i gather, what it is expected to do.

    You say you want to execute two (2) orders but your post is only talking about one order. To which order are you referring?

    To execute things with the open price with cheat-on-open you have to use next_open. Apparently you haven't.

    You share no code, you share no data, you share no logs. Let us know something else.



  • Hi again.

    You're right, I did not share any code and I should've.
    First, let me explain what is it exactly I desire.

    Suppose your data is daily OHLC. My strategy would be simple :
    if a certain condition is met on the current bar datas[0] (lets say the performance is greater than a certain value), I decide to do the following operations the following day, whatever may happen :

    • Buy at Open price.
    • Sell at Close price.

    No cheating whatsoever as I make that decision before I get to know the values of datas[1].

    Now what @Traderone3 said :
    @traderone3 said in Cheat on order execution price:

    I have activated coo and coc as you described.

    cerebro.broker.set_coo(True)
    cerebro.broker.set_coc(True)
    

    the problem is that both of them wont work together. The last one takes priority. How do you properly do it?

    From what I gather he was trying to do the same thing as me, and the code above only activates cheat-on-close as the orders issued in both next_open and next are executed at close price, making the operation's profit always null.

    Now I did try to find a solution and I think I somehow got it to perform what I needed. Here's my code :

    cerebro = bt.Cerebro(cheat_on_open=True)
    cerebro.broker.set_coc(True)
    

    which, and it is worth stating it, surprisingly gives different results than what was proposed previously :

    cerebro = bt.Cerebro()
    cerebro.broker.set_coo(True)
    cerebro.broker.set_coc(True)
    

    (As I said this seems to only activate cheat-on-close, "the last one takes priority" as @Traderone3 said.)

    Then, I issued my orders as such :

    • in next_open I issue the order to buy at open price with arguments coo=True, coc=False
    self.buy(coo=True, coc=False)
    
    • in next I issue the order to sell at close price with arguments coo=False, coc=True
    self.order = self.sell(coo=False, coc=True)
    

    The results I get are somehow what I need, the first order is executed as I wanted at Open price of datas[1] the next bar.
    But the second order, even though it is executed at close price of datas[1], which is what I want, is only notified by notify_order the following day (datas[2]), which i guess is normal since it was issued in next. I would have preferred to see it notified the same day, is there perhaps a method notify_order_close that makes this possible ?

    That's my take on the issue, hope I made myself clear enough and this post helps people struggling with the same problem.



  • @cerberos I was also looking for such a system I tried your way but I think in my tests it just sells and buys the asset at same open price itself. Because of this its doing nothing to the overall trade. If we add commision then we lose the trade.

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