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/

    Submit order 30 minutes before market close

    General Discussion
    5
    11
    5509
    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.
    • E
      Ed Bartosh last edited by

      My strategy includes submitting orders at 30 minutes before market close. How to achieve it in backtester? Is there some scheduling functionality similar to schedule_function ?

      1 Reply Last reply Reply Quote 0
      • Brad Lloyd
        Brad Lloyd last edited by

        if your market close is always 16:00, you could do something like this at the top your "next" function:
        if self.datas[0].datetime.time(0) < datetime.time(15, 30):
        return

        then nothing happens until after 15:30

        but if you are processing signals intraday then you can just put your order statements inside of this if statement
        if self.datas[0].datetime.time(0) >= datetime.time(15, 30):
        self.buy(self.datas[0])

        either way you would need add some logic so you are not sending order after order

        E 1 Reply Last reply Reply Quote 0
        • B
          backtrader administrators last edited by

          There is a little not so well known functionality to simplify the comparison. Assuming you operate on something which closes at 16:00 in the local trading time.

          class MyStrategy(bt.Strategy):
          
              def next(self):
                  if self.data.datetime == datetime.time(15, 30):
                      do_something_here()
          

          This can even be packed as an indicator (and hence as a signal):

          class TimeSignal(bt.Indicator):
              lines = ('mytime',)
          
              params = (('when', datetime.time(15, 30),)
          
              def __init__(self):
                  self.lines.mytime = (self.data.datetime == self.p.when)
          

          Which can then be used in your strategy as:

          class MyStrategy(bt.Strategy):
          
              def __init__(self):
                  self.timesignal = TimeSignal()
          
              def next(self):
                  if self.timesignal:  # equivalent to if self.timesignal[0]
                      do_something_here()
          

          In any case the scheduling of functions seems to be a sought topic (someone also wanted a post-market scheduled function call)

          1 Reply Last reply Reply Quote 0
          • E
            Ed Bartosh @Brad Lloyd last edited by

            @Brad-Lloyd I'm trading US stock market. It's not always closes at 16:00, I'm afraid.

            Brad Lloyd 1 Reply Last reply Reply Quote 1
            • Brad Lloyd
              Brad Lloyd @Ed Bartosh last edited by

              @Ed-Bartosh
              the bulk of the time you have 16:00 as you close, 16:15 for some of the index ETFs,
              you can download the exchange calendars and then put the holidays in where you early close

              if you have some timezone issues then try using pytz to manage that, I think there is some functionality in backtrader for it

              another option would be to count minutes from the first trade of the day, but you still have to manage the holidays

              E 1 Reply Last reply Reply Quote 0
              • B
                backtrader administrators last edited by

                How do closing times look like? Do you have a couple of examples?

                E 1 Reply Last reply Reply Quote 0
                • E
                  Ed Bartosh @Brad Lloyd last edited by

                  @Brad-Lloyd The main issue with this is caused by early closes. I ended up using pandas_market_calendars to detect them:

                  import backtester as bt
                  from pandas_market_calendars import get_calendar
                  
                  class Strategy(bt.Strategy):
                  
                  def __init__(self):
                      calendar = get_calendar('NYSE')
                      schedule = calendar.schedule(start_date=self.p.start_date,
                                                   end_date=self.p.end_date)
                      self.early_closes = calendar.early_closes(schedule).index
                  
                  ...
                  
                      def eod(self):
                          """
                          Calculate time of eod actions.
                          """
                          if self.data0.datetime.date() in self.early_closes:
                              return datetime.time(12, 30)
                          else:
                              return datetime.time(15, 30)
                  
                  ...
                  
                      def next(self):
                  ...
                          if self.data0.datetime.time() >= self.eod():
                                  self.eod_actions()
                                  return
                  ...
                  

                  Just wondering if backtester has better way to do it and I missed it.

                  1 Reply Last reply Reply Quote 0
                  • E
                    Ed Bartosh @backtrader last edited by

                    @backtrader > How do closing times look like? Do you have a couple of examples?

                    Sure: https://www.wallstreetdaily.com/nyse-stock-market-holiday-closings-schedule/

                    pandas_market_calendars shows it this way:

                    In [1]: from datetime import date
                    
                    In [2]: from pandas_market_calendars import get_calendar
                    
                    In [3]: nyse = get_calendar('NYSE')
                    
                    In [4]: nyse.early_closes(nyse.schedule(start_date=date(2016, 1, 1), end_date=date(2017, 12, 31)))
                    Out[4]: 
                                             market_open              market_close
                    2016-11-25 2016-11-25 14:30:00+00:00 2016-11-25 18:00:00+00:00
                    2017-07-03 2017-07-03 13:30:00+00:00 2017-07-03 17:00:00+00:00
                    2017-11-24 2017-11-24 14:30:00+00:00 2017-11-24 18:00:00+00:00
                    
                    1 Reply Last reply Reply Quote 0
                    • B
                      backtrader administrators last edited by

                      You seem to be using this:

                      • https://github.com/rsheftel/pandas_market_calendars

                      Which is a Python 3 only package, or at least can only be installed directly with pip under Python 3

                      The introduction of a trading calendar has been discussed, specifically when dealing with live data and the need to deliver a resampled daily bar in sync with the latest minute bar which closes the day.

                      A potential usage pattern could be:

                      • Adding a calendar parameter to the construction of data feeds
                      • If a calendar is present, do a continuous adjustment of the self.p.sessionend (and self.p.sessionstart) parameters

                      Such an approach would (without deeping looking into it) theoretically transparently integrate into backtrader.

                      A package like pandas_market_calendars would be wrapped to convert the pandas.Timestamps to datetime.datetime instances, adjusted to the exchange local time, if a timezone has been provided to the data feed (or one has been learnt like in the case of Interactive Brokers)

                      Your code could be simplified to:

                      dnow = self.data.datetime.date().isoformat()
                      schedule = self.calendar.schedule(start_date=dnow, end_date=dnow).tz_convert(self.calendar.tz)
                      eos = schedule.iloc[0, 1].tz_convert(tz=self.calendar.tz).to_datetime().time() 
                      

                      You can even pack that in an indicator again:

                      class BeforeEoS(self):
                          lines = ('beos',)
                      
                          params = (
                              ('exchange', 'NYSE'),
                              ('before', 30),  # in minutes
                          )
                      
                          def __init__(self):
                              self.calendar = pandas_market_calendars.get_calendar(self.p.exchange)
                              self.tdbefore = datetime.timedelta(minutes=self.p.before)
                              self.lastdt = datetime.date.min
                      
                          def next(self):
                              curdate = self.data.datetime.date()
                              if curdate > self.lastdt:
                                  self.lastdt = curdate
                                  dnow = curdate.isoformat()
                                  schedule = self.calendar.schedule(start_date=dnow, end_date=dnow).tz_convert(self.calendar.tz)
                                  cureos = schedule.iloc[0, 1].tz_convert(tz=self.calendar.tz).to_datetime()
                                  curbeos = cureos - self.tdbefore
                                  self.curbeos = self.data.date2num(curbeos)
                      
                              self.lines.beos[0] = self.curbeos
                      

                      And later in the strategy is simply about comparing self.data.datetime with self.beosindicator

                          if self.data.datetime == self.beosindicator:
                      
                      E 1 Reply Last reply Reply Quote 0
                      • E
                        Ed Bartosh @backtrader last edited by

                        That sounds great! Any chance to have it implemented/added to TODO list?

                        1 Reply Last reply Reply Quote 0
                        • B
                          backtrader administrators last edited by

                          The idea is always to have a generic model, like it is the case with the timezones, in which you may pass pytz instances or something that, more or less, complies to the interface of pytz.

                          A similar approach will be taken.

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