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

Orders executed in weird sequence



  • Hey together

    I am having a problem with a strategy where I am rebalancing two assets. See the code below:

    class RebalancingStrategy(bt.Strategy):
    
    	def __init__(self, verbose=1):
    
    		# verbosity
    		self.verbose = verbose
    
    	def next(self):
    
    		asset_0_target   = 0.75
    		asset_1_target   = 0.25
    		rebalance_spread = 0.05
    
    		# calculate current position weights
    		asset_0_weight = round((self.getposition(self.datas[0]).size * self.datas[0].close[0]) / self.broker.getvalue(), 4)
    		asset_1_weight = round((self.getposition(self.datas[1]).size * self.datas[1].close[0]) / self.broker.getvalue(), 4)
    
    		asset_0_spread = abs(asset_0_target - asset_0_weight)
    		asset_1_spread = abs(asset_1_target - asset_1_weight)
    
    		total_spread   = asset_0_spread + asset_1_spread
    
    		if total_spread > rebalance_spread:
    
    			# determine sell order and issue it first
    			if asset_0_weight > asset_0_target:
    				
    				sell_asset_num    = 0
    				sell_asset_target = asset_0_target
    				
    				buy_asset_num    = 1
    				buy_asset_target = asset_1_target
    
    			else:
    			
    				sell_asset_num = 1
    				sell_asset_target = asset_1_target
    
    				buy_asset_num  = 0
    				buy_asset_target = asset_0_target
    
    			self.order_target_percent(data=self.datas[sell_asset_num], target=sell_asset_target, exectype=bt.Order.Limit, price=self.datas[sell_asset_num].open[1])
    			self.order_target_percent(data=self.datas[buy_asset_num],  target=buy_asset_target,  exectype=bt.Order.Limit, price=self.datas[buy_asset_num].open[1])
    
    

    For optical reasons I excluded the notify functions. From what I see in the docs, I assume that the order that gets issued first, will be executed first. As you can see, I am issuing the "sell" order first to get free cash for the buy order. Below is the output from the notify functions.

    2018-10-02 - BUY[1]      VIXY    1148    @ 21.76
    2018-10-02 - BUY[2]      SPY     257     @ 291.56
    2018-10-11 - SELL[3]     VIXY    -222    @ 27.6
    2018-10-11 - BUY[4]      SPY     22      @ 277.08
    2018-10-25 - SELL[5]     VIXY    -121    @ 31.58
    2018-10-25 - BUY[6]      SPY     14      @ 267.38
    2018-11-07 - REJ[8]      VIXY    99      @ 0.0
    2018-11-07 - SELL[7]     SPY     -9      @ 277.56
    2018-11-08 - REJ[10]     VIXY    165     @ 0.0
    2018-11-08 - SELL[9]     SPY     -6      @ 280.11
    2018-12-10 - SELL[11]    VIXY    -19     @ 33.23
    2018-12-10 - BUY[12]     SPY     19      @ 263.37
    2018-12-21 - SELL[13]    VIXY    -92     @ 36.91
    2018-12-21 - BUY[14]     SPY     13      @ 246.74
    2018-12-26 - SELL[15]    VIXY    -73     @ 40.38
    2018-12-26 - BUY[16]     SPY     13      @ 235.97
    

    What I don't understand is why sometimes the BUY order is still issued first and therefore obviously rejected. Could you point me to what I am missing. Would be really grateful. :)


  • administrators

    @nimrare said in Orders executed in weird sequence:

    I assume that the order that gets issued first, will be executed first

    The assumption is partially right and therefore absolutely wrong.

    ... exectype=bt.Order.Limit, ...
    

    Orders will be evaluated in the order in which they are issued (inserted into the system), i.e.: FIFO. If you were using Market orders, that would mean that execution would also follow the FIFO pattern.

    But if you issue Limit orders, and thus you cannot guarantee execution order (you cannot actually even guarantee execution at all, with or without time constraints imposed on the order)

    With no single data point it is obviously impossible to show a practical example.



  • @backtrader

    Ah, that makes sense. Thanks a lot for your response.


Log in to reply
 

});