Calculating averages for the last 30 minutes

I'm trying to figure out how to calculate the moving average for the last 30 minutes, inside on_minute_bar. Does anyone have sample code that I can use? Thanks.

Comments

  • ptunneyptunney Posts: 246
    edited August 2019

    There are many ways to achieve this but there are some extra things you need to consider....
    Do you want to include pre-market bars, for example, at 9:31 where should the "last 30 mins" be coming from? Should it be 9:30 and the last 29 minutes of the previous trading day? Or just 9:30 and expand as we build? Or include pre market bars.. if there are any.. and what do we do if there are not.

    Basically you are going to fetch minute bars from the history... two ways to do this, ask it for 30 minute bars and have it give you as many as it can get, or tell it to get you 30 mine bars in total, go back quite some way if you need to.

    We will put our bars into a variable, call it mybars for now...

    mybars = md.bar.minute(start=-30, today_only=False,include_extended=True) # this will attempt to get you 30 bars and will include out of hours bars
    mybars = md.bar.minute(start=-30, today_only=False,include_extended=False) # This will attempt to get you 30 bars but will exclude out of market hours bars

    To tell the system to get you 30 bars no matter what use (docs https://app.cloudquant.com/#/glossary/134)
    mybars = md.bar.minute_by_index(-30) # again you can give this today_only and include_extended)

    So lets say we will use by_index to try to ensure we get 30 bars and we will not do extended but we set today_only to false.
    mybars = md.bar.minute_by_index(-30,today_only=False)

    If you print mybars you will see that it is a list containing 16 lists (open,close,high,low,volume,timestamp etc etc etc). We only want the close bars, so we can specify that by adding .close on the end...

    mybars = md.bar.minute_by_index(-30,today_only=False).close

    If we print mybars now we will more often that not get 30 closing prices but sometimes we will get less. Perhaps it is an IPO or a very thinly traded symbol or some other event has happened that we have not considered. We will take this into account by dividing the total of our close prices by the number of close prices.

    But what if we get no close prices for some reason... well then we risk a divide by zero, so we will check for this first as well...

    In is_symbol_qualified we define our symbol universe, in on_start we will define our simple 30 minute Moving Average variable, self.myavol
    Then in on_minute we pull the bars, selecting only the close prices, using by_index to get 30 bars where possible and using today_only=false to go back into the previous days bars at the start of the day.
    If the length of the list of close prices we get back > 0 then we divide the sum by the length and we use the round command to round the result to 2 decimal places.

    from cloudquant.interfaces import Strategy
    
    class avg_price_30m(Strategy):
    
        @classmethod 
        def is_symbol_qualified(cls, symbol, md, service, account):
            return md.stat.avol>100000
    
        def on_start(self, md, order, service, account): 
            self.myavol = 0
    
        def on_minute_bar(self, event, md, order, service, account, bar): 
            mybars = md.bar.minute_by_index(-30,today_only=False).close
            if len(mybars)>0:
                self.myavol = round(sum(mybars)/len(mybars),2)
            print self.symbol,self.myavol
    

    You could try this more fancy print statement at the end if you prefer, it takes the timestamp for the event, converts it to a string, pulls out the Hours and Minutes and prints it together with the symbol name (aligned left and padded to 6 characters), the 30m average price (it uses 8 characters for the price with 2 after the decimal) and the number of bars found.

        print "{} {:<6} {:8.2f} {}".format(service.time_to_string(event.timestamp,"%H:%M"),self.symbol,self.myavol,len(mybars))
    

    Hope this helps!

  • Thanks. Let me try that out.

Sign In or Register to comment.