Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    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

    General Code/Help
    2
    10
    562
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Jens Halsberghe
      Jens Halsberghe last edited by

      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

      1 Reply Last reply Reply Quote 0
      • run-out
        run-out last edited by

        Some information on timezones.

        RunBacktest.com

        Jens Halsberghe 1 Reply Last reply Reply Quote 1
        • Jens Halsberghe
          Jens Halsberghe @run-out last edited by

          @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.

          Jens Halsberghe 1 Reply Last reply Reply Quote 0
          • Jens Halsberghe
            Jens Halsberghe @Jens Halsberghe last edited by

            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.

            run-out 1 Reply Last reply Reply Quote 0
            • run-out
              run-out @Jens Halsberghe last edited by

              @Jens-Halsberghe
              Try using bar length instead.

              len(self)
              

              From android

              RunBacktest.com

              Jens Halsberghe 1 Reply Last reply Reply Quote 2
              • Jens Halsberghe
                Jens Halsberghe @run-out last edited by

                @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

                1 Reply Last reply Reply Quote 0
                • run-out
                  run-out last edited by

                  @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
                  

                  RunBacktest.com

                  Jens Halsberghe 1 Reply Last reply Reply Quote 2
                  • Jens Halsberghe
                    Jens Halsberghe @run-out last edited by

                    @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

                    1 Reply Last reply Reply Quote 0
                    • Jens Halsberghe
                      Jens Halsberghe last edited by

                      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!

                      1 Reply Last reply Reply Quote 0
                      • run-out
                        run-out last edited by

                        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.

                        RunBacktest.com

                        1 Reply Last reply Reply Quote 3
                        • 1 / 1
                        • First post
                          Last post
                        Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors