How do I stop and reverse on same bar?



  • I'm looking for the approach to close a trade and reverse direction. My first attempt to do this was in next(): but it seems that a trade execution breaks us from the next. If tried the following in the strategy:

    if position:
        if condition:
            self.close()
    
    if not position:
        if condition:
            self.buy()
        elif condition:
            self.sell()
    

    From what I can see, we seem to not revisit the if not position: until the next bar. What is the appropriate way to handle this?


  • administrators

    The platform cannot forbid the execution of the 2nd condition.

    The problem is that the position is not zero as revealed by the 1st test. The orders will be executed in the broker once you are out of next



  • How do I set the order size in Strategy next()?

    I have position.size of current position and I know I can call self.buy(size=int) or self.sell(size=int). Is there a way I can call the sizer from this point in the strategy? The goal being to increase the size enough to trigger a position reversal.



  • Appears I have self.getsizing() here if I understand correctly what it is doing. I'm looking for portfolio value after closing the currently open trade which should include some unrealized profit or loss.



  • This 'next' reverse position. It buys/cover short on Mondays and sell/go short on Wednesdays. Is it what you are looking for?

        def next(self):
    
            pos_size = self.broker.getvalue() // self.data.close[0] 
    
            if self.data.datetime.date().weekday() == 0: # BUY condition
                if self.position:
                    self.close()
                self.order = self.buy(size=pos_size)
    
            if self.data.datetime.date().weekday() == 2: # SELL condition
                if self.position:
                    self.close()
                self.order = self.sell(size=pos_size)
    

    Also it buys/sells on close of the day.



  • I think what I have failed to mention is that I want this to happen on the same bar.

    I believe I can accomplish that by either buying or selling in the opposite direction of the current position, but am trying to apply the sizer logic to calculate the new order size. ie self.position.size + sizer()

    In your example above, doesn't self.broker.getvalue() return a monetary value of the account? It was my understanding that size parameter passed to the self.buy() or self.sell() was expecting an integer number of shares/contracts? Not true?



  • @RandyT This script buys & sells on the same bar. Here is the output (one buy and one short) from modified script with the log function:

    Starting Portfolio Value: 100000.00
    2016-06-01  Open Pos, 0; Price 210.2700; Lev Val 100000.0000 Val 100000.00; Cash 100000.00, 
    2016-06-01 ORDER CREATED, Price 210.27; SELL, 475
    2016-06-02  Open Pos, -475; Price 210.9100; Lev Val 99696.0000 Val 99696.00; Cash 199878.25, 
    2016-06-03  Open Pos, -475; Price 210.2800; Lev Val 99995.2524 Val 99995.25; Cash 199878.25, 
    2016-06-06  Open Pos, -475; Price 211.3500; Lev Val 99486.9990 Val 99487.00; Cash 199878.25, 
    2016-06-06 LONG CLOSED, Price 211.35; SOLD, -475
    2016-06-06 ORDER CREATED, Price 211.35; BUY, 470
    2016-06-07 OPERATION PROFIT, GROSS -513.00, NET -513.00
    2016-06-07  Open Pos, 470; Price 211.6800; Lev Val 99642.0929 Val 99642.09; Cash 152.50, 
    2016-06-08  Open Pos, 470; Price 212.3700; Lev Val 99966.3939 Val 99966.39; Cash 152.50, 
    2016-06-08 SHORT CLOSED, Price 212.37; BOUGHT, 470
    2016-06-08 ORDER CREATED, Price 212.37; SELL, 470
    2016-06-09 OPERATION PROFIT, GROSS 479.39, NET 479.39
    

    Trade report comes bar later , but it is a bt thing.

    Formula for position size:
    pos_size = self.broker.getvalue() // self.data.close[0]

    It will be integer number of shares based on current funds and stock price. Somehow forum recognizes // as a comment but it is not.



  • I'll give this another try to see if I can replicate your behavior. From what I saw, trading on daily timeframe, I saw the trade for the reversal getting executed on the next day after the exit of the previous position.

    Also, my sizer is more complicated than just number of shares per equity. I have created a VaR sizer which returns an integer number of contracts to purchase based on VaR of current market. So I really need to access the sizer() value at this point to determine order size.



  • In my script output you can see that on 2016-06-06 order to close previous position was issued by self.close(), and at the same day new buy order was created by self.buy(). Same happened on 2016-06-08: close long order issued, open short order issued. Since I use .set_coc=True, then these orders are executed at the same day as they are issued. I've misspelled the following: SHORT CLOSED should be LONG CLOSED and LONG CLOSED should be SHORT CLOSED. But it is mistake in log string, not in the trading logic.

    If I understand bt logic correctly, sizer value is calculated internally when the buy - self.buy() - or sell - self.sell() - order is issued. You don't need to call it somehow in the strategy.

    I was thinking to use sizer for this, but I wasn't able to get separate trades. I got one trade with varying position size according sizing rules.


  • administrators

    As mentioned by @ab_trader orders are executed on the same bar if you set coc=True in the broker. If not the bar is considered closed and order execution is deferred until the next bar. Two orders issued on the same bar with Market execution policy should be executed also on the same bar (be it the next or the current bar)

    The system does a check of submitted orders before accepting them. To avoid for example having 2 consecutive orders which would go over the actual cash reserves on the same bar. If tries to take into account that if a long position is closed cash will be re-injected into the system to let you operate with another buy.

    Deactivation of the check can be achieved in the broker with checksubmit=False

    Sizers are called internally by buy and sell (close uses the actual existing position) but a Sizer can be subclassed to provide complex functionality.

    In that documentation page there are examples of how the modification of _getsizing achieves policies, like for example reversing a position or keeping it long only.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.