Linear Algebra | Introduction To Financial Python on QuantConnect (2024)

Introduction

Many papers in statistics and quantitative finance make heavy use of linear algebra, so you need to have a working knowledge of it in order to read and apply them to your trading.

Vectors

A vector can be thought of as an arrow pointing from the origin to a specific point. Any vector or point can be represented by its coordinates i.e. an array of numbers, such as for a 2-dimensional vector, or for a 3-dimensional one. We usually write a vector as a column:

The scalar product of two vectors and in 2-dimensional space is defined as:

This definition can be easily generalized to n dimensional space. Clearly, we cannot take the scalar product of two vectors with different dimensions.

Matrices

If we have a few vectors with the same dimension, then we can put them side-by-side to form a matrix. For example, the vectors

can be combined to produce a matrix:

m is a 3 × 3 matrix. We typically describe the dimensions of a matrix as where m = number of rows and n = number of columns.

A square matrix is one with as many rows as columns.

Notation: refers to a specific value in row and column of a matrix . For example, is the number in the second row and third column of .

Python Implementation

In Python, the NumPy package deals with linear algebra. The array we learned in the NumPy chapter can be deemed as a vector:

import numpy as npa = np.array([1,2,3])b = np.array([2,2,2])c = np.array([3,1,1])matrix = np.column_stack((a,b,c))print(matrix)print(type(matrix))[out]:[[1 2 3] [2 2 1] [3 2 1]][out]: <class 'numpy.ndarray'>

It is worth noticing that we used column_stack() here to ensure that the vectors are vertical and placed side-by-side to form a matrix. Without the column_stack() function, the vectors will be made horizontal and stacked on top of one another:

matrix2 = np.array([a,b,c])print(matrix2)[out]:[[1 2 3] [2 2 2] [3 1 1]]

Matrix Multiplication

How are two matrices multiplied? Suppose . Each entry of matrix is the scalar product of row from matrix with column from matrix . This is best illustrated with an example:

In NumPy, we can multiply matrices with the dot() function:

A = np.array([[2,3],[4,2],[2,2]])B = np.array([[4,2],[4,6]])x = np.dot(A,B)print x[out]:[[20 22] [24 20] [16 16]]

Since matrix multiplication is defined in terms of scalar products, the matrix product exists only if has as many columns as has rows. It's useful to remember this shorthand: (m × n) × (n × p) = (m × p) which means that an (m × n) matrix multiplied by an (n × p) matrix yields an (m × p) matrix.

Reversing the order of multiplication results in an error since B does not have as many columns as A has rows:

x = np.dot(B,A)

A natrual consequence of this fact is that matrix multiplication is not commutative. In other words, in general.

Inverse

An identity matrix is a square matrix with ones on the main diagonal and zeros elsewhere. Here is an identity matrix:

Multiplying any matrix by an identity matrix (of the correct shape) is like multiplying a number by 1. Concretely, if is an matrix, then:

is the inverse matrix of a square matrix if:

Some caveats:

  • A rectangular matrix will not have an inverse, but it may have a pseudoinverse (not covered in this tutorial).
  • A square matrix may not have an inverse i.e. it may be "singular".
  • If a square matrix has an inverse, then its inverse is unique.

Inverse matrices are computed using the Gauss-Jordan method. In NumPy, we use the linalg.inv() function to do it:

print(matrix)print('\n-------------------------\n')print(np.linalg.inv(matrix))[out]:[[1 2 3] [2 2 1] [3 2 1]]-------------------------[[ 0. -1. 1. ] [-0.25 2. -1.25] [ 0.5 -1. 0.5 ]]

Now let's check if the multiplication is :

inverse = np.linalg.inv(matrix)print(np.dot(matrix, inverse))print('\n-------------------------\n')print(np.dot(inverse,matrix))[out]:[[ 1.00000000e+00 -6.66133815e-16 6.66133815e-16] [ 0.00000000e+00 1.00000000e+00 1.11022302e-16] [ 0.00000000e+00 -2.22044605e-16 1.00000000e+00]]-------------------------[[ 1.00000000e+00 -4.44089210e-16 -2.22044605e-16] [ 6.66133815e-16 1.00000000e+00 0.00000000e+00] [ 0.00000000e+00 0.00000000e+00 1.00000000e+00]]

Not surprisingly, we ended up with an identity matrix. We can form a non-invertible matrix by making one of its rows a multiple of another:

singular = np.array([[1,2,3],[1,2,3],[3,3,3]])inv = np.linalg.inv(singular) [out]: numpy.linalg.linalg.LinAlgError: Singular matrix

Linear Equations

A common problem in linear algebra is solving linear equations. Consider the following linear equations:

If we let:

Then the linear equations above can be written as

If A is invertible, then we can multiply on both sides of the equation to obtain the solution:

As long as exists, we can compute it to solve the linear equations:

A = np.array([[2,1,-1],[-3,-1,2],[-2,1,2]])b = np.array([[8],[-11],[-3]])inv_A = np.linalg.inv(A)print np.dot(inv_A, b)[out]:[[ 2.] [ 3.] [-1.]]

The solution is x = 2, y = 3, z = −1. However, computing the inverse matrix is not recommended, since it is numerically unstable i.e. small rounding errors can dramatically affect the result.

Instead, NumPy solves linear equations by LU decomposition:

print np.linalg.solve(A, b)[out]:[[ 2.] [ 3.] [-1.]]

Of course, we get the same solution. We can check the correctness of the solution by substituting x, y and z into the linear equations.

Summary

In this chapter we have introduced vectors, matrices, inverse matrices and linear equations. Some applications in finance include: finding arbitrage opportunities by solving linear equations, computing portfolio variance, etc. In the next chapter, we will introduce modern portfolio theory and CAPM.

Linear Algebra | Introduction To Financial Python on QuantConnect (1)

Try the world leading quantitative analysis platform today

Sign Up

Previous: Multiple Linear Regression Next: Modern Portfolio Theory

Linear Algebra | Introduction To Financial Python on QuantConnect (2024)
Top Articles
Latest Posts
Article information

Author: Reed Wilderman

Last Updated:

Views: 5727

Rating: 4.1 / 5 (72 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Reed Wilderman

Birthday: 1992-06-14

Address: 998 Estell Village, Lake Oscarberg, SD 48713-6877

Phone: +21813267449721

Job: Technology Engineer

Hobby: Swimming, Do it yourself, Beekeeping, Lapidary, Cosplaying, Hiking, Graffiti

Introduction: My name is Reed Wilderman, I am a faithful, bright, lucky, adventurous, lively, rich, vast person who loves writing and wants to share my knowledge and understanding with you.