- Solve real problems with our hands-on interface
- Progress from basic puts and calls to advanced strategies

Posted July 24, 2026 at 10:33 am
The article “R: The Hodrick-Prescott Filter or HP Filter” was originally posted on SHLee AI Financial Model blog
This post demonstrates how to apply the Hodrick-Prescott (HP) filter in R by using the hpfilter R library.
Previously, the HP filter was addressed using Python. This post presents an R version.
The Hodrick-Prescott filter models a time series (yt) as

where τt and ct are trend and cyclical components respectively.
To decompose in this way, we solve the following minimization problem.

λ is typically recommended as 100, 1600, and 14400 for annual, quarterly, and monthly frequency, respectively.
R code
The hpfilter R library provides two convenient functions for the HP filter: hp1() for the one-sided filter and hp2() for the two-sided filter. They are easy to use, as demonstrated in the code below.
It’s interesting that plotting results requires more lines of code compared to the HP filter code (just two lines), which is the main topic of this post.
#========================================================#
# Quantitative Financial Econometrics & Derivatives
# ML/DL using R, Python, Tensorflow by Sang-Heon Lee
#
# https://shleeai.blogspot.com
#---------------------------------------------------------
# Hodrick-Prescott (HP) filter - 1 sided & 2 sided
#========================================================#
graphics.off(); rm(list = ls())
library(quantmod)
library(hpfilter)
#------------------------------------------
# Download monthly AAPL stock data
#------------------------------------------
aapl <- getSymbols("AAPL",
from = "2011-01-01",
to = "2022-12-31",
auto.assign = FALSE,
periodicity = "monthly")
df <- as.data.frame(Ad(aapl))
date <- index(aapl) #as.data.frame(index(aapl))
y <- df; colnames(df) <- "AAPL"
#------------------------------------------
# Apply the HP filter (1-sided, 2-sided)
#------------------------------------------
yt1 = hp1(y, lambda = 14400); yc1 = y - yt1
yt2 = hp2(y, lambda = 14400); yc2 = y - yt2
#------------------------------------------
# Plot the three resulting series
#------------------------------------------
x11(width=7, height=6);
plot(y$AAPL, type="l", col=1, lty=1, lwd=3,
ylab="", xlab="", xaxt = "n",
ylim=c(min(yc1, yt1)*1.2,max(yc1, yt1)*1.1))
lines(yt1$AAPL, lwd=5, col=rgb(1,0,0, alpha=0.5))
lines(yt2$AAPL, lwd=5, col=rgb(0,0,1, alpha=0.5))
# Plotting polygons with 50% transparency
polygon(c(1, seq(yc1$AAPL), length(yc1$AAPL)),
c(0, yc1$AAPL, 0),
col = rgb(1, 0, 0, alpha = 0.3))
polygon(c(1, seq(yc2$AAPL), length(yc2$AAPL)),
c(0, yc2$AAPL, 0),
col = rgb(0, 0, 1, alpha = 0.3))
# Add x-axis with selected dates
sel_dates <- date[seq(18, length(date), by = 24)]
axis(1, at = which(date %in% sel_dates),
labels = substr(sel_dates,1,4))
# Legend
legend("topleft", cex=0.8, lty = 1,
col = c(1,2,4,2,4), lwd=c(3,5,5,3,3),
c("Data", "Trend (1-sided)", "Trend (2-sided)",
"Cycle (1-sided)", "Cycle (2-sided)"))Visit SHLee AI Financial Model blog for additional insights on this topic.
Information posted on IBKR Campus that is provided by third-parties does NOT constitute a recommendation that you should contract for the services of that third party. Third-party participants who contribute to IBKR Campus are independent of Interactive Brokers and Interactive Brokers does not make any representations or warranties concerning the services offered, their past or future performance, or the accuracy of the information provided by the third party. Past performance is no guarantee of future results.
This material is from SHLee AI Financial Model and is being posted with its permission. The views expressed in this material are solely those of the author and/or SHLee AI Financial Model and Interactive Brokers is not endorsing or recommending any investment or trading discussed in the material. This material is not and should not be construed as an offer to buy or sell any security. It should not be construed as research or investment advice or a recommendation to buy, sell or hold any security or commodity. This material does not and is not intended to take into account the particular financial conditions, investment objectives or requirements of individual customers. Before acting on this material, you should consider whether it is suitable for your particular circumstances and, as necessary, seek professional advice.
The third-party code discussed within this article is not investment or trading advice, and is for proof-of-concept, educational, and illustrative purposes only. IBKR makes no representations or warranty regarding its accuracy or completeness. Users are solely responsible for conducting their own independent testing and due diligence before applying any code or concepts in a live or production environment
Please keep in mind that the examples discussed in this material are purely for technical demonstration purposes, and do not constitute trading advice. Also, it is important to remember that placing trades in a paper account is recommended before any live trading.
Join The Conversation
For specific platform feedback and suggestions, please submit it directly to our team using these instructions.
If you have an account-specific question or concern, please reach out to Client Services.
We encourage you to look through our FAQs before posting. Your question may already be covered!