This code uses the 'numpy' library for matrix operations and 'matplotlib' for plotting the results.
# First we will import the libraries for numerical operations (numpy) and # plotting (matplotlib).
import numpy as np
import matplotlib.pyplot as plt
# Settings
# Initializing the parameters for the length of the data, number of points to # project (extrapolate), multinomial degree, and lock forecast flag.
length = 50
extrapolate = 10
degree = 3
lock = False
# Generating sample data. Replacing with actual close prices.
src = np.random.random(length)
# Here we are simply defining colors and width for the lines.
up_css = '#0cb51a'
dn_css = '#ff1100'
ex_css = '#00dfd0'
width = 1
# Fill lines array. Initializing an empty list for storing lines.
lines = []
# Creating the design matrix and precompute matrices for multinomial # regression.
n = np.arange(length)
design = np.vander(n, degree + 1, increasing=True)
a = np.linalg.inv(design.T @ design)
b = a @ design.T
# Getting response matrix and computing the rolling multinomial regression
pass_flag = 1
x = -extrapolate
forecast = None
# Preparing the response matrix and coefficients for multinomial regression.
response = src.reshape(-1, 1)
coefficients = b @ response
y1 = np.nan
idx = 0
# Plotting setup
# Initializing the plot and loop through the data points to compute and plot # the multinomial regression lines. Test and plot the projection if 'lock' # is set to 'True.'
plt.figure(figsize=(10, 6))
for i in range(-extrapolate, length):
y2 = sum(coefficients[j] * i ** j for j in range(degree + 1))
if idx == 0:
forecast = y2
css = up_css if y2 < y1 else dn_css
color = ex_css if i <= 0 else css
if not np.isnan(y1):
plt.plot([n[-1] - i + 1, n[-1] - i], [y1, y2], color=color, linewidth=width)
y1 = y2
idx += 1
if lock:
pass_flag = 0
else:
y2 = sum(coefficients[j] * x ** j for j in range(degree + 1))
forecast = y2
# The magic. Plotting the projection
if pass_flag == 0:
plt.axhline(y=forecast, color=ex_css, linestyle='--', linewidth=width, label='Projection')
# Adding labels and legend
plt.title("Multinomial Retrogression Projection")
plt.xlabel("Index")
plt.ylabel("Value")
plt.legend()
plt.grid(True)
plt.show()
Now, let’s check out how well it back tests!