Skip to content
All library documents

Rolling Windows for Recent Bars and Indicator Values

Article Strategy library · Author: QuantConnect

Summary

This QuantConnect example shows how a rolling window can retain a fixed number of recent observations for use in an algorithm. It creates one window for the latest two daily SPY trade bars and another for five updated values of a five-period simple moving average. After both windows are ready, the algorithm accesses the newest and oldest stored values and logs their timestamps and values. It then buys SPY when it is not already invested and the current moving average exceeds the oldest value in its window.

The example teaches data handling and warm-up checks rather than presenting a tested trading system. Its trading rule is a basic comparison of the recent and older moving average values; the code shows no exit rule or performance analysis. Results and behavior would depend on the data, execution assumptions, and how the algorithm is extended. The rolling window provides convenient bounded history, but the example does not discuss broader storage or computational trade-offs.

Key ideas

  • A rolling window retains a fixed number of the most recent observations.
  • The example stores recent SPY trade bars and updated moving average values in separate windows.
  • The algorithm waits until both windows are ready before accessing their contents.
  • It buys SPY when the latest moving average exceeds the oldest stored value and there is no current investment.
  • The example illustrates data handling and a simple entry condition, not a complete evaluated strategy.

Tags

Full text
# RollingWindowAlgorithm


# RollingWindowAlgorithm









Using rolling windows for efficient storage of historical data; which automatically clears after a period of time.

## Source (Apache-2.0)

```python
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from AlgorithmImports import *

### <summary>
### Using rolling windows for efficient storage of historical data; which automatically clears after a period of time.
### </summary>
### <meta name="tag" content="using data" />
### <meta name="tag" content="history and warm up" />
### <meta name="tag" content="history" />
### <meta name="tag" content="warm up" />
### <meta name="tag" content="indicators" />
### <meta name="tag" content="rolling windows" />
class RollingWindowAlgorithm(QCAlgorithm):

    def initialize(self):
        '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''

        self.set_start_date(2013,10,1)  #Set Start Date
        self.set_end_date(2013,11,1)    #Set End Date
        self.set_cash(100000)           #Set Strategy Cash
        # Find more symbols here: http://quantconnect.com/data
        self.add_equity("SPY", Resolution.DAILY)

        # Creates a Rolling Window indicator to keep the 2 TradeBar
        self._window = RollingWindow(2)    # For other security types, use QuoteBar

        # Creates an indicator and adds to a rolling window when it is updated
        self._sma = self.sma("SPY", 5)
        self._sma.updated += self._sma_updated
        self._sma_win = RollingWindow(5)


    def _sma_updated(self, sender, updated):
        '''Adds updated values to rolling window'''
        self._sma_win.add(updated)


    def on_data(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''

        # Add SPY TradeBar in rollling window
        self._window.add(data["SPY"])

        # Wait for windows to be ready.
        if not (self._window.is_ready and self._sma_win.is_ready): return

        curr_bar = self._window[0]                        # Current bar had index zero.
        past_bar = self._window[1]                        # Past bar has index one.
        self.log(f"Price: {past_bar.time} -> {past_bar.close} ... {curr_bar.time} -> {curr_bar.close}")

        curr_sma = self._sma_win[0]                       # Current SMA had index zero.
        past_sma = self._sma_win[self._sma_win.count-1]   # Oldest SMA has index of window count minus 1.
        self.log(f"SMA:   {past_sma.time} -> {past_sma.value} ... {curr_sma.time} -> {curr_sma.value}")

        if not self.portfolio.invested and curr_sma.value > past_sma.value:
            self.set_holdings("SPY", 1)

```

Shown in full with attribution under the source's licence. Licence: Apache-2.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.