April 5, 2022

Matrices come to Pine Script™

Quants can now use matrices in their scripts! They are implemented as a new object with its dedicated namespace and a complete set of 49 accompanying functions that allow you to create and modify them, and perform common matrix algebra.

Matrix-related functions live in the matrix.* namespace. A simple matrix can be created by calling the matrix.new<type>(rows, columns, initial_value) function, e.g:

// Creates a 2x3 (2 rows x 3 columns) "int" matrix with values zero.
m = matrix.new<int>(2, 3, 0)

You may fill a matrix by calling the matrix.set() function to set the value of specific elements, or via the matrix.fill() function to fill the whole matrix with a value. Matrices support all Pine types. All elements in the matrix must be of the same type, which is specified using the new type templates (a type name in “<>” brackets) in the matrix.new<type>() call. Matrix algebra functions are only available for “int” and “float” numerical types; other operations are allowed on all matrix types.

Matrix functions

matrix.new<type> Creates a new matrix object. A matrix is a two-dimensional data structure containing rows and columns. All elements in the matrix must be of the type specified in the type template (“<type>”).
matrix.row() Creates a one-dimensional array from the elements of a matrix row.
matrix.col() Creates a one-dimensional array from the elements of a matrix column.
matrix.get() Returns the element with the specified index of the matrix.
matrix.set() Assigns value to the element at the column and row index of the matrix.
matrix.rows() Returns the number of rows in the matrix.
matrix.columns() Returns the number of columns in the matrix.
matrix.elements_count() Returns the total number of matrix elements.
matrix.add_row() Adds a row to the matrix. The row can consist of na values, or an array can be used to provide values.
matrix.add_col() Adds a column to the matrix. The column can consist of na values, or an array can be used to provide values.
matrix.remove_row() Removes the row of the matrix and returns an array containing the removed row’s values.
matrix.remove_col() Removes the column of the matrix and returns an array containing the removed column’s values.
matrix.swap_rows() Swaps the rows in the matrix.
matrix.swap_columns() Swaps the columns in the matrix.
matrix.fill() Fills a rectangular area of the matrix defined by the indices from_column to to_column (not including it) and from_row to to_row (not including it) with the value.
matrix.copy() Creates a new matrix which is a copy of the original.
matrix.submatrix() Extracts a submatrix within the specified indices.
matrix.reverse() Reverses the order of rows and columns in the matrix. The first row and first column become the last, and the last become the first.
matrix.reshape() Rebuilds the matrix to rows x cols dimensions.
matrix.concat() Append one matrix to another.
matrix.sum() Returns a new matrix resulting from the sum of two matrices, or of a matrix and a scalar (a numerical value).
matrix.diff() Returns a new matrix resulting from the subtraction between matrices, or of matrix and a scalar (a numerical value).
matrix.mult() Returns a new matrix resulting from the product between the matrices, or between a matrix and a scalar (a numerical value), or between a matrix and a vector (an array of values).
matrix.sort() Rearranges the rows in the id matrix following the sorted order of the values in the column.
matrix.avg() Calculates the average of all elements in the matrix.
matrix.max() Returns the largest value from the matrix elements.
matrix.min() Returns the smallest value from the matrix elements.
matrix.median() Calculates the median (“the middle” value) of matrix elements.
matrix.mode() Calculates the mode of the matrix, which is the most frequently occurring value from the matrix elements. When there are multiple values occurring equally frequently, the function returns the smallest of those values.
matrix.pow() Calculates the product of the matrix by itself power times.
matrix.det() Returns the determinant of a square matrix.
matrix.transpose() Creates a new, transposed version of the matrix by interchanging the row and column index of each element.
matrix.pinv() Returns the pseudoinverse of a matrix.
matrix.inv() Returns the inverse of a square matrix.
matrix.rank() Calculates the rank of the matrix.
matrix.trace() Calculates the trace of a matrix (the sum of the main diagonal’s elements).
matrix.eigenvalues() Returns an array containing the eigenvalues of a square matrix.
matrix.eigenvectors() Returns a matrix of eigenvectors, in which each column is an eigenvector of the matrix.
matrix.kron() Returns the Kronecker product for the two matrices.
matrix.is_zero() Determines if all elements of the matrix are zero.
matrix.is_identity() Determines if a matrix is an identity matrix (elements with ones on the main diagonal and zeros elsewhere).
matrix.is_binary() Determines if the matrix is binary (when all elements of the matrix are 0 or 1).
matrix.is_symmetric() Determines if a square matrix is ​​symmetric (elements are symmetric with respect to the main diagonal).
matrix.is_antisymmetric() Determines if a matrix is antisymmetric (its transpose equals its negative).
matrix.is_diagonal() Determines if the matrix is ​​diagonal (all elements outside the main diagonal are zero).
matrix.is_antidiagonal() Determines if the matrix is anti-​​diagonal (all elements outside the secondary diagonal are zero).
matrix.is_triangular() Determines if the matrix is triangular (if all elements above or below the main diagonal are zero).
matrix.is_stochastic() Determines if the matrix is stochastic.
matrix.is_square() Determines if the matrix is square (it has the same number of rows and columns).

Some existing functions also support matrices now: the for…in structure allows you to cycle through matrix rows and use them as arrays, str.tostring() converts a matrix into its string representation for display.

In the example below, we create a matrix and sort its elements in ascending order of the first column’s values. We then display the matrix in a table:

indicator("Matrix Example", overlay = true)

// Create a 2x2 matrix with ‘na’ values. 
m1 = matrix.new<float>(2, 2, na)

// Set values to the matrix’s elements. First argument is the matrix object we created before, second is a row index (it starts from 0 for the first row), third is a column index (it starts from 0 for the first column). Last argument is the value to set.
matrix.set(m1, 0, 0, 3)
matrix.set(m1, 0, 1, 4)
matrix.set(m1, 1, 0, 1)
matrix.set(m1, 1, 1, 2)

// Copy the matrix to create a new one.
m2 = matrix.copy(m1)

// Sort rows of the `m2` matrix based on the values of the first column, in ascending order. 
matrix.sort(m2, 0, order.ascending)

// Display the matrix’s elements in the table.
var t = table.new(position.top_right, 2, 2, color.green)
if barstate.islastconfirmedhistory
    table.cell(t, 0, 0, "Original Matrix:")
    table.cell(t, 0, 1, str.tostring(m1))
    table.cell(t, 1, 0, "Sorted Matrix:")
    table.cell(t, 1, 1, str.tostring(m2))

The following publications are examples of scripts published on TradingView by the PineCoders who help us test new Pine Script™ features:

The “Function Polynomial Fit” library by RicardoSantos 

Performs Polynomial Regression fit to data. In statistics, polynomial regression is a form of regression analysis in which the relationship between the independent variable x and the dependent variable y is modeled as an nth degree polynomial in x.

The “Ordinary Least Squares” library by lejmer

One of the most common ways to estimate the coefficients for a linear regression is to use the Ordinary Least Squares (OLS) method. This implementation can be used to fit a linear regression of multiple independent variables onto one dependent variable, as long as the assumptions behind OLS hold.

The “Discounted Price Probability” by HeWhoMustNotBeNamed

The script compares the price and fundamentals historical correlation and defines the probability of being undervalued.

We hope you find this highly-requested feature useful. Please keep sending us your feedback and suggestions for improvement. We build TradingView for you, and we’re always keen to hear from you.

To stay informed of new Pine features, keep an eye on our Pine User Manual’s Release notes. The PineCoders account also broadcasts updates from its Squawk Box on Telegram, its Twitter account, and from the Pine Script public chat on TradingView.

Look first / Then leap

Launch Chart