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

Filtering trading sessions



  • Hi,

    the strategy, I'm working on is a day trading strategy which would normally run during the EU session. Currently, for backtesting purposes, I have imported 1 minute metaquote (MT4) EURUSD data and reading it in as a dataframe, I downloaded it from here https://www.fxdd.com/mt/en/resources/mt4-one-minute-data. I think it's in GMT time but not sure.

    I would need some sort of indicator which indicates the different sessions so I can filter out my trading time for it. I was wondering how to tackle the issue of daylight savings and I'd imagine I'd have to set the timezone or something. I don't really have an idea where to start and eventually I want use IB data to forward test.

    thanks



  • Some information on timezones.



  • @run-out thanks run-out. other question which is related to datetime. for order we have the parameter "valid". if my order is not triggered the next bar(next minute in this case) then I want to cancel it. I can see that datetime.datetime can be used. however, I need to reference the time for the current bar and then I imagine, use a timedelta to get to the next bar in order to cancel the order. how can we reference the datetime of the current bar? I've tried self.datetime.datetime[0] but that doesn't work.



  • to be more concrete. I want to cancel the order if it doesn't get triggered next bar. however if the high would be equal, and the low would be higher (for a long), I would want to keep my entry the same (above the high) and move the stoploss to the new low.



  • @Jens-Halsberghe
    Try using bar length instead.

    len(self)
    

    From android



  • @run-out thanks.

    just an FYI. I figured out I can use

    self.data.datetime.datetime(0)
    

    to reference the current's bar datetime

    then if I'd want it to be valid for eg 1 minute I can do

    valid=self.data.datetime.datetime(0) + datetime.timedelta(0,0,0,0,1)
    

    I think using

    len(self)
    

    is what I'll need. I am struggling with checking if the order got filled or not.

    def next(self):
        
        # Check if an order is pending ... if yes, we cannot send a 2nd one
        if self.order:
            return
        
        # Check if we are in the market
        if not self.position:
        
            if entry_condition == True:
                self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high[0], transmit=False)
    
                self.StopLoss = self.sell(price=self.data.low[0],exectype=bt.Order.Stop, transmit=False, size=self.order.size,parent=self.order )
    
                self.target = self.sell(price=(self.order.price-self.data.low[0]*1.1+self.order.price), exectype=bt.Order.Limit, transmit=True, size=self.order.size,  parent=self.order)
    
                self.bar_order_submitted = len(self)
    
                self.log('BUY CREATE, %.5f' % self.order.price)
                    
            if self.order not in order.Completed and len(self) == self.bar_order_submitted + 1: # error occurs here
            
                if self.data.high[0] == self.data.high[-1]: # current's bar high is equal to the previous bar's high
                    self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high[0], transmit=False)
    
                    if self.data.low[0] > self.data.low[-1]: # if the current bar's low is higher, we adjust ourstoploss to the current bar's low
                       self.target = self.sell(price=(self.order.price-self.data.low[0]*1.1+self.order.price) ,exectype=bt.Order.Limit,transmit=True, size=self.order.size,  parent=self.order)
    

    error I'm getting

    --> 102             if self.order not in order.Completed and len(self) == self.bar_order_submitted + 1:
        103                 if self.data.high[0] == self.data.high[-1]: # current's bar high is equal to the previous bar's high
        104                     self.order = self.buy(exectype=bt.Order.StopLimit, price=self.data.high[0], transmit=False)
    
    NameError: name 'order' is not defined
    

    just wanted to mention, I have the notify_trade method in the strategy and also self.order = None at init



  • @Jens-Halsberghe said in Filtering trading sessions:

    if self.order not in order.Completed

    The offending line is here. order.Complete is a local variable to the next method, and is not defined in next. It is defined in notify_order. Try using self.order.Complete.

    Or you can just use the number 4 to replace order.Complete. The order.Complete attribute returns the number 4. Here is the status list in the order object and the order Status is a list that reflects the number returned.

    ['Created', 'Submitted', 'Accepted', 'Partial', 'Completed', 'Canceled', 'Expired', 'Margin', 'Rejected']. 
    

    And if you debug and look at the attributes you would find

    Completed: 4
    


  • @run-out thanks again Sir. I have actually tried this before and I'm getting

    AttributeError: 'NoneType' object has no attribute 'Completed'
    

    I tried

    self.order.4 
    self.4
    

    and then I'm getting a syntax error so I'm not sure if I'm getting what you're referring to.

    btw I know you said "Complete" I tried that too but I think you meant to say "Completed" as that's what we have in notify_order



  • Couple things here. First of all, I figured out if I add order.status in notify_trade, I'm getting the numbers as you mentioned

            if order.status in [order.Submitted, order.Accepted]:
                # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                self.log(order.status)
    

    second, I actually noticed that my order is always cancelled for some reason. I split what it says in the log to distinguish between canceled, margin and rejected.

    if we have a look at the log:

    Starting Portfolio Value: 1000000.00
    2020-08-12 08:30, BUY CREATE, 1.17170
    2020-08-12 08:31, BUY EXECUTED, Price: 1.17170, Cost: 1.1717, Comm 0.0000
    2020-08-12 08:32, SELL EXECUTED, Price: 1.17183, Cost: 1.1717, Comm 0.0000
    2020-08-12 08:32, cancelled
    2020-08-12 08:32, OPERATION PROFIT, GROSS 0.0001, NET 0.0001
    2020-08-12 08:53, BUY CREATE, 1.17228
    2020-08-12 08:54, BUY EXECUTED, Price: 1.17228, Cost: 1.1723, Comm 0.0000
    2020-08-12 08:55, SELL EXECUTED, Price: 1.17222, Cost: 1.1723, Comm 0.0000
    2020-08-12 08:55, cancelled
    2020-08-12 08:55, OPERATION PROFIT, GROSS -0.0001, NET -0.0001
    2020-08-12 08:55, BUY CREATE, 1.17225
    2020-08-12 08:57, BUY EXECUTED, Price: 1.17225, Cost: 1.1723, Comm 0.0000
    2020-08-12 08:58, SELL EXECUTED, Price: 1.17208, Cost: 1.1723, Comm 0.0000
    2020-08-12 08:58, cancelled
    

    I have not really any idea why that is. I initially create the order, target and stop loss as in my post above. I wanted to log when the stoploss or target gets triggered but I can't really see how to do that either. the execution part is quite tricky for me at the moment!



  • In next you have assigend your entry order object to the variable self.order. When in notify_order, you access the current order object using the variable order. These are both order objects.

    In an order object you can access the status of that object which is stores as in next self.order.status or in notify_order as order.status.

    For completed orders this status variable will equal 4.

    In your code, in next, you can use:

    if self.order.status != self.order.Completed  etc.
    

    or

    if self.order.status != 4    etc.
    

    The cancel is normal. It is cancelling the other side of the bracket, so if you fill on the take profit, the stop gets cancelled and vice versa. If you want a bit more information in your log you can show the order reference numbers.

    Also as another side note, I notice you are assigning the size using order.size. Size is acutally tracked in order.created.size.


Log in to reply
 

});