Use the Kalman filter for parameterless indicators
![](https://cdn.prod.website-files.com/6606adcab6ed6464b674ad71/6661e8fde41ef65ad1393966_pyquant-newsletter-25.webp)
Use the Kalman filter for parameterless indicators
Use the Kalman filter and OpenBB for parameterless indicators
In today’s issue, I’m going to show you how to use the Kalman filter to smooth stock prices. I also introduce the OpenBB SDK: The free Bloomberg alternative.
The Kalman filter is an algorithm that tracks an object in state space. Given a sequence of noisy measurements, the Kalman Filter recovers the “true state” of the object. In today’s newsletter, you’ll recover the “true average” of a series of stock prices.
The Kalman filter updates its estimates at every time step so it’s useful for estimating rolling parameters. Quants use it to smooth trading indicators on noisy price data to signal trading opportunities. The Kalman filter is an unsupervised learning algorithm so you don’t need to select a window length. This helps reduce the risk of overfitting-though does not remove it.
Use the Kalman filter to smooth rolling indicators
The Kalman filter is useful for computing the moving average or for smoothing out estimates of other quantities. For example, if you already computed the moving Sharpe ratio, you can smooth it using a Kalman filter. At each time step, the algorithm estimates the current state of the system using the transition matrix, takes in new measurements, then updates the estimated current state.
By the end of this newsletter, you will be able to:
- Get stock price data with the OpenBB SDK
- Build a moving average with the Kalman filter
And you’ll do it with Python.
But first: The OpenBB SDK
OpenBB is a leading open source investment research software platform for accessing and analyzing financial market data. The SDK provides a convenient way to access raw financial data from multiple data providers using the same architecture as the OpenBB Terminal.
And it's completely free.
Step 1: Get stock price data with the OpenBB SDK
Start by importing the libraries you need. pykalman is the “dead-simple” Kalman filter library for Python.
1import pandas as pd
2import matplotlib.pyplot as plt
3
4from pykalman import KalmanFilter
5from openbb_terminal.sdk import openbb
Now get stock price data using the OpenBB SDK.
1data = openbb.stocks.load("LMT", start_date="2013-01-01", end_date="2015-01-01")
2prices = data["Adj Close"]
Step 2: Build a smoothed average with the Kalman filter
Start by setting the initial paramaters for the Kalman filter.
1kf = KalmanFilter(
2 transition_matrices = [1],
3 observation_matrices = [1],
4 initial_state_mean = 0,
5 initial_state_covariance = 1,
6 observation_covariance=1,
7 transition_covariance=0.01
8)
The transition matrix tells the algorithm how the system evolves from one state to another. The observation matrix tracks the next measurement given the predicted next state. The initial mean and covariance are the initial estimates of the state and error and the covariances measure the noise in the evolution of the algorithm. In more complex examples, you can calibrate these inputs to give a better first estimate.
After you define the inputs for the Kalman filter algorithm, use it to filter the prices and find the “true” average.
1state_means, _ = kf.filter(prices.values)
2state_means = pd.Series(state_means.flatten(), index=prices.index)
3
4mean30 = prices.rolling(window=30).mean()
5
6plt.plot(state_means)
7plt.plot(prices)
8plt.plot(mean30)
9plt.title('Kalman filter estimate of average')
10plt.legend(['Kalman', 'Price', '30-day MA'])
11plt.xlabel('Day')
12plt.ylabel('Price')
![PQN #025: Use the Kalman filter and OpenBB for parameterless indicators](https://cdn.prod.website-files.com/6606adcab6ed6464b674ad71/66c8fcca57644a8b6dfb56f6_662df5a659bae9e8da09b3f7_8k7sjcwGWvWd1WzoJ5WuV6.jpeg)
Notice the Kalman filter starts with an estimate that is far away from the prices. That’s because we seeded the algorithm with a matrix of 1s. Within only a few time steps it corrects and more accurately models the price series.
Zoom in on the last 200 days to get a closer look.
1plt.plot(state_means[-200:])
2plt.plot(prices[-200:])
3plt.plot(mean30[-200:])
4plt.title('Kalman filter estimate of average')
5plt.legend(['Kalman', 'Price', '30-day MA'])
6plt.xlabel('Day')
7plt.ylabel('Price');
![PQN #025: Use the Kalman filter and OpenBB for parameterless indicators](https://cdn.prod.website-files.com/6606adcab6ed6464b674ad71/66c8fccd57644a8b6dfb5715_662df5a659bae9e8da09b3f4_7M9tjUXpU4ZZWUHUUG8L2H.jpeg)
The Kalman filter works well on noisy data and trains quickly without labeled data (it’s an unsupervised learning algorithm). Use it to smooth rolling metrics on noisy stock price data.
For a deep dive into the Kalman filter, check out this article for a great visual walkthrough.
![Man with glasses and a wristwatch, wearing a white shirt, looking thoughtfully at a laptop with a data screen in the background.](https://cdn.prod.website-files.com/6604815bfffc39e4941bd158/66070439083cb3ca5c1d1c34_cta%20image.webp)