On this page
Overview
In this tutorial I show you how to add labels in ThinkOrSwim with the thinkScript AddLabel function. We work through 6 examples that get harder as we go, so by the end you have a working knowledge of labels you can use in your own studies.
The first 3 are static labels, which print a value a study already has, like an EMA or volume. The last 3 are dynamic labels, which print the result of a calculation you write in the code: a stacked moving average check, a signal counter, and a label that changes with your inputs. It's written for beginners. For Examples 5 and 6 you'll also need the code of our free Simple Breakout Tool.
Key Takeaways
- The thinkScript AddLabel function takes 3 parameters: when the label shows (
yes,noor a condition), what it says (text, a value or both), and its background color. - ThinkOrSwim counts a label as a plot, so a study made only of AddLabel lines clears the "At least one plot should be defined" error.
- To show a value from another study, write the study name with parentheses and the plot after a period, such as
ChaikinMoneyFlow().CMF. - TotalSum adds a signal up across every bar loaded on the chart. In the video, it counted 8 bullish and 6 bearish Simple Breakout Tool signals on a 5-year daily SPY chart.
- A label can print a study input, such as the fast SMA length, so it updates when someone changes that setting.
What the AddLabel Function Does
AddLabel is the thinkScript function that prints a colored box of text in the top left corner of a ThinkOrSwim chart. To find it, open the thinkScript editor and click Reference in the top right corner if the side pane is hidden. Open the Functions tab, then Look & Feel, and AddLabel is listed there.
The function takes 3 parameters, and each one can be static (one fixed value) or dynamic (an if/then statement that changes with the chart):
| Parameter | What it controls | Static example | Dynamic example |
|---|---|---|---|
| 1. Show condition | When the label appears. yes always shows it, no never does. | yes | sumOfBullish >= 1 |
| 2. Text | What the label says: text in quotes, a variable, or both joined with + | EMA8 | if bullishStacked then "Bullish" else ... |
| 3. Color | The label's background color | color.yellow | if bullishStacked then color.green else ... |
ThinkOrSwim counts a label as a plot. A study with no plot throws the error "At least one plot should be defined", and adding a label clears it, so a study can be nothing but labels.
Our Utility Labels indicator works that way: it tracks sectors and market internals in labels without drawing a line, and its first parameter is an input such as showSectors, so you can switch each group of labels on or off.
Static Labels vs Dynamic Labels
Static labels and dynamic labels differ in where the value comes from. A static label shows a value a study already calculates, so you don't do any math yourself. A dynamic label prints the result of something you calculate in the code: a true/false condition, a count, or an input. The 6 examples in the video cover both kinds:
| Example | Type | What the label shows |
|---|---|---|
| 1. 8-period EMA | Static | The EMA value |
| 2. Volume | Static | The current bar's volume |
| 3. Chaikin Money Flow | Static | The CMF plot from another study |
| 4. Stacked moving averages | Dynamic | "Bullish", "Bearish" or "N/A" in green, red or yellow |
| 5. Signal counter | Dynamic | How many bullish and bearish signals fired on the chart |
| 6. User input | Dynamic | The current value of a study input |
How to Create a Study for Your Labels
Every label lives inside a ThinkOrSwim study. The first step is a blank study, and these are the steps I follow in the video:
- Click the Studies icon on your chart, then Create to open a blank thinkScript editor.
- Give the study a name. I named mine TI_LabelsTutorial.
- Click Reference in the top right if you want AddLabel's description beside your code.
- Write your code, click OK, then Apply to see the label on the chart.

The finished sample script from the video, TI_LabelsTutorial, is on the Code tab of this page. Its signal counter (Example 5) is active, and the other examples are commented out with #. Delete the # in front of the example you want to try, plus the EMA lines at the top for Examples 1 and 4.
If you have a study as a .ts file instead, our guide on how to import a study into ThinkOrSwim covers that route.
Static Label Examples
Static labels in ThinkOrSwim reference a value and show it in a label instead of drawing it on the chart. These 3 examples take about 5 minutes.
Example 1: The 8 EMA
Define the 8-period exponential moving average, then put the variable in the second parameter:
This step’s code is free with an account. Create one or sign in.
The def line on its own throws the "At least one plot should be defined" error. The AddLabel line clears it. On the 5-year daily Apple chart in the video, the label showed 152.5586, and the 8 EMA's price bubble on the right axis showed the same value rounded to 152.56.

Example 2: Volume
To show the current bar's volume, put volume in the second parameter. You don't need to define it first.
This step’s code is free with an account. Create one or sign in.
The first time you apply a study that uses volume, ThinkOrSwim puts it in the volume pane. Move it back up to the price pane in the study settings. The label showed 140,893,240 shares for Apple, which matched the volume on the Trade tab.
Example 3: Chaikin Money Flow
Pulling a value out of another study takes two things: the study name with parentheses after it, and the name of the plot you want. Add ChaikinMoneyFlow to a chart and open its settings, and you'll see two plots. CMF is the money flow line, which is the one we want.
This step’s code is free with an account. Create one or sign in.
The parentheses tell ThinkOrSwim that ChaikinMoneyFlow is a study. The period and CMF pick the plot. The money flow line read 0.00747 and the label showed 0.0075.

Dynamic Label Examples
Dynamic labels in ThinkOrSwim print the result of a calculation. The pattern is to do the calculation first, in its own variables, then plug those variables into the label. You can also write a calculation inside the second parameter itself.
Example 4: Stacked Moving Averages
This label tells you whether the 8, 21 and 34 EMAs are stacked bullish or bearish. We use the same idea in our squeeze tools, in the moving average crossover backtester and in the Stacked Moving Averages indicator. Start with the 3 averages and 2 true/false variables:
This step’s code is free with an account. Create one or sign in.
Each variable returns 1 when its condition is true and 0 when it isn't. Now use an if/then statement in the text parameter, and the same if/then structure in the color parameter:
This step’s code is free with an account. Create one or sign in.
On SPY the label read "Bullish" on a green background. On AT&T it read "Bearish" on red. I find it cleaner to define the true/false variables outside the label and plug them in, as this example does, than to write the whole condition inside AddLabel.


Example 5: Count How Many Times a Signal Fired
This example counts the signals from our free Simple Breakout Tool. Copy the part of its code that defines the bullish and bearish signals into your study. Skip the painting strategy and line weight lines at the bottom, and change the two plot statements to def, since the label will do the plotting.
TotalSum adds a value up across every bar ThinkOrSwim has loaded for the chart. Each signal variable is 1 on a signal bar and 0 everywhere else, so the total is the number of signals:
This step’s code is free with an account. Create one or sign in.
The first parameter hides each label until there's at least 1 signal. The + joins the text and the number, and the space inside the quotes keeps them apart. On a 5-year daily SPY chart, the labels showed 8 bullish and 6 bearish signals. To count over a longer period, change the chart's time frame.
You can also put both counts in one label and let the color show which side has more:
This step’s code is free with an account. Create one or sign in.
With 8 bullish and 6 bearish signals, the combined label came up green.

The same counter works on any signal you can write as a true/false variable. In the video I mention the Fisher Transformer as one example; our Fisher Transformer scans show how its signals are written.
Example 6: Show a User Input in the Label
A label can show the current value of a study input, so the user can see what the study is measuring after changing a setting. The Simple Breakout Tool has an input called fastSMALength, which defaults to 10. Paste the input name into the text parameter:
This step’s code is free with an account. Create one or sign in.
Change the input to 11 in the settings, and the label changes to 11 along with the signals. When I set it to 20, the counter labels from Example 5 showed 11 bullish and 5 bearish signals. I counted the arrows on the chart by hand and found all 11 bullish ones.
The same idea works for any input: an EMA length you let the user set, or a days-to-earnings setting where the label shows 7 days instead of 8 after someone changes it.
How to Format the Label Text
Label text in thinkScript is built by joining pieces with a plus sign. Text is written inside quotes, variables go outside them, and any spaces you want go inside the quotes. A divider such as " | " lets one label hold two values, as in Example 5.
In the video, labels printed numbers with up to 4 decimal places: 152.5586 for the EMA and 0.0075 for the money flow. For large numbers you can shorten the value before printing it. Our Average Volume Stats indicator divides volume by 1,000,000 and rounds it with Round() before it goes in a label.
Using Labels to Track Statistics
Labels are where I put backtest numbers. Our Slingshot Squeeze backtester and Squeeze Signals backtester print their stats in labels, and when you change an input like the exit condition, the labels update right away. In the video, switching a backtester's exit condition from "no squeeze" to "losing momentum" changed the statistics in the labels.

Once you can count signals, you can track what happened after them. Create variables that check the move 5 candles after each bullish signal, whether it gained more than 2%, or how far it drew down, and print the totals in labels. You get the statistics on the chart and keep the chart clean.
A count of signals tells you how often a setup fired, and a label of results is a quick read of the past. Neither is an entry by itself. Before you trade a signal you've counted, decide where the stop goes and size the position so a stop-out costs a small, fixed share of your account.
Common Label Problems and Fixes
These 5 label problems can come up while you build the examples above, and each one has a quick fix:
- "At least one plot should be defined." The study has only
deflines. Add an AddLabel line or a plot. - The study jumps to the volume pane. Studies that use volume land there the first time. Move the study back to the price pane in its settings.
- A reference to another study won't compile. Check for the parentheses after the study name and the exact plot name, which you can see in that study's settings.
- The label never appears. Check the first parameter. A condition like
sumOfBullish >= 1hides the label until it's true. - Arrows or lines appear along with the counter. Signal code pasted from another study still says
plot. Change those lines todefso only the labels show.
To show a value from a higher time frame in a label, such as a daily ATR on an intraday chart, see our tutorial on aggregation periods in thinkScript. For more lessons like this one, browse the thinkScript tutorials.
Full thinkScript code
Create a free account or sign in to copy all 54 lines and download the file.
Download
The download is the sample script from the video: a .zip with one file, TI_LabelsTutorialSTUDY.ts. It holds all 6 label examples. The Simple Breakout Tool signal counter is active, and the other examples are commented out with #, so delete the # in front of the ones you want to try. You can import the STUDY.ts file straight into ThinkOrSwim. If you haven't done that before, here's how to import into your ThinkOrSwim platform.
Questions
What are the three parameters of AddLabel in thinkScript?
The first is a true/false value that decides when the label shows: yes, no, or a condition. The second is what the label says, which can be text, a variable, or both joined with a plus sign. The third is the background color, which can be fixed, like color.yellow, or chosen with an if/then statement.
How do I show an indicator value in a ThinkOrSwim label?
Reference the value and put it in the second parameter. For an EMA, define it first with def EMA8 = ExpAverage(close, 8); and then write AddLabel(yes, EMA8, color.yellow);. For another study, use the study name with parentheses and the plot name after a period, like ChaikinMoneyFlow().CMF.
How do I change a label's color based on a condition?
Use an if/then statement as the third parameter. For example: if bullishStacked then color.green else if bearishStacked then color.red else color.yellow. Define the conditions as their own true/false variables first and plug them in. The same if/then structure in the second parameter changes the text.
How do I count how many times a signal fired in thinkScript?
Make the signal a def that equals 1 on signal bars and 0 otherwise, then wrap it in TotalSum, for example def sumOfBullish = TotalSum(bullish);. TotalSum adds it up across every bar loaded on the chart, so the result is the number of signals. Change the chart's time frame to count over a longer period.
Why do I get "At least one plot should be defined"?
Every ThinkOrSwim study needs at least one plot, and a study made only of def lines has none. AddLabel counts as a plot, so adding a label clears the error. That means a study can contain only labels and draw no lines on the chart at all.
How do I hide a label until a condition is true?
Put the condition in the first parameter instead of yes. AddLabel(sumOfBullish >= 1, "Bullish: " + sumOfBullish, color.green); only shows the label once there has been at least 1 bullish signal on the chart. Any true/false variable works there, including a stacked moving average check.
How do I combine text and numbers in one label?
Join them with a plus sign. "Bullish: " + sumOfBullish + " | Bearish: " + sumOfBearish prints both counts in a single label. Text goes inside quotes and variables go outside them. Put any spaces you want inside the quotes, or the text and number print right next to each other.
Can a label show the value of a study input?
Yes. Put the input name in the text parameter, like "Fast SMA: " + fastSMALength. When someone changes the input in the study settings, the label updates to the new value. In the video, changing the Simple Breakout Tool's fast SMA length from 10 to 11 changed the label to 11.
Get each new indicator by email
One email on Sundays with the week's new tool and its code. A free account also unlocks every .txt download.
No credit card. Unsubscribe anytime.
Fair Value Gap
False Breakout Scanner
Heiken Ashi Trend



Stock Volatility Box
Futures Volatility Box
ORB Setups
Squeeze Setups
Utility Labels Indicator - Quickly Track Sector Performance and Internals
Utility Labels Indicator Updated
How to Import a thinkScript Study into ThinkOrSwim
How to Fix Bugs in thinkScript Code
How to Set Custom Hours in thinkScript
Aggregation Periods - How to Plot Larger Time Frame Indicators on Smaller Time Frames