RollingWindow█ OVERVIEW
This a Pine Script™ library to create rolling windows with arrays and matrices.
A rolling window is a first-in-first-out algorithm that stores values over chart updates, removing the oldest element as new values are added. Many programmers implement a form of this algorithm into their scripts currently like this:
var window = array.new(size = 10)
window.push(close) // Append `close` as a new element every new bar.
if 10 < window.size() // Maintain a size of 10 elements.
window.shift() // Remove oldest element.
With the RollingWindow library, you can simply call `roll()` to do the same thing like so:
var window = array.new(size = 10)
window.roll(close) // Rolling window of 10 elements updated each bar with `close`.
█ USAGE
Rolling Window Arrays
Import the RollingWindow library into your script.
import joebaus/RollingWindow/1 as rw
Create a rolling window array by calling `roll()` on an array declared with `var` bar persistence.
var window = array.new()
rw.roll(id = window, source = close, size = 3) // Alternatively: window.roll(close, 3)
Using an array with `varip` intrabar persistence lets `roll()` execute on and update elements intrabar.
varip window = array.new() // Updates intrabar.
rw.roll(id = window, source = close, size = 3) // Executes `roll()` every realtime update.
Ensure arrays are declared with `var` or `varip` keywords to store updated elements. Otherwise, applying `roll()` will not store rolled values.
id = array.new() // No `var` or `varip` keyword.
rw.roll(id, close, 3) // Only updates a single element in `id`!
New elements can be added dynamically to empty arrays with the limit set by the `roll(size)` parameter. Once the array is full, every sequential chart update rolls out , removes, the oldest element.
varip id = array.new()
// Dynamically appends up to 3 elements of `timenow`, then rolls elements.
id.roll(source = timenow, size = 3) // Use `roll()` as a method on `id`.
Arrays with initialized values and sizes can be used as a rolling window array.
var array id = array.from("Hello", "World")
string closeString = str.tostring(close, format.mintick)
id.roll(source = closeString, size = 2) // Rolls elements into `id`, up to 2 elements.
The `roll(size)` parameter becomes optional for arrays with an initialized size, because `roll()` will by default use the initialized size of the array provided if `roll(size)` is not set.
var id = array.new(size = 3) // Returns
color gradient = color.from_gradient(close, low, high, color.red, color.green)
id.roll(source = gradient) // Uses the size of `id` as the rolling window size limit.
An array with initialized values can still grow dynamically if `roll(size)` parameter is greater than the array's initial size.
var id = array.new(size = 3) // Returns
chart.point nowPoint = chart.point.now(close)
id.roll(source = nowPoint, size = 4) // Dynamically grows to
The `roll(size)` parameter must always be equal to or greater than the initial size of the array, or else `roll()` will generate a runtime error.
var id = array.new(size = 3)
id.roll(source = close, size = 2) // Generates a runtime error!
// roll(array id, float source, int size):
// `size` (2) must be greater than or equal to the size of `id` (3), or set to `na`!
When the array size and `roll(size)` parameter are both unspecified, `roll()` will dynamically size the array up to the element limit before rolling new elements.
var id = array.new()
id.roll(timenow) // Adds new elements to `id` up to the element limit, then rolls elements.
From within a conditional local scope , `roll()` can operate on arrays in a higher scope.
var id1 = array.new(size = 3)
float sma50 = ta.sma(close, 50)
float sma200 = ta.sma(close, 200)
if ta.cross(sma50, sma200) // Golden Cross condition.
id1.roll(source = str.format_time(time)) // Rolls up to 3 Golden Cross dates into `id1`.
var id2 = array.new()
footprint reqFootprint = request.footprint(100)
if not na(reqFootprint)
id2.roll(source = reqFootprint, size = 3) // Rolls up to 3 footprint objects into `id2`.
`roll()` returns the element removed from the array, allowing scripts to capture values as they are rolled out.
var id = array.new(size = 3)
float removedElement = id.roll(close, 3) // Returns the removed `close` value from the array.
if not na(removedElement)
label.new(bar_index, removedValue, str.tostring(removedValue))
Reverse Rolling Window Arrays
The roll operation can be done in reverse order using the `rollReverse()` library function; new elements are inserted at the beginning of the array instead, and old elements are removed at the end of the array.
var id1 = array.new()
id1.rollReverse(source = close, size = 3) // Dynamically sized reverse rolling window array.
varip id2 = array.new(size = 3)
id2.rollReverse(source = close) // Initialized size reverse rolling window array.
`rollReverse()` returns the element removed from the array, just like `roll()`.
var id = array.new(size = 3)
int removedValue = id.rollReverse(bar_index, 3)
Sorted Rolling Window Arrays
Rolling window arrays created with `roll()` are unsorted. To create ascending sorted rolling window arrays for `float` or `int` types, use the `rollAscendingVar()` or `rollAscendingVarip()` functions for `var` and `varip` keyword arrays respectively.
var id1 = array.new()
// Ascending sorted, dynamically sized `var` rolling window array.
id1.rollAscendingVar(source = close, size = 3)
varip id2 = array.new(size = 3)
// Ascending sorted, initialized size `varip` rolling window array.
id2.rollAscendingVarip(source = bar_index)
To create descending sorted rolling window arrays for `float` or `int` types, use the `rollDescendingVar()` or `rollDescendingVarip()` functions for `var` and `varip` keyword arrays respectively.
var id1 = array.new()
// Descending sorted, dynamically sized `var` rolling window array.
id1.rollDescendingVar(bar_index, 3)
varip id2 = array.new(3)
// Descending sorted, initialized size `varip` rolling window array.
id2.rollDescendingVarip(close)
Just like with the `array.sort()` built-in function, the ascending and descending rolling window functions do not sort `na` values.
float sma = ta.sma(50, close) // First 49 values are `na`.
var id = array.new()
id.rollAscendingVar(sma, 3) // Rolls nothing until `sma` values are not `na`.
The arrays with unsorted values should be sorted in ascending or descending order before calling the respective sorted rolling window library functions.
var array id = array.from(4, 1, 2, 3, 10, 8, 15, 7) // Unsorted initialized array.
id.sort(order.ascending) // Sort it first!
id.rollAscendingVar(bar_index)
The sorted rolling window functions can return the latest element removed from the array.
var id = array.new(size = 3)
float removedElement = id.rollAscendingVar(close, 3)
Rolling Window Matrices
The `roll()` matrix methods store a rolling window of arrays in row-major order. Rows are "rolled" by adding a new row at index `0`, and removing the oldest row at the end of the matrix.
var closeArray = array.new(10) // Array to store in the rolling window matrix.
var closeMatrix = matrix.new()
// Create a rolling window matrix with up to 3 `closeArray` rows and 10 columns (1 per element).
rw.roll(id = closeMatrix, array_id = closeArray, rows = 3)
A matrix with `varip` intrabar persistence lets `roll()` execute and update matrix rows intrabar.
varip closeArray = array.new(size = 10)
rw.roll(id = closeArray, source = time)
varip closeMatrix = matrix.new()
// Create a rolling window matrix with up to 3 `closeArray` rows and 10 elements (columns).
closeMatrix.roll(array_id = closeArray, rows = 3)
The matrix methods of `roll()` will dynamically create the necessary columns to fit all elements of `roll(array_id)` as long as the array size is greater than the number of matrix columns.
var closeArray = array.new(size = 10000)
closeArray.roll(source = close) // Creating a rolling window array.
// Size empty matrices dynamically with `roll(array_id)`.
var closeMatrix = matrix.new()
// Roll up to 100 rows of `closeArray` with 10000 elements (columns) into `closeMatrix`.
rw.roll(id = closeMatrix, array_id = closeArray, rows = 100)
The size of `array_id` can possibly be too large when dynamically adding columns to a rolling window matrix, generating a runtime error when the new column would exceed the 100,000 matrix size limit.
var closeArray = array.new()
closeArray.roll(source = close, size = 1001)
var closeMatrix = matrix.new()
rw.roll(id = closeMatrix, array_id = closeArray, rows = 100) // Generates a runtime error!
// roll(matrix id, array array_id, int rows):
// `array_id` (1001) and `rows` (100) create 100100 matrix elements!"
// Reduce the size of `array_id` or value of `rows` to stay within the 100,000 matrix size limit!
A matrix with initialized rows and columns can also be used with `roll()`. This requires that the array's size used in `roll(array_id)` must be less than or equal to the number of matrix columns.
var closeArray = array.new(100) // Initialized matrix columns require initialized array sizes.
closeArray.roll(close) // Roll 100 `close` elements into `closeArray`.
var closeMatrix = matrix.new(rows = 10, columns = 100) // 100 array elements, 100 columns.
rw.roll(id = closeMatrix, array_id = closeArray, rows = 10)
The `roll(rows)` parameter is also optional: `roll()` will use the number of rows in the initialized matrix when `roll(rows)` is not set. Plus the number of initialized matrix columns does not have to be the same size as `roll(array_id)`.
var closeArray = array.new(10) // Array initialized with 10 elements.
closeArray.roll(close)
var closeMatrix = matrix.new(rows = 10, columns = 100) // Matrix initialized with 100 columns.
closeMatrix.roll(closeArray) // No `rows` parameter, uses the initialized number of matrix rows.
Managing Drawings
An array or matrix of `line`, `linefill`, `label`, `box`, `polyline`, or `table` types can be used with `roll()` to manage the number of drawing on a chart.
var id = array.new()
// Roll a label in `id` after a bullish bar is confirmed.
if close > open and barstate.isconfirmed
chart.point nowPoint = chart.point.now(high)
label newLabel = label.new(nowPoint, "Bullish")
id.roll(newLabel, 5) // Rolls up to 5 labels in `id`, array grows up to a size of 5.
When drawings are rolled out of an array or matrix, they are deleted with the `.delete()` method of the respective type used. The library functions return `void` for drawing types, so no value is returned when an element is removed.
Pine Script®腳本庫




















