A free P/E ratio indicator for ThinkorSwim. It plots the trailing 12-month P/E as a line, with labels for the current, lowest, highest and median P/E.
Download IndicatorIn this tutorial I plot the P/E ratio in ThinkorSwim with a few lines of thinkScript. The indicator divides the closing price by the earnings reported over the past 252 trading days, draws that trailing 12-month P/E as a line under the chart, and adds labels for the current, lowest, highest and median P/E.
Sites like Yahoo Finance and the Wall Street Journal show you today’s P/E. In ThinkorSwim you also get the history behind it, 10 years or more, and you can line it up with the chart setups you already trade. It’s for investors and swing traders who value companies with steady earnings.
GetActualEarnings() over the last 252 daily bars. It plots as a line in a lower pane.The P/E ratio, or price-to-earnings ratio, is a stock’s price divided by its earnings per share. A P/E of 20 means investors pay $20 for each $1 of yearly earnings. The trailing P/E uses the last 12 months of reported earnings, and the forward P/E uses estimates for the next 12 months. This indicator is a trailing P/E.
A P/E that’s low for the stock’s own history means the market is pricing its earnings more cheaply than usual. A high one means investors are paying up. Neither tells you why, so the P/E is a starting point for research.
The P/E ratio doesn’t fit every stock. If earnings are negative, the number is close to useless. It’s most useful where earnings are steady and the P/E has traditionally been a good way to value the company. For a valuation based on assets instead, see our price to book ratio indicator, and for income stocks, our dividend yield indicator.
Plotting the P/E ratio in ThinkorSwim gives you 2 things a quote page doesn’t:
In the video I use Starbucks as the example. Its chart had a technical setup, and its P/E was near the level of its March 2020 low. Seeing both in one place is the reason to build this.
The P/E ratio formula has the price on top and trailing 12-month earnings on the bottom. ThinkorSwim already has the price: it’s close. Earnings take 2 steps.
def earningsValue = if IsNan(GetActualEarnings()) then 0 else GetActualEarnings();
GetActualEarnings() returns the reported earnings per share on an earnings day and NaN (not a number) on every other bar. The if IsNan(...) then 0 part turns those empty bars into 0, so the sum in the next step works.
To check it, I plotted earningsValue in chart bubbles. They matched the earnings figures along the bottom of the Starbucks chart: 0.32, -0.46 and 0.51. The download keeps a commented-out bubble line at the bottom that prints the P/E in a bubble on every bar: delete the # to turn it on.
def earningsTTM = Sum(earningsValue, 252);
Sum adds up the last 252 bars, one trading year on a daily chart, which normally covers the last 4 quarterly reports. In the video, Starbucks’ trailing 12-month earnings came to 3.32.
declare lower;
plot pe = close / earningsTTM;
declare lower puts the study in its own pane under the price chart. I first wrote pe as a def and looked at it in chart bubbles. Changing it to plot draws a line, so you see how the P/E moved year by year.
def LowestPE = LowestAll(pe);
def HighestPE = HighestAll(pe);
def MedianPE = Median(pe,200);
LowestAll and HighestAll read every bar loaded on the chart, so on a 10-year chart they give the cheapest and most expensive the stock has been in 10 years.
Median(pe,200) is the middle value of the last 200 bars, about 9 to 10 months of daily bars, so the median label covers the same window on a 10-year or a 20-year chart. For a longer median, raise the 200 (an edit that isn’t in the video).
AddLabel(yes, "P/E Ratio: " + pe, color.white);
AddLabel(yes, "Lowest P/E: " + LowestPE, color.yellow);
AddLabel(yes, "Highest P/E: " + HighestPE, color.yellow);
The first 3 labels print the current P/E in white and the lowest and highest P/E in yellow.
AddLabel(yes, "Median P/E: " + MedianPE, if pe <= MedianPE then color.light_green else color.light_red);
The median label is the one I read first. It turns light green when the current P/E is at or below the median and light red when it’s above, a first read on whether the stock is in cheaper territory than usual. If you’re new to labels, our AddLabel tutorial covers the syntax.
| Label | What it shows | Color |
|---|---|---|
| P/E Ratio | Close divided by trailing 12-month earnings | White |
| Lowest P/E | Lowest P/E on the chart | Yellow |
| Highest P/E | Highest P/E on the chart | Yellow |
| Median P/E | Median P/E of the last 200 bars | Light green at or below the median, light red above |
The P/E ratio indicator is one study, and these are the steps I follow in the video:
declare lower.The download is the same code as the Code tab. To import the .ts file instead of pasting, follow our guide on how to import a study into ThinkorSwim.
Starbucks is the main P/E ratio example in the video, with Costco as a second check. These are the values from the day I recorded, on 10-year daily charts:
| Stock | Current P/E | Lowest P/E | Highest P/E | Median P/E |
|---|---|---|---|---|
| Starbucks | 21.6657 | 10.7916 | 120.755 (April 2021) | 21.97 |
| Costco | 34 | 16 | 49 | 39.95 |
Starbucks had hit its 127.2% Fibonacci extension and pulled back to its 50% retracement. At the same time, its P/E of 21.67 was getting close to the 19.70 it fell to in March 2020, and it sat a little below its median. That pairing of a technical pullback with a P/E near past lows is how I look for undervalued spots. Our Fibonacci Trading Course covers those levels.
Costco was below its median of 39.95 too, at a P/E of 34. Against its lowest P/E of 16, though, it still had room to fall. The labels give you a baseline for what counts as cheap for each stock.
The P/E ratio in ThinkorSwim won’t always match other sites. In the video, Starbucks read 21.6657 in ThinkorSwim, 19.19 on Yahoo Finance and 19.26 on the Wall Street Journal: close, with a slight gap.
The benefit of the ThinkorSwim number is consistency. The indicator measures today’s P/E and every past P/E on the chart the same way, so comparing the stock with its own history is apples to apples.
The lowest and highest P/E labels change with the chart’s time frame, because LowestAll and HighestAll read every loaded bar. The current and median labels don’t. When I switched Starbucks from 10 years to 20 years, the lowest P/E reached further back, and the Highest P/E label stopped plotting, since the data didn’t go back before 2008. I went back to 10 years for the rest of the video.
The 252 in the code means 252 bars, one trading year on a daily chart, so keep the study on a daily chart.
The P/E ratio indicator works the same way on any stock that reports earnings. The screenshots below show it on Walmart and Target on May 20, 2022, each on a 10-year daily chart. In both, the price and the P/E line drop sharply at the right edge, and the median label is green, so the current P/E sits at or below its 200-bar median.
A green median label is the first read. Next, compare the current P/E with the lowest and highest labels, and check the price chart for a setup.
The P/E ratio indicator gives me a baseline for value, and the chart decides the timing. The setup I want is a P/E near the low end of the stock’s own range, with the median label green, plus a technical setup like Starbucks’ pullback to its 50% retracement.
A low P/E can get lower, so treat a green label as a read on value, not an entry. Decide where your stop goes before you buy, and size the position so a stop-out costs a small, fixed share of your account.
If you like working with data, you can take it further with range calculations on the same P/E series to define what you consider undervalued. For other ways to value a company, compare the P/E with our Dividend Discount Model for dividend payers, or with the price to book ratio for a view based on book value.
Most P/E ratio indicator problems come from the data behind it:
AddLabel line. I started the median label as color.cyan in the video before switching to the green and red version.#TOS Indicators
#Home of the Volatility Box
#Indicator: P/E Ratio
#Code written in 2022
#Full Tutorial: https://www.tosindicators.com/indicators/pe-ratio
declare lower;
def earningsValue = if IsNan(GetActualEarnings()) then 0 else GetActualEarnings();
def earningsTTM = Sum(earningsValue, 252);
plot pe = close / earningsTTM;
def LowestPE = LowestAll(pe);
def HighestPE = HighestAll(pe);
def MedianPE = Median(pe,200);
AddLabel(yes, "P/E Ratio: " + pe, color.white);
AddLabel(yes, "Lowest P/E: " + LowestPE, color.yellow);
AddLabel(yes, "Highest P/E: " + HighestPE, color.yellow);
AddLabel(yes, "Median P/E: " + MedianPE, if pe <= MedianPE then color.light_green else color.light_red);
#AddChartBubble(pe, close, pe, color.yellow);Want the .ts file and the one-click import? Both come with a free account.
Join 40,000+ traders using institutional-grade tools for ThinkOrSwim.
Get the Bundle