Fit a log linear model to find a trending stock

Fit a log linear model to find a trending stock
A linear trend model assumes that the variable changes at a constant rate with time, and attempts to find a line of best fit.
While these types of models do come with caveats for financial time series (see below), they are a useful way to very quickly forecast a long term trend.
By reading today’s newsletter, you’ll get Python code to build, fit, and use a log-linear model for spotting trends, mean reversion signals, and momentum trades in any stock.
Let's go!
Fit a log linear model to find a trending stock
A log-linear trend model analyzes the natural logarithm of stock prices, capturing compounding effects and filtering out noise from raw price moves. It models log(price) as a linear function of time, summarizing the average return and deviations.
These models emerged as quantitative finance sought better ways to describe stock trends. The concept builds on work in early financial econometrics, where returns were found to behave more predictably in log terms. Moving from simple price analysis to log-returns allowed practitioners to measure returns and risk on a standardized scale.
In modern trading, professionals use log-linear models to spot trend direction, mean reversion points, and abnormal deviations.
Traders fit the model to recent price data, then monitor the standardized residuals for mean reversion or breakout opportunities. The model's trend slope guides expectation, while deviations inform entry and exit points.
Let's see how it works with Python.
Imports and set up
We use math for numerical methods, matplotlib.pyplot for charting, numpy for numerical arrays, statsmodels and the regression module for statistical modeling, and yfinance for downloading market price data.
1import math
2import matplotlib.pyplot as plt
3import numpy as np
4import statsmodels.api as sm
5from statsmodels import regression
6import yfinance as yf
This block pulls daily price data for the XLY ETF from Yahoo Finance using yfinance, keeping only the close prices for a 10-year period.
1close = yf.download(
2 "XLY", period="10y", interval="1d", auto_adjust=False, progress=False
3).Close
4dates = close.index
The code here requests historical data for the XLY ETF, which tracks consumer discretionary stocks. We use the yfinance library to grab the data and focus only on the closing values, dropping everything else. The result is an indexed time series we'll analyze further.
Run a log-linear regression
This block defines a function to fit a log-linear regression to the price data, modeling price growth as exponential over time.
1def loglinreg(X, Y):
2 x = sm.add_constant(X)
3 model = regression.linear_model.OLS(np.log(Y), x).fit()
4 a, b = model.params
5
6 X2 = np.linspace(X.min(), X.max(), 100)
7 Y_hat = np.exp(a + b * X2)
8 return model, X2, Y_hat
This function uses statsmodels to perform a regression where we assume the logarithm of the price changes linearly over time. It returns the regression model along with a smooth set of points for plotting. We use the exponential function to transform predicted values back to actual prices, so the output matches the original price scale.
Let’s run the regression.
1X = np.arange(len(close))
2Y = close.values
3model, X2, Y_hat = loglinreg(X, Y)
4print(model.summary())
Here, we assign each time point a sequential index number for regression. We send these numbers and the corresponding price values into our log-linear regression. The model outputs both the statistical fit and a set of predicted prices, ready for charting.
You’ll also see the summary statistics.
.png)
The regression explains about 88% of the variation in log-prices (R² = 0.88), which is very strong for financial data. The slope coefficient (0.0004, highly significant) implies a consistent exponential growth trend in the stock over the past 10 years.
However, the residual diagnostics show skewness, excess kurtosis, and strong autocorrelation (Durbin-Watson ≈ 0), which indicates serial dependence and non-normality—common in financial time series—so forecasts or risk metrics based on this model should be used cautiously.
Visualize the regression fit
This block creates a chart showing both the actual XLY price data and the fitted exponential growth curve.
1fig, ax = plt.subplots()
2ax.plot(dates, Y, label="XLY Price")
3ax.plot(dates[X2.astype(int)], Y_hat, "r", label="Log-Linear Fit")
4
5# Formatting
6ax.set_title("XLY Price with Log-Linear Regression Fit")
7ax.set_xlabel("Date")
8ax.set_ylabel("Price")
9ax.legend()
10
11# Auto-handle x-axis ticks/dates
12fig.autofmt_xdate()
13plt.show()
We use matplotlib to chart both the real ETF price (in blue) and our fitted exponential growth path (in red), plotting them on the same date axis.
.png)
The chart clearly shows how closely our regression follows the general trend in price over the decade. We label each line and axis, then adjust the dates so the chart is legible. This helps us see at a glance how well our model describes the price movement.
Your next steps
You can now fit and visualize exponential growth trends on ETF price data. Try swapping out "XLY" for another ticker in the yf.download call to see how different assets behave. Tweak the "period" parameter to focus on shorter or longer histories. These changes help you get a real feel for how log-linear regression reacts across markets and timespans.
