ta.barssince in Pine Script: Count Bars Since Any Condition
ta.barssince is a Pine Script function that counts how many bars have passed since a specified condition last returned true. Pass it any boolean test — close > open, ta.crossover(fast, slow), whatever you need — and it returns an integer: 0 if the condition fired right now, 1 if one bar ago, 2 if two, and so on. If the condition never triggered, you get na.
I've been writing Pine Script for about three years, and ta.barssince keeps showing up in almost every script I build. During the August 2024 selloff on AAPL, I used it to enforce a 5-bar cooldown between RSI-based entries. That one line saved me from averaging into a falling knife. On a weekly SPY chart I track bars since the last all-time high to guess whether the trend is getting long in the tooth. Not everything worked. I tried the same trick for mean reversion on TSLA and the lag was brutal — by the time ta.barssince said "condition met," the move was already done.
Whether you're asking "how many bars since the last bullish engulfing pattern?" or tracking when price last crossed above your 50-day SMA, ta.barssince answers it directly. It's a workhorse function for any trading strategy that cares about timing.
The Basic Syntax
The syntax is dead simple:
ta.barssince(condition) → series int
- condition: Any boolean expression — like
close > openfor green candles, orta.crossover(fast_ma, slow_ma)for moving average crossovers - Returns: An integer for bars elapsed, or
naif the condition never happened
Your First ta.barssince Example
Start with something straightforward — counting bars since we last had a green candle:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//======================================================================//
// ____ _ _ __ //
// | _ \(_)_ __ ___(_)/ _|_ _ //
// | |_) | | '_ \ / _ \ | |_| | | | //
// | __/| | | | | __/ | _| |_| | //
// |_| |_|_| |_|\___|_|_| \__, | //
// |___/ //
//======================================================================//
//@version=6
indicator("[Pineify - Best Pine Script Generator] Bars Since Green Candle")
plot(ta.barssince(close >= open))
This plots a line that resets to 0 on every green candle, then counts up until the next one. Simple. But I've found it surprisingly useful for gauging market momentum at a glance — when the count stays low for long stretches, you're in a strong uptrend.
Real-World Example: Moving Average Crossovers
Now for something you'd actually trade with. This script counts bars since a fast MA crossed above a slow MA:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Pineify
//======================================================================//
// ____ _ _ __ //
// | _ \(_)_ __ ___(_)/ _|_ _ //
// | |_) | | '_ \ / _ \ | |_| | | | //
// | __/| | | | | __/ | _| |_| | //
// |_| |_|_| |_|\___|_|_| \__, | //
// |___/ //
//======================================================================//
//@version=6
indicator("[Pineify - Best Pine Script Generator] Bars Since MA Cross")
fastMA = ta.sma(close, 10)
slowMA = ta.sma(close, 30)
crossover = ta.crossover(fastMA, slowMA)
plot(ta.barssince(crossover))
A low number means you're in a fresh trend. A high number suggests the trend might be aging. I prefer checking this on the daily timeframe — on lower timeframes the noise makes the reading less reliable.
Advanced Applications
Signal Filtering
One of the smartest uses for ta.barssince is preventing signal spam. Make your strategy only take new signals after enough bars have passed since the last one:
lastSignal = ta.barssince(buyCondition)
takeSignal = buyCondition and lastSignal > 20 // Only take signals if 20+ bars have passed
Dynamic Stop Loss Management
You can also adjust stops based on how long you've been in a trade:
barsInTrade = ta.barssince(strategy.position_size == 0)
tighterStop = barsInTrade > 50 // Tighten stops after being in trade for 50 bars
Why I Reach for Pineify
I'll be honest — writing Pine Script by hand gets old. Looking up syntax, chasing compilation errors, spending an hour on something that should take five minutes. I use Pineify for most of my indicator building now. I can set up a ta.barssince filter visually, test it on different tickers, and export the generated code if I want to hand-tune later. It's not a silver bullet — I've hit edge cases where the visual builder couldn't express exactly what I wanted — but for 90% of what I need, it saves real time.
Common Gotchas and How to Avoid Them
Before you go wild with ta.barssince, here are things that might trip you up:
The NA Problem
Early in your chart — especially the first few bars — you might get na because your condition hasn't happened yet. This can break other calculations. The fix is nz():
barsSince = nz(ta.barssince(condition), 0)
This replaces any na with 0, keeping your calculations smooth. I prefer adding nz() from the start rather than debugging mysterious na errors mid-backtest.
Repainting Issues
This is crucial: ta.barssince can change its historical values as new bars come in. Backtests can look better than reality because the function is "cheating" by looking into the future. When I build real strategies, I always assume the backtest numbers are optimistic and add extra padding to my signal conditions.
Version Compatibility
In Pine Script v5 and v6, you must use ta.barssince(), not just barssince(). The old syntax throws a compilation error. If you're following older tutorials, update the function names. Our Pine Script v6 guide covers version differences in more detail.
Practical Trading Applications
Here are real ways I've used ta.barssince:
Entry Timing: Only take long positions if more than X bars have passed since the last breakout attempt. I set X to 10 on daily charts.
Risk Management: Adjust position size based on how long it's been since the last major market event. I haven't tested this on crypto yet — the volatility pattern feels different.
Trend Analysis: Measure trend "age" to avoid entering late. On SPY, if bars since the last higher high exceed 25, I wait for a pullback.
Pattern Recognition: Count bars since specific candlestick patterns appeared.
Market Regime Detection: Track time since volatility spikes or volume surges.
References:
- https://pinewizards.com/technical-analysis-functions/ta-barssince-function-in-pine-script/
- https://stackoverflow.com/questions/71803965/why-is-barssince-not-working-in-pine-script-v5
- https://www.tradingview.com/pine-script-docs/faq/functions/
- https://www.reddit.com/r/TradingView/comments/o4z4v1/bars_since_entry_function_in_pine_script/
- https://www.reddit.com/r/pinescript/comments/11di31o/help_getting_bars_since_last_entry/
- https://www.tradingview.com/pine-script-docs/language/time-series/
- https://www.reddit.com/r/pinescript/comments/132j2x1/how_do_i_close_the_trade_with_tabarssince/
- https://www.youtube.com/watch?v=yfV_0XPmG38
- https://usethinkscript.com/threads/barssince.11328/
- https://www.tradingcode.net/tradingview/bars-since-last-entry/
Frequently Asked Questions
▶What does ta.barssince do in Pine Script?
ta.barssince(condition) counts how many bars have passed since a condition was last true. It returns an integer: 0 means the condition is true on the current bar, 1 means one bar ago, and so on. If the condition never happened, you get na.
▶How do I handle na values returned by ta.barssince?
Use nz() to replace na with a default. For example: barsSince = nz(ta.barssince(condition), 0). This stops downstream calculations from breaking when the condition hasn't occurred yet — common at the start of a chart's history.
▶Can I use ta.barssince to filter duplicate signals in a Pine Script strategy?
Yes, this is one of the most practical uses. Compare the result to a minimum bar count to prevent signals from firing too close together: takeSignal = buyCondition and ta.barssince(buyCondition) > 20. This ensures at least 20 bars between consecutive entry signals.
▶Does ta.barssince repaint in TradingView?
Yes. ta.barssince can repaint — historical values may change as new bars form. Backtest results can look better than live performance. I always account for this when building strategies that depend on this function.
▶What is the difference between barssince and ta.barssince in Pine Script?
In Pine Script v5 and v6, barssince() was moved into the ta namespace. ta.barssince() is the correct form. Using the old barssince() in v5+ throws a compilation error. If you're following an older tutorial, update it.
▶How can I count bars since entry in a Pine Script strategy?
Use ta.barssince(strategy.position_size == 0) to count bars since you had no open position — basically, since the last entry. Handy for time-based exits or tightening stops after a trade has been open for a certain number of bars.
▶What Pine Script version introduced ta.barssince?
ta.barssince() was introduced with the ta namespace in Pine Script v5. In v4 and earlier, the function was available as barssince(). Pine Script v6 continues using ta.barssince().

