thinkScript study guide
Probability Technical Indicator in thinkScript
A probability technical indicator in thinkScript can measure how often price rose over a chosen bar horizon inside a rolling historical sample. The study below reports empirical frequency. It does not calculate the chance of a future gain.
# Excerpt: only display a complete window
# valid and upMove are defined in the full source below.
def validCount = Sum(if valid then 1 else 0, sampleSize);
plot rate = if validCount == sampleSize
then Average(upMove, sampleSize)
else Double.NaN;- Statistic
- Rolling historical up rate
- Grid horizons
- 5, 10, and 20 bars
- Output
- Lower plot and chart labels
Direct answer
What this probability study measures
For each bar, the study asks whether the close is above the close from a fixed number of bars earlier. It converts that result to 1 or 0, then uses a rolling average. A value of 0.57 means that 57 percent of the observations in the current sample were positive for that bar horizon.
The unit is bars, so the chart aggregation changes the time represented by each horizon. On a daily chart, 5 bars is roughly one trading week. On a 15-minute chart, it is 75 minutes across five full bar intervals; session breaks can make elapsed clock time longer. The current bar can still change before it closes.
Complete source
thinkScript probability grid code
This single-file study uses one helper for every horizon. The lower plot follows the selected horizon, while the label row keeps the 5, 10, and 20-bar readings visible together.
declare lower;
input sampleSize = 100;
input selectedHorizon = 10;
input showProbabilityGrid = yes;
script UpRate {
input price = close;
input horizon = 5;
input sampleSize = 100;
Assert(horizon > 0, "horizon must be positive");
Assert(sampleSize > 0, "sampleSize must be positive");
def valid = !IsNaN(price) and !IsNaN(price[horizon]);
def upMove = if valid and price > price[horizon] then 1 else 0;
def validCount = Sum(if valid then 1 else 0, sampleSize);
plot rate = if validCount == sampleSize
then Average(upMove, sampleSize) else Double.NaN;
}
def up5 = UpRate(
price = close,
horizon = 5,
sampleSize = sampleSize
);
def up10 = UpRate(
price = close,
horizon = 10,
sampleSize = sampleSize
);
def up20 = UpRate(
price = close,
horizon = 20,
sampleSize = sampleSize
);
def selectedUpRate = UpRate(
price = close,
horizon = selectedHorizon,
sampleSize = sampleSize
);
plot UpProbability = 100 * selectedUpRate;
plot ReferenceLine = 50;
UpProbability.SetDefaultColor(Color.CYAN);
UpProbability.SetLineWeight(2);
ReferenceLine.SetDefaultColor(Color.GRAY);
AddCloud(
UpProbability,
ReferenceLine,
Color.DARK_GREEN,
Color.DARK_RED
);
AddLabel(
showProbabilityGrid,
"5 BAR UP " + AsPercent(up5),
if up5 >= 0.5 then Color.GREEN else Color.GRAY
);
AddLabel(
showProbabilityGrid,
"10 BAR UP " + AsPercent(up10),
if up10 >= 0.5 then Color.GREEN else Color.GRAY
);
AddLabel(
showProbabilityGrid,
"20 BAR UP " + AsPercent(up20),
if up20 >= 0.5 then Color.GREEN else Color.GRAY
);Calculation
How the indicator works
- 01
Classify each return
The helper compares the current close with the close at the requested historical offset. With valid endpoints, an increase becomes 1 and an equal or lower close becomes 0. A missing endpoint makes the window unavailable.
- 02
Average the sample
Average converts the binary series into a rolling rate. The plot multiplies the rate by 100 so the axis reads as a percentage.
- 03
Display the grid
AddLabel formats the 5, 10, and 20-bar rates with AsPercent. The selected horizon remains visible as a lower-chart series.
Two different tools
Custom probability grid vs. ProbabilityOfExpiringCone
The built-in study and the code on this page answer different questions. Use the built-in cone when you want its expiration-based forecast range. Use the custom grid when you want to inspect the historical direction rate across fixed bar horizons.
| Dimension | Custom probability grid | ProbabilityOfExpiringCone |
|---|---|---|
| Question answered | How often was the horizon return positive in this rolling sample? | What future price range corresponds to the selected probability setting? |
| Output | A lower plot plus 5, 10, and 20-bar labels | Upper and lower forecast cone plots into expiration Fridays |
| Main inputs | Sample size and bar horizon | Forecast period and probability range |
| Interpretation | Historical directional frequency | Statistical forecast range |
Platform steps
Add the study to thinkorswim
- 1
Open the thinkorswim desktop Charts tab, then choose Studies and Edit Studies.
- 2
Click Create, remove the default plot, and paste the complete source from this page.
- 3
Let the thinkScript Editor parse the source. Review any messages before saving the study.
- 4
Add the study to a chart, then compare symbols, aggregations, sample sizes, and horizons.
Primary sources
Official thinkScript references used here
The calculation and interface use documented thinkScript building blocks. The source links below define the functions and the built-in study discussed on this page.
- ProbabilityOfExpiringConeBuilt-in forecast-cone purpose, inputs, and plots.
- Sum and sample validityRolling count used to require a complete window.
- scriptSame-file helper definition and reuse.
- AddLabelChart labels used to display the horizon grid.
- AsPercentPercentage text formatting for each label.
- AddCloudPlot shading above and below the 50 percent line.
Frequently asked questions
What does this thinkScript probability indicator measure?
It measures the rolling share of historical bars where the current close was above the close a chosen number of bars earlier. It is an empirical frequency from the selected chart and sample, not a calibrated forecast of the next move.
How does the thinkScript probability grid work?
The grid uses the same UpRate helper for 5, 10, and 20-bar horizons, then prints each result with AddLabel. The lower plot uses the selectedHorizon input so you can inspect one horizon as a time series.
Is this the same as the thinkorswim ProbabilityOfExpiringCone study?
No. The built-in ProbabilityOfExpiringCone study plots a forecast price range for upcoming expiration Fridays using a probability-range input. This custom study reports historical directional frequency over fixed bar horizons.
Does a value above 50 percent predict that price will rise?
No. It only says that positive returns occurred more often than not in the rolling sample for that horizon. Market regime, symbol, aggregation, sample size, and overlapping observations can all change the result.
How do I add this code to thinkorswim?
In thinkorswim desktop, open Charts, choose Studies, select Edit Studies, and click Create. Replace the default code, paste this study, let the thinkScript Editor parse it, then add it to a chart and inspect the output.
Can Pineify customize this probability indicator?
Yes. Pineify can generate or edit a single-file thinkScript study from a plain-language request. You can ask for different horizons, labels, filters, alerts, or plot behavior, then review the source and check it in the thinkScript Editor.
Adapt the study to your own rules
Use the thinkorswim AI Coding Agent to change the horizons, sample logic, labels, filters, alerts, or plots in one editable thinkScript file. Review the result in Pineify, then check it in the thinkScript Editor and on relevant charts.
This page is for educational and informational purposes. It does not provide investment advice, predict future prices, or guarantee trading results.